From 4d20e36a756609ce03d2ec42eb716de184713afd Mon Sep 17 00:00:00 2001 From: Peter Balogh Date: Wed, 21 Nov 2018 21:31:21 +0100 Subject: [PATCH 1/4] Use asyncio Lock for fibaro light --- homeassistant/components/light/fibaro.py | 130 +++++++++++++---------- 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/homeassistant/components/light/fibaro.py b/homeassistant/components/light/fibaro.py index cfc28e12218a9b..840798b3b007bf 100644 --- a/homeassistant/components/light/fibaro.py +++ b/homeassistant/components/light/fibaro.py @@ -6,7 +6,8 @@ """ import logging -import threading +import asyncio +from functools import partial from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_WHITE_VALUE, ENTITY_ID_FORMAT, @@ -37,12 +38,15 @@ def scaleto100(value): return max(0, min(100, ((value * 100.4) / 255.0))) -def setup_platform(hass, config, add_entities, discovery_info=None): +async def async_setup_platform(hass, + config, + async_add_entities, + discovery_info=None): """Perform the setup for Fibaro controller devices.""" if discovery_info is None: return - add_entities( + async_add_entities( [FibaroLight(device, hass.data[FIBARO_CONTROLLER]) for device in hass.data[FIBARO_DEVICES]['light']], True) @@ -58,7 +62,7 @@ def __init__(self, fibaro_device, controller): self._brightness = None self._white = 0 - self._update_lock = threading.RLock() + self._update_lock = asyncio.Lock() if 'levelChange' in fibaro_device.interfaces: self._supported_flags |= SUPPORT_BRIGHTNESS if 'color' in fibaro_device.properties: @@ -88,45 +92,49 @@ def supported_features(self): """Flag supported features.""" return self._supported_flags - def turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs): """Turn the light on.""" - with self._update_lock: - if self._supported_flags & SUPPORT_BRIGHTNESS: - target_brightness = kwargs.get(ATTR_BRIGHTNESS) - - # No brightness specified, so we either restore it to - # last brightness or switch it on at maximum level - if target_brightness is None: - if self._brightness == 0: - if self._last_brightness: - self._brightness = self._last_brightness - else: - self._brightness = 100 - else: - # We set it to the target brightness and turn it on - self._brightness = scaleto100(target_brightness) - - if self._supported_flags & SUPPORT_COLOR: - # Update based on parameters - self._white = kwargs.get(ATTR_WHITE_VALUE, self._white) - self._color = kwargs.get(ATTR_HS_COLOR, self._color) - rgb = color_util.color_hs_to_RGB(*self._color) - self.call_set_color( - int(rgb[0] * self._brightness / 99.0 + 0.5), - int(rgb[1] * self._brightness / 99.0 + 0.5), - int(rgb[2] * self._brightness / 99.0 + 0.5), - int(self._white * self._brightness / 99.0 + - 0.5)) - if self.state == 'off': - self.set_level(int(self._brightness)) - return - - if self._supported_flags & SUPPORT_BRIGHTNESS: + async with self._update_lock: + await self.hass.async_add_executor_job(partial(self._turn_on, **kwargs)) + + def _turn_on(self, **kwargs): + """Really turn the light on.""" + if self._supported_flags & SUPPORT_BRIGHTNESS: + target_brightness = kwargs.get(ATTR_BRIGHTNESS) + + # No brightness specified, so we either restore it to + # last brightness or switch it on at maximum level + if target_brightness is None: + if self._brightness == 0: + if self._last_brightness: + self._brightness = self._last_brightness + else: + self._brightness = 100 + else: + # We set it to the target brightness and turn it on + self._brightness = scaleto100(target_brightness) + + if self._supported_flags & SUPPORT_COLOR: + # Update based on parameters + self._white = kwargs.get(ATTR_WHITE_VALUE, self._white) + self._color = kwargs.get(ATTR_HS_COLOR, self._color) + rgb = color_util.color_hs_to_RGB(*self._color) + self.call_set_color( + int(rgb[0] * self._brightness / 99.0 + 0.5), + int(rgb[1] * self._brightness / 99.0 + 0.5), + int(rgb[2] * self._brightness / 99.0 + 0.5), + int(self._white * self._brightness / 99.0 + + 0.5)) + if self.state == 'off': self.set_level(int(self._brightness)) - return + return + + if self._supported_flags & SUPPORT_BRIGHTNESS: + self.set_level(int(self._brightness)) + return - # The simplest case is left for last. No dimming, just switch on - self.call_turn_on() + # The simplest case is left for last. No dimming, just switch on + self.call_turn_on() def turn_off(self, **kwargs): """Turn the light off.""" @@ -143,23 +151,27 @@ def is_on(self): """Return true if device is on.""" return self.current_binary_state - def update(self): - """Call to update state.""" + async def async_update(self): + """Update the state.""" + async with self._update_lock: + await self.hass.async_add_executor_job(self._update) + + def _update(self): + """Really update the state.""" # Brightness handling - with self._update_lock: - if self._supported_flags & SUPPORT_BRIGHTNESS: - self._brightness = float(self.fibaro_device.properties.value) - # Color handling - if self._supported_flags & SUPPORT_COLOR: - # Fibaro communicates the color as an 'R, G, B, W' string - rgbw_s = self.fibaro_device.properties.color - if rgbw_s == '0,0,0,0' and\ - 'lastColorSet' in self.fibaro_device.properties: - rgbw_s = self.fibaro_device.properties.lastColorSet - rgbw_list = [int(i) for i in rgbw_s.split(",")][:4] - if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]: - self._color = color_util.color_RGB_to_hs(*rgbw_list[:3]) - if (self._supported_flags & SUPPORT_WHITE_VALUE) and \ - self.brightness != 0: - self._white = min(255, max(0, rgbw_list[3]*100.0 / - self._brightness)) + if self._supported_flags & SUPPORT_BRIGHTNESS: + self._brightness = float(self.fibaro_device.properties.value) + # Color handling + if self._supported_flags & SUPPORT_COLOR: + # Fibaro communicates the color as an 'R, G, B, W' string + rgbw_s = self.fibaro_device.properties.color + if rgbw_s == '0,0,0,0' and\ + 'lastColorSet' in self.fibaro_device.properties: + rgbw_s = self.fibaro_device.properties.lastColorSet + rgbw_list = [int(i) for i in rgbw_s.split(",")][:4] + if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]: + self._color = color_util.color_RGB_to_hs(*rgbw_list[:3]) + if (self._supported_flags & SUPPORT_WHITE_VALUE) and \ + self.brightness != 0: + self._white = min(255, max(0, rgbw_list[3]*100.0 / + self._brightness)) \ No newline at end of file From bdeca2c663523eeabbd8c0b14f689573228ee7be Mon Sep 17 00:00:00 2001 From: Peter Balogh Date: Wed, 21 Nov 2018 21:49:39 +0100 Subject: [PATCH 2/4] line length and empty line at end --- homeassistant/components/light/fibaro.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/fibaro.py b/homeassistant/components/light/fibaro.py index 840798b3b007bf..1a592b6efcb85a 100644 --- a/homeassistant/components/light/fibaro.py +++ b/homeassistant/components/light/fibaro.py @@ -95,7 +95,8 @@ def supported_features(self): async def async_turn_on(self, **kwargs): """Turn the light on.""" async with self._update_lock: - await self.hass.async_add_executor_job(partial(self._turn_on, **kwargs)) + await self.hass.async_add_executor_job( + partial(self._turn_on, **kwargs)) def _turn_on(self, **kwargs): """Really turn the light on.""" @@ -174,4 +175,4 @@ def _update(self): if (self._supported_flags & SUPPORT_WHITE_VALUE) and \ self.brightness != 0: self._white = min(255, max(0, rgbw_list[3]*100.0 / - self._brightness)) \ No newline at end of file + self._brightness)) From 04b3e4df4f82fd8c26126483738cd4ed439e2251 Mon Sep 17 00:00:00 2001 From: Peter Balogh Date: Thu, 22 Nov 2018 17:17:54 +0100 Subject: [PATCH 3/4] async turn_off Turned the turn_off into async as well --- homeassistant/components/light/fibaro.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/light/fibaro.py b/homeassistant/components/light/fibaro.py index 1a592b6efcb85a..c17c5ce558439b 100644 --- a/homeassistant/components/light/fibaro.py +++ b/homeassistant/components/light/fibaro.py @@ -137,15 +137,21 @@ def _turn_on(self, **kwargs): # The simplest case is left for last. No dimming, just switch on self.call_turn_on() - def turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs): """Turn the light off.""" + async with self._update_lock: + await self.hass.async_add_executor_job( + partial(self._turn_off, **kwargs)) + + def _turn_off(self, **kwargs): + """Really turn the light off.""" + # Let's save the last brightness level before we switch it off - with self._update_lock: - if (self._supported_flags & SUPPORT_BRIGHTNESS) and \ - self._brightness and self._brightness > 0: - self._last_brightness = self._brightness - self._brightness = 0 - self.call_turn_off() + if (self._supported_flags & SUPPORT_BRIGHTNESS) and \ + self._brightness and self._brightness > 0: + self._last_brightness = self._brightness + self._brightness = 0 + self.call_turn_off() @property def is_on(self): From 43ab459702065311078f99ee37779baade91110e Mon Sep 17 00:00:00 2001 From: Peter Balogh Date: Thu, 22 Nov 2018 18:42:28 +0100 Subject: [PATCH 4/4] bless you, blank lines... My local flake8 lies to me. Not cool. --- homeassistant/components/light/fibaro.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/light/fibaro.py b/homeassistant/components/light/fibaro.py index c17c5ce558439b..96069d50335fe2 100644 --- a/homeassistant/components/light/fibaro.py +++ b/homeassistant/components/light/fibaro.py @@ -145,7 +145,6 @@ async def async_turn_off(self, **kwargs): def _turn_off(self, **kwargs): """Really turn the light off.""" - # Let's save the last brightness level before we switch it off if (self._supported_flags & SUPPORT_BRIGHTNESS) and \ self._brightness and self._brightness > 0: