From 903cda08b153400849409c253cbc8051af53a503 Mon Sep 17 00:00:00 2001 From: Cameron Llewellyn Date: Mon, 8 Jan 2018 11:18:10 -0600 Subject: [PATCH] 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 --- homeassistant/components/fan/insteon_local.py | 80 +++---------------- homeassistant/components/insteon_local.py | 39 ++++++--- .../components/light/insteon_local.py | 79 +++--------------- .../components/switch/insteon_local.py | 77 +++--------------- requirements_all.txt | 2 +- 5 files changed, 64 insertions(+), 213 deletions(-) diff --git a/homeassistant/components/fan/insteon_local.py b/homeassistant/components/fan/insteon_local.py index 58c8caa331b..85e603c8c81 100644 --- a/homeassistant/components/fan/insteon_local.py +++ b/homeassistant/components/fan/insteon_local.py @@ -12,7 +12,6 @@ from homeassistant.components.fan import ( SUPPORT_SET_SPEED, FanEntity) from homeassistant.helpers.entity import ToggleEntity import homeassistant.util as util -from homeassistant.util.json import load_json, save_json _CONFIGURING = {} _LOGGER = logging.getLogger(__name__) @@ -20,8 +19,6 @@ _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['insteon_local'] DOMAIN = 'fan' -INSTEON_LOCAL_FANS_CONF = 'insteon_local_fans.conf' - MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) 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): """Set up the Insteon local fan platform.""" insteonhub = hass.data['insteon_local'] - - 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.') - + if discovery_info is None: return - def insteon_fan_config_callback(data): - """The actions to do when our configuration callback is called.""" - setup_fan(device_id, data.get('name'), insteonhub, hass, - add_devices_callback) + linked = discovery_info['linked'] + device_list = [] + for device_id in linked: + 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( - '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)]) + add_devices(device_list) class InsteonLocalFanDevice(FanEntity): """An abstract Class for an Insteon node.""" - def __init__(self, node, name): + def __init__(self, node): """Initialize the device.""" self.node = node - self.node.deviceName = name self._speed = SPEED_OFF @property def name(self): """Return the name of the node.""" - return self.node.deviceName + return self.node.device_id @property def unique_id(self): diff --git a/homeassistant/components/insteon_local.py b/homeassistant/components/insteon_local.py index 711dafb6b73..dbe8597be3d 100644 --- a/homeassistant/components/insteon_local.py +++ b/homeassistant/components/insteon_local.py @@ -13,8 +13,9 @@ import voluptuous as vol from homeassistant.const import ( CONF_PASSWORD, CONF_USERNAME, CONF_HOST, CONF_PORT, CONF_TIMEOUT) 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__) @@ -22,6 +23,14 @@ DEFAULT_PORT = 25105 DEFAULT_TIMEOUT = 10 DOMAIN = 'insteon_local' +INSTEON_CACHE = '.insteon_local_cache' + +INSTEON_PLATFORMS = [ + 'light', + 'switch', + 'fan', +] + CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Required(CONF_HOST): cv.string, @@ -34,12 +43,8 @@ CONFIG_SCHEMA = vol.Schema({ def setup(hass, config): - """Set up the Insteon Hub component. - - This will automatically import associated lights. - """ + """Setup insteon hub.""" from insteonlocal.Hub import Hub - conf = config[DOMAIN] username = conf.get(CONF_USERNAME) password = conf.get(CONF_PASSWORD) @@ -48,21 +53,23 @@ def setup(hass, config): timeout = conf.get(CONF_TIMEOUT) try: - if not os.path.exists(hass.config.path('.insteon_cache')): - os.makedirs(hass.config.path('.insteon_cache')) + if not os.path.exists(hass.config.path(INSTEON_CACHE)): + os.makedirs(hass.config.path(INSTEON_CACHE)) insteonhub = Hub(host, username, password, port, timeout, _LOGGER, - hass.config.path('.insteon_cache')) + hass.config.path(INSTEON_CACHE)) # Check for successful connection insteonhub.get_buffer_status() except requests.exceptions.ConnectTimeout: - _LOGGER.error("Error on insteon_local." - "Could not connect. Check config", exc_info=True) + _LOGGER.error( + "Could not connect. Check config", + exc_info=True) return False except requests.exceptions.ConnectionError: - _LOGGER.error("Error on insteon_local. Could not connect." - "Check config", exc_info=True) + _LOGGER.error( + "Could not connect. Check config", + exc_info=True) return False except requests.exceptions.RequestException: if insteonhub.http_code == 401: @@ -71,6 +78,12 @@ def setup(hass, config): _LOGGER.error("Error on insteon_local hub check", exc_info=True) return False + linked = insteonhub.get_linked() + hass.data['insteon_local'] = insteonhub + for insteon_platform in INSTEON_PLATFORMS: + load_platform(hass, insteon_platform, DOMAIN, {'linked': linked}, + config) + return True diff --git a/homeassistant/components/light/insteon_local.py b/homeassistant/components/light/insteon_local.py index 9d704327a1d..88d621d4060 100644 --- a/homeassistant/components/light/insteon_local.py +++ b/homeassistant/components/light/insteon_local.py @@ -10,8 +10,6 @@ from datetime import timedelta from homeassistant.components.light import ( ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light) import homeassistant.util as util -from homeassistant.util.json import load_json, save_json - _CONFIGURING = {} _LOGGER = logging.getLogger(__name__) @@ -19,8 +17,6 @@ _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['insteon_local'] DOMAIN = 'light' -INSTEON_LOCAL_LIGHTS_CONF = 'insteon_local_lights.conf' - MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) 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): """Set up the Insteon local light platform.""" insteonhub = hass.data['insteon_local'] - - 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.') - + if discovery_info is None: return - def insteon_light_config_callback(data): - """Set up actions to do when our configuration callback is called.""" - setup_light(device_id, data.get('name'), insteonhub, hass, - add_devices_callback) + linked = discovery_info['linked'] + device_list = [] + for device_id in linked: + if linked[device_id]['cat_type'] == 'dimmer': + device = insteonhub.dimmer(device_id) + device_list.append( + InsteonLocalDimmerDevice(device) + ) - _CONFIGURING[device_id] = configurator.request_config( - '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)]) + add_devices(device_list) class InsteonLocalDimmerDevice(Light): """An abstract Class for an Insteon node.""" - def __init__(self, node, name): + def __init__(self, node): """Initialize the device.""" self.node = node - self.node.deviceName = name self._value = 0 @property def name(self): """Return the name of the node.""" - return self.node.deviceName + return self.node.device_id @property def unique_id(self): diff --git a/homeassistant/components/switch/insteon_local.py b/homeassistant/components/switch/insteon_local.py index 5fd37c84986..c20a638c00f 100644 --- a/homeassistant/components/switch/insteon_local.py +++ b/homeassistant/components/switch/insteon_local.py @@ -9,7 +9,6 @@ from datetime import timedelta from homeassistant.components.switch import SwitchDevice import homeassistant.util as util -from homeassistant.util.json import load_json, save_json _CONFIGURING = {} _LOGGER = logging.getLogger(__name__) @@ -17,8 +16,6 @@ _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['insteon_local'] DOMAIN = 'switch' -INSTEON_LOCAL_SWITCH_CONF = 'insteon_local_switch.conf' - MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100) 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): """Set up the Insteon local switch platform.""" insteonhub = hass.data['insteon_local'] - - 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.') - + if discovery_info is None: return - def insteon_switch_config_callback(data): - """Handle configuration changes.""" - setup_switch(device_id, data.get('name'), insteonhub, hass, - add_devices_callback) + linked = discovery_info['linked'] + device_list = [] + for device_id in linked: + if linked[device_id]['cat_type'] == 'switch': + device = insteonhub.switch(device_id) + device_list.append( + InsteonLocalSwitchDevice(device) + ) - _CONFIGURING[device_id] = configurator.request_config( - '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)]) + add_devices(device_list) class InsteonLocalSwitchDevice(SwitchDevice): """An abstract Class for an Insteon node.""" - def __init__(self, node, name): + def __init__(self, node): """Initialize the device.""" self.node = node - self.node.deviceName = name self._state = False @property def name(self): """Return the name of the node.""" - return self.node.deviceName + return self.node.device_id @property def unique_id(self): diff --git a/requirements_all.txt b/requirements_all.txt index 4b076b1e1f2..68670fe7a1b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -400,7 +400,7 @@ iglo==1.0.0 influxdb==4.1.1 # homeassistant.components.insteon_local -insteonlocal==0.52 +insteonlocal==0.53 # homeassistant.components.insteon_plm insteonplm==0.7.5