From da8e9a437c1ddcd84efb9e840cffbbc75d74553f Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sun, 20 Aug 2017 15:31:56 +0200 Subject: [PATCH 1/4] Remove hass to init hack and use official interfaces --- .../components/binary_sensor/homematic.py | 3 +- homeassistant/components/climate/homematic.py | 3 +- homeassistant/components/cover/homematic.py | 3 +- homeassistant/components/homematic.py | 41 +++++++++---------- homeassistant/components/light/homematic.py | 3 +- homeassistant/components/sensor/homematic.py | 3 +- homeassistant/components/switch/homematic.py | 3 +- 7 files changed, 26 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/binary_sensor/homematic.py b/homeassistant/components/binary_sensor/homematic.py index a82431a5ab8805..2f464bc73cc581 100644 --- a/homeassistant/components/binary_sensor/homematic.py +++ b/homeassistant/components/binary_sensor/homematic.py @@ -35,8 +35,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMBinarySensor(hass, conf) - new_device.link_homematic() + new_device = HMBinarySensor(conf) devices.append(new_device) add_devices(devices) diff --git a/homeassistant/components/climate/homematic.py b/homeassistant/components/climate/homematic.py index 60cda24eef9c14..ce6e9580e54fcb 100644 --- a/homeassistant/components/climate/homematic.py +++ b/homeassistant/components/climate/homematic.py @@ -47,8 +47,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMThermostat(hass, conf) - new_device.link_homematic() + new_device = HMThermostat(conf) devices.append(new_device) add_devices(devices) diff --git a/homeassistant/components/cover/homematic.py b/homeassistant/components/cover/homematic.py index e8372b84ce4888..9e3d675cabebe0 100644 --- a/homeassistant/components/cover/homematic.py +++ b/homeassistant/components/cover/homematic.py @@ -21,8 +21,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMCover(hass, conf) - new_device.link_homematic() + new_device = HMCover(conf) devices.append(new_device) add_devices(devices) diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index f9583d9be7ae04..0c21a10368a073 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -4,8 +4,8 @@ For more details about this component, please refer to the documentation at https://home-assistant.io/components/homematic/ """ +import asyncio import os -import time import logging from datetime import timedelta from functools import partial @@ -18,7 +18,7 @@ CONF_PLATFORM, CONF_HOSTS, CONF_NAME, ATTR_ENTITY_ID) from homeassistant.helpers import discovery from homeassistant.helpers.entity import Entity -from homeassistant.helpers.event import track_time_interval +from homeassistant.helpers.event import async_track_time_interval from homeassistant.config import load_yaml_config_file REQUIREMENTS = ['pyhomematic==0.1.30'] @@ -121,7 +121,6 @@ ] DATA_HOMEMATIC = 'homematic' -DATA_DELAY = 'homematic_delay' DATA_DEVINIT = 'homematic_devinit' DATA_STORE = 'homematic_store' @@ -134,7 +133,6 @@ CONF_RESOLVENAMES = 'resolvenames' CONF_VARIABLES = 'variables' CONF_DEVICES = 'devices' -CONF_DELAY = 'delay' CONF_PRIMARY = 'primary' DEFAULT_LOCAL_IP = '0.0.0.0' @@ -145,7 +143,6 @@ DEFAULT_PASSWORD = '' DEFAULT_VARIABLES = False DEFAULT_DEVICES = True -DEFAULT_DELAY = 0.5 DEFAULT_PRIMARY = False @@ -177,7 +174,6 @@ }}, vol.Optional(CONF_LOCAL_IP, default=DEFAULT_LOCAL_IP): cv.string, vol.Optional(CONF_LOCAL_PORT, default=DEFAULT_LOCAL_PORT): cv.port, - vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): vol.Coerce(float), }), }, extra=vol.ALLOW_EXTRA) @@ -249,7 +245,6 @@ def setup(hass, config): """Set up the Homematic component.""" from pyhomematic import HMConnection - hass.data[DATA_DELAY] = config[DOMAIN].get(CONF_DELAY) hass.data[DATA_DEVINIT] = {} hass.data[DATA_STORE] = set() @@ -575,9 +570,8 @@ def _device_from_servicecall(hass, service): class HMHub(Entity): """The HomeMatic hub. (CCU2/HomeGear).""" - def __init__(self, hass, name, use_variables): + def __init__(self, name, use_variables): """Initialize HomeMatic hub.""" - self.hass = hass self.entity_id = "{}.{}".format(DOMAIN, name.lower()) self._homematic = hass.data[DATA_HOMEMATIC] self._variables = {} @@ -585,14 +579,17 @@ def __init__(self, hass, name, use_variables): self._state = STATE_UNKNOWN self._use_variables = use_variables + @asyncio.coroutine + def async_added_to_hass(self): + """Load data init callbacks.""" # Load data - track_time_interval(hass, self._update_hub, SCAN_INTERVAL_HUB) - self._update_hub(None) + async_track_time_interval(hass, self._update_hub, SCAN_INTERVAL_HUB) + yield from self.hass.async_add_job(self._update_hub, None) if self._use_variables: - track_time_interval( + async_track_time_interval( hass, self._update_variables, SCAN_INTERVAL_VARIABLES) - self._update_variables(None) + yield from self.hass.async_add_job(self._update_variables, None) @property def name(self): @@ -624,7 +621,9 @@ def _update_hub(self, now): """Retrieve latest state.""" state = self._homematic.getServiceMessages(self._name) self._state = STATE_UNKNOWN if state is None else len(state) - self.schedule_update_ha_state() + + if now: + self.schedule_update_ha_state() def _update_variables(self, now): """Retrive all variable data and update hmvariable states.""" @@ -640,7 +639,7 @@ def _update_variables(self, now): state_change = True self._variables.update({key: value}) - if state_change: + if state_change and now: self.schedule_update_ha_state() def hm_set_variable(self, name, value): @@ -662,9 +661,8 @@ def hm_set_variable(self, name, value): class HMDevice(Entity): """The HomeMatic device base object.""" - def __init__(self, hass, config): + def __init__(self, config): """Initialize a generic HomeMatic device.""" - self.hass = hass self._homematic = hass.data[DATA_HOMEMATIC] self._name = config.get(ATTR_NAME) self._address = config.get(ATTR_ADDRESS) @@ -680,6 +678,11 @@ def __init__(self, hass, config): if self._state: self._state = self._state.upper() + @asyncio.coroutine + def async_added_to_hass(self): + """Load data init callbacks.""" + yield from self.hass.async_add_job(self.link_homematic) + @property def should_poll(self): """Return false. HomeMatic states are pushed by the XML-RPC Server.""" @@ -734,10 +737,6 @@ def link_homematic(self): try: # Initialize datapoints of this object self._init_data() - if self.hass.data[DATA_DELAY]: - # We optionally delay / pause loading of data to avoid - # overloading of CCU / Homegear - time.sleep(self.hass.data[DATA_DELAY]) self._load_data_from_hm() # Link events from pyhomematic diff --git a/homeassistant/components/light/homematic.py b/homeassistant/components/light/homematic.py index 60865dd223e814..807c19fffdb32d 100644 --- a/homeassistant/components/light/homematic.py +++ b/homeassistant/components/light/homematic.py @@ -24,8 +24,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMLight(hass, conf) - new_device.link_homematic() + new_device = HMLight(conf) devices.append(new_device) add_devices(devices) diff --git a/homeassistant/components/sensor/homematic.py b/homeassistant/components/sensor/homematic.py index 771b4a94bd492f..061fd27ca69785 100644 --- a/homeassistant/components/sensor/homematic.py +++ b/homeassistant/components/sensor/homematic.py @@ -57,8 +57,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMSensor(hass, conf) - new_device.link_homematic() + new_device = HMSensor(conf) devices.append(new_device) add_devices(devices) diff --git a/homeassistant/components/switch/homematic.py b/homeassistant/components/switch/homematic.py index 566eff99828a93..487947598bbadf 100644 --- a/homeassistant/components/switch/homematic.py +++ b/homeassistant/components/switch/homematic.py @@ -21,8 +21,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMSwitch(hass, conf) - new_device.link_homematic() + new_device = HMSwitch(conf) devices.append(new_device) add_devices(devices) From 797baed86a3e024eac57eee93d1f1b6fd57c118c Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sun, 20 Aug 2017 15:58:05 +0200 Subject: [PATCH 2/4] fix lint --- homeassistant/components/homematic.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index 0c21a10368a073..3a6143de344d30 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -583,12 +583,13 @@ def __init__(self, name, use_variables): def async_added_to_hass(self): """Load data init callbacks.""" # Load data - async_track_time_interval(hass, self._update_hub, SCAN_INTERVAL_HUB) + async_track_time_interval( + self.hass, self._update_hub, SCAN_INTERVAL_HUB) yield from self.hass.async_add_job(self._update_hub, None) if self._use_variables: async_track_time_interval( - hass, self._update_variables, SCAN_INTERVAL_VARIABLES) + self.hass, self._update_variables, SCAN_INTERVAL_VARIABLES) yield from self.hass.async_add_job(self._update_variables, None) @property From 7acb2dd858ac17d4ef69dcf2ae9066e654cfb0b9 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 30 Aug 2017 23:39:50 +0200 Subject: [PATCH 3/4] Fix lint --- homeassistant/components/homematic.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index 3a6143de344d30..81a4424729f6f9 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -272,7 +272,7 @@ def setup(hass, config): # Create server thread bound_system_callback = partial(_system_callback_handler, hass, config) - hass.data[DATA_HOMEMATIC] = HMConnection( + hass.data[DATA_HOMEMATIC] = homematic = HMConnection( local=config[DOMAIN].get(CONF_LOCAL_IP), localport=config[DOMAIN].get(CONF_LOCAL_PORT), remotes=remotes, @@ -281,7 +281,7 @@ def setup(hass, config): ) # Start server thread, connect to hosts, initialize to receive events - hass.data[DATA_HOMEMATIC].start() + homematic.start() # Stops server when HASS is shutting down hass.bus.listen_once( @@ -291,7 +291,7 @@ def setup(hass, config): entity_hubs = [] for _, hub_data in hosts.items(): entity_hubs.append(HMHub( - hass, hub_data[CONF_NAME], hub_data[CONF_VARIABLES])) + homematic, hub_data[CONF_NAME], hub_data[CONF_VARIABLES])) # Register HomeMatic services descriptions = load_yaml_config_file( @@ -354,7 +354,7 @@ def _service_handle_value(service): def _service_handle_reconnect(service): """Service to reconnect all HomeMatic hubs.""" - hass.data[DATA_HOMEMATIC].reconnect() + homematic.reconnect() hass.services.register( DOMAIN, SERVICE_RECONNECT, _service_handle_reconnect, @@ -570,10 +570,10 @@ def _device_from_servicecall(hass, service): class HMHub(Entity): """The HomeMatic hub. (CCU2/HomeGear).""" - def __init__(self, name, use_variables): + def __init__(self, homematic, name, use_variables): """Initialize HomeMatic hub.""" self.entity_id = "{}.{}".format(DOMAIN, name.lower()) - self._homematic = hass.data[DATA_HOMEMATIC] + self._homematic = homematic self._variables = {} self._name = name self._state = STATE_UNKNOWN @@ -664,13 +664,13 @@ class HMDevice(Entity): def __init__(self, config): """Initialize a generic HomeMatic device.""" - self._homematic = hass.data[DATA_HOMEMATIC] self._name = config.get(ATTR_NAME) self._address = config.get(ATTR_ADDRESS) self._proxy = config.get(ATTR_PROXY) self._channel = config.get(ATTR_CHANNEL) self._state = config.get(ATTR_PARAM) self._data = {} + self._homematic = None self._hmdevice = None self._connected = False self._available = False @@ -682,6 +682,7 @@ def __init__(self, config): @asyncio.coroutine def async_added_to_hass(self): """Load data init callbacks.""" + self._homematic = self.hass.data[DATA_HOMEMATIC] yield from self.hass.async_add_job(self.link_homematic) @property From b369917c551c55bedb8ace6e4e2abee3576244bc Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 31 Aug 2017 20:38:04 +0200 Subject: [PATCH 4/4] change style --- homeassistant/components/homematic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index 81a4424729f6f9..dc5e641cbbaab1 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -682,7 +682,6 @@ def __init__(self, config): @asyncio.coroutine def async_added_to_hass(self): """Load data init callbacks.""" - self._homematic = self.hass.data[DATA_HOMEMATIC] yield from self.hass.async_add_job(self.link_homematic) @property @@ -733,6 +732,7 @@ def link_homematic(self): return True # Initialize + self._homematic = self.hass.data[DATA_HOMEMATIC] self._hmdevice = self._homematic.devices[self._proxy][self._address] self._connected = True