Insteon local update (#11088)

* trying to rework device discovery. now the main component will do the getlinked and pass it to the sub-components. no longer any config needed other than what is needed to connect to the hub. device names are no longer stored. core team told us to stop using configurator to ask for names. there should be a way to set names in hass...possibly this https://home-assistant.io/docs/configuration/customizing-devices/

* fix device types

* make device names just be the isnteon device id

* revert some config changes

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* update insteon client

* linting fixes

* Error Clean up

* Update to make requested changes

* more changes

* Finish requested changes to components

* Fixing Rebase Conflicts

* fix device types

* make device names just be the isnteon device id

* revert some config changes

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* update insteon client

* linting fixes

* Error Clean up

* Update to make requested changes

* more changes

* Finish requested changes to components

* Update Insteon_Local for performance improvements

* Fix errors from get_linked

* Fix typo

* Requested changes

* Fix spacing

* Clean up

* Requested Changes
pull/11534/head
Cameron Llewellyn 2018-01-08 11:18:10 -06:00 committed by Fabian Affolter
parent e0e2f739ba
commit 903cda08b1
5 changed files with 64 additions and 213 deletions

View File

@ -12,7 +12,6 @@ from homeassistant.components.fan import (
SUPPORT_SET_SPEED, FanEntity) SUPPORT_SET_SPEED, FanEntity)
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
import homeassistant.util as util import homeassistant.util as util
from homeassistant.util.json import load_json, save_json
_CONFIGURING = {} _CONFIGURING = {}
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -20,8 +19,6 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['insteon_local'] DEPENDENCIES = ['insteon_local']
DOMAIN = 'fan' DOMAIN = 'fan'
INSTEON_LOCAL_FANS_CONF = 'insteon_local_fans.conf'
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
@ -31,85 +28,34 @@ SUPPORT_INSTEON_LOCAL = SUPPORT_SET_SPEED
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Insteon local fan platform.""" """Set up the Insteon local fan platform."""
insteonhub = hass.data['insteon_local'] insteonhub = hass.data['insteon_local']
if discovery_info is None:
conf_fans = load_json(hass.config.path(INSTEON_LOCAL_FANS_CONF))
if conf_fans:
for device_id in conf_fans:
setup_fan(device_id, conf_fans[device_id], insteonhub, hass,
add_devices)
else:
linked = insteonhub.get_linked()
for device_id in linked:
if (linked[device_id]['cat_type'] == 'dimmer' and
linked[device_id]['sku'] == '2475F' and
device_id not in conf_fans):
request_configuration(device_id,
insteonhub,
linked[device_id]['model_name'] + ' ' +
linked[device_id]['sku'],
hass, add_devices)
def request_configuration(device_id, insteonhub, model, hass,
add_devices_callback):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
# We got an error if this method is called while we are configuring
if device_id in _CONFIGURING:
configurator.notify_errors(
_CONFIGURING[device_id], 'Failed to register, please try again.')
return return
def insteon_fan_config_callback(data): linked = discovery_info['linked']
"""The actions to do when our configuration callback is called.""" device_list = []
setup_fan(device_id, data.get('name'), insteonhub, hass, for device_id in linked:
add_devices_callback) if (linked[device_id]['cat_type'] == 'dimmer' and
linked[device_id]['sku'] == '2475F'):
device = insteonhub.fan(device_id)
device_list.append(
InsteonLocalFanDevice(device)
)
_CONFIGURING[device_id] = configurator.request_config( add_devices(device_list)
'Insteon ' + model + ' addr: ' + device_id,
insteon_fan_config_callback,
description=('Enter a name for ' + model + ' Fan addr: ' + device_id),
entity_picture='/static/images/config_insteon.png',
submit_caption='Confirm',
fields=[{'id': 'name', 'name': 'Name', 'type': ''}]
)
def setup_fan(device_id, name, insteonhub, hass, add_devices_callback):
"""Set up the fan."""
if device_id in _CONFIGURING:
request_id = _CONFIGURING.pop(device_id)
configurator = hass.components.configurator
configurator.request_done(request_id)
_LOGGER.info("Device configuration done!")
conf_fans = load_json(hass.config.path(INSTEON_LOCAL_FANS_CONF))
if device_id not in conf_fans:
conf_fans[device_id] = name
save_json(hass.config.path(INSTEON_LOCAL_FANS_CONF), conf_fans)
device = insteonhub.fan(device_id)
add_devices_callback([InsteonLocalFanDevice(device, name)])
class InsteonLocalFanDevice(FanEntity): class InsteonLocalFanDevice(FanEntity):
"""An abstract Class for an Insteon node.""" """An abstract Class for an Insteon node."""
def __init__(self, node, name): def __init__(self, node):
"""Initialize the device.""" """Initialize the device."""
self.node = node self.node = node
self.node.deviceName = name
self._speed = SPEED_OFF self._speed = SPEED_OFF
@property @property
def name(self): def name(self):
"""Return the name of the node.""" """Return the name of the node."""
return self.node.deviceName return self.node.device_id
@property @property
def unique_id(self): def unique_id(self):

View File

@ -13,8 +13,9 @@ import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, CONF_HOST, CONF_PORT, CONF_TIMEOUT) CONF_PASSWORD, CONF_USERNAME, CONF_HOST, CONF_PORT, CONF_TIMEOUT)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform
REQUIREMENTS = ['insteonlocal==0.52'] REQUIREMENTS = ['insteonlocal==0.53']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -22,6 +23,14 @@ DEFAULT_PORT = 25105
DEFAULT_TIMEOUT = 10 DEFAULT_TIMEOUT = 10
DOMAIN = 'insteon_local' DOMAIN = 'insteon_local'
INSTEON_CACHE = '.insteon_local_cache'
INSTEON_PLATFORMS = [
'light',
'switch',
'fan',
]
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({ DOMAIN: vol.Schema({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
@ -34,12 +43,8 @@ CONFIG_SCHEMA = vol.Schema({
def setup(hass, config): def setup(hass, config):
"""Set up the Insteon Hub component. """Setup insteon hub."""
This will automatically import associated lights.
"""
from insteonlocal.Hub import Hub from insteonlocal.Hub import Hub
conf = config[DOMAIN] conf = config[DOMAIN]
username = conf.get(CONF_USERNAME) username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD) password = conf.get(CONF_PASSWORD)
@ -48,21 +53,23 @@ def setup(hass, config):
timeout = conf.get(CONF_TIMEOUT) timeout = conf.get(CONF_TIMEOUT)
try: try:
if not os.path.exists(hass.config.path('.insteon_cache')): if not os.path.exists(hass.config.path(INSTEON_CACHE)):
os.makedirs(hass.config.path('.insteon_cache')) os.makedirs(hass.config.path(INSTEON_CACHE))
insteonhub = Hub(host, username, password, port, timeout, _LOGGER, insteonhub = Hub(host, username, password, port, timeout, _LOGGER,
hass.config.path('.insteon_cache')) hass.config.path(INSTEON_CACHE))
# Check for successful connection # Check for successful connection
insteonhub.get_buffer_status() insteonhub.get_buffer_status()
except requests.exceptions.ConnectTimeout: except requests.exceptions.ConnectTimeout:
_LOGGER.error("Error on insteon_local." _LOGGER.error(
"Could not connect. Check config", exc_info=True) "Could not connect. Check config",
exc_info=True)
return False return False
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
_LOGGER.error("Error on insteon_local. Could not connect." _LOGGER.error(
"Check config", exc_info=True) "Could not connect. Check config",
exc_info=True)
return False return False
except requests.exceptions.RequestException: except requests.exceptions.RequestException:
if insteonhub.http_code == 401: if insteonhub.http_code == 401:
@ -71,6 +78,12 @@ def setup(hass, config):
_LOGGER.error("Error on insteon_local hub check", exc_info=True) _LOGGER.error("Error on insteon_local hub check", exc_info=True)
return False return False
linked = insteonhub.get_linked()
hass.data['insteon_local'] = insteonhub hass.data['insteon_local'] = insteonhub
for insteon_platform in INSTEON_PLATFORMS:
load_platform(hass, insteon_platform, DOMAIN, {'linked': linked},
config)
return True return True

View File

@ -10,8 +10,6 @@ from datetime import timedelta
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light) ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light)
import homeassistant.util as util import homeassistant.util as util
from homeassistant.util.json import load_json, save_json
_CONFIGURING = {} _CONFIGURING = {}
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -19,8 +17,6 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['insteon_local'] DEPENDENCIES = ['insteon_local']
DOMAIN = 'light' DOMAIN = 'light'
INSTEON_LOCAL_LIGHTS_CONF = 'insteon_local_lights.conf'
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
@ -30,84 +26,33 @@ SUPPORT_INSTEON_LOCAL = SUPPORT_BRIGHTNESS
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Insteon local light platform.""" """Set up the Insteon local light platform."""
insteonhub = hass.data['insteon_local'] insteonhub = hass.data['insteon_local']
if discovery_info is None:
conf_lights = load_json(hass.config.path(INSTEON_LOCAL_LIGHTS_CONF))
if conf_lights:
for device_id in conf_lights:
setup_light(device_id, conf_lights[device_id], insteonhub, hass,
add_devices)
else:
linked = insteonhub.get_linked()
for device_id in linked:
if (linked[device_id]['cat_type'] == 'dimmer' and
device_id not in conf_lights):
request_configuration(device_id,
insteonhub,
linked[device_id]['model_name'] + ' ' +
linked[device_id]['sku'],
hass, add_devices)
def request_configuration(device_id, insteonhub, model, hass,
add_devices_callback):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
# We got an error if this method is called while we are configuring
if device_id in _CONFIGURING:
configurator.notify_errors(
_CONFIGURING[device_id], 'Failed to register, please try again.')
return return
def insteon_light_config_callback(data): linked = discovery_info['linked']
"""Set up actions to do when our configuration callback is called.""" device_list = []
setup_light(device_id, data.get('name'), insteonhub, hass, for device_id in linked:
add_devices_callback) if linked[device_id]['cat_type'] == 'dimmer':
device = insteonhub.dimmer(device_id)
device_list.append(
InsteonLocalDimmerDevice(device)
)
_CONFIGURING[device_id] = configurator.request_config( add_devices(device_list)
'Insteon ' + model + ' addr: ' + device_id,
insteon_light_config_callback,
description=('Enter a name for ' + model + ' addr: ' + device_id),
entity_picture='/static/images/config_insteon.png',
submit_caption='Confirm',
fields=[{'id': 'name', 'name': 'Name', 'type': ''}]
)
def setup_light(device_id, name, insteonhub, hass, add_devices_callback):
"""Set up the light."""
if device_id in _CONFIGURING:
request_id = _CONFIGURING.pop(device_id)
configurator = hass.components.configurator
configurator.request_done(request_id)
_LOGGER.debug("Device configuration done")
conf_lights = load_json(hass.config.path(INSTEON_LOCAL_LIGHTS_CONF))
if device_id not in conf_lights:
conf_lights[device_id] = name
save_json(hass.config.path(INSTEON_LOCAL_LIGHTS_CONF), conf_lights)
device = insteonhub.dimmer(device_id)
add_devices_callback([InsteonLocalDimmerDevice(device, name)])
class InsteonLocalDimmerDevice(Light): class InsteonLocalDimmerDevice(Light):
"""An abstract Class for an Insteon node.""" """An abstract Class for an Insteon node."""
def __init__(self, node, name): def __init__(self, node):
"""Initialize the device.""" """Initialize the device."""
self.node = node self.node = node
self.node.deviceName = name
self._value = 0 self._value = 0
@property @property
def name(self): def name(self):
"""Return the name of the node.""" """Return the name of the node."""
return self.node.deviceName return self.node.device_id
@property @property
def unique_id(self): def unique_id(self):

View File

@ -9,7 +9,6 @@ from datetime import timedelta
from homeassistant.components.switch import SwitchDevice from homeassistant.components.switch import SwitchDevice
import homeassistant.util as util import homeassistant.util as util
from homeassistant.util.json import load_json, save_json
_CONFIGURING = {} _CONFIGURING = {}
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -17,8 +16,6 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['insteon_local'] DEPENDENCIES = ['insteon_local']
DOMAIN = 'switch' DOMAIN = 'switch'
INSTEON_LOCAL_SWITCH_CONF = 'insteon_local_switch.conf'
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
@ -26,83 +23,33 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Insteon local switch platform.""" """Set up the Insteon local switch platform."""
insteonhub = hass.data['insteon_local'] insteonhub = hass.data['insteon_local']
if discovery_info is None:
conf_switches = load_json(hass.config.path(INSTEON_LOCAL_SWITCH_CONF))
if conf_switches:
for device_id in conf_switches:
setup_switch(
device_id, conf_switches[device_id], insteonhub, hass,
add_devices)
else:
linked = insteonhub.get_linked()
for device_id in linked:
if linked[device_id]['cat_type'] == 'switch'\
and device_id not in conf_switches:
request_configuration(device_id, insteonhub,
linked[device_id]['model_name'] + ' ' +
linked[device_id]['sku'],
hass, add_devices)
def request_configuration(
device_id, insteonhub, model, hass, add_devices_callback):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
# We got an error if this method is called while we are configuring
if device_id in _CONFIGURING:
configurator.notify_errors(
_CONFIGURING[device_id], 'Failed to register, please try again.')
return return
def insteon_switch_config_callback(data): linked = discovery_info['linked']
"""Handle configuration changes.""" device_list = []
setup_switch(device_id, data.get('name'), insteonhub, hass, for device_id in linked:
add_devices_callback) if linked[device_id]['cat_type'] == 'switch':
device = insteonhub.switch(device_id)
device_list.append(
InsteonLocalSwitchDevice(device)
)
_CONFIGURING[device_id] = configurator.request_config( add_devices(device_list)
'Insteon Switch ' + model + ' addr: ' + device_id,
insteon_switch_config_callback,
description=('Enter a name for ' + model + ' addr: ' + device_id),
entity_picture='/static/images/config_insteon.png',
submit_caption='Confirm',
fields=[{'id': 'name', 'name': 'Name', 'type': ''}]
)
def setup_switch(device_id, name, insteonhub, hass, add_devices_callback):
"""Set up the switch."""
if device_id in _CONFIGURING:
request_id = _CONFIGURING.pop(device_id)
configurator = hass.components.configurator
configurator.request_done(request_id)
_LOGGER.info("Device configuration done")
conf_switch = load_json(hass.config.path(INSTEON_LOCAL_SWITCH_CONF))
if device_id not in conf_switch:
conf_switch[device_id] = name
save_json(hass.config.path(INSTEON_LOCAL_SWITCH_CONF), conf_switch)
device = insteonhub.switch(device_id)
add_devices_callback([InsteonLocalSwitchDevice(device, name)])
class InsteonLocalSwitchDevice(SwitchDevice): class InsteonLocalSwitchDevice(SwitchDevice):
"""An abstract Class for an Insteon node.""" """An abstract Class for an Insteon node."""
def __init__(self, node, name): def __init__(self, node):
"""Initialize the device.""" """Initialize the device."""
self.node = node self.node = node
self.node.deviceName = name
self._state = False self._state = False
@property @property
def name(self): def name(self):
"""Return the name of the node.""" """Return the name of the node."""
return self.node.deviceName return self.node.device_id
@property @property
def unique_id(self): def unique_id(self):

View File

@ -400,7 +400,7 @@ iglo==1.0.0
influxdb==4.1.1 influxdb==4.1.1
# homeassistant.components.insteon_local # homeassistant.components.insteon_local
insteonlocal==0.52 insteonlocal==0.53
# homeassistant.components.insteon_plm # homeassistant.components.insteon_plm
insteonplm==0.7.5 insteonplm==0.7.5