Use asyncio Lock for fibaro light (#18622)

* Use asyncio Lock for fibaro light

* line length and empty line at end

* async turn_off

Turned the turn_off into async as well

* bless you, blank lines...

My local flake8 lies to me. Not cool.
This commit is contained in:
pbalogh77 2018-11-26 13:17:56 +01:00 committed by Martin Hjelmare
parent b5b5bc2de8
commit 4a661e351f

View File

@ -6,7 +6,8 @@ https://home-assistant.io/components/light.fibaro/
""" """
import logging import logging
import threading import asyncio
from functools import partial
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_WHITE_VALUE, ENTITY_ID_FORMAT, 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))) 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.""" """Perform the setup for Fibaro controller devices."""
if discovery_info is None: if discovery_info is None:
return return
add_entities( async_add_entities(
[FibaroLight(device, hass.data[FIBARO_CONTROLLER]) [FibaroLight(device, hass.data[FIBARO_CONTROLLER])
for device in hass.data[FIBARO_DEVICES]['light']], True) for device in hass.data[FIBARO_DEVICES]['light']], True)
@ -58,7 +62,7 @@ class FibaroLight(FibaroDevice, Light):
self._brightness = None self._brightness = None
self._white = 0 self._white = 0
self._update_lock = threading.RLock() self._update_lock = asyncio.Lock()
if 'levelChange' in fibaro_device.interfaces: if 'levelChange' in fibaro_device.interfaces:
self._supported_flags |= SUPPORT_BRIGHTNESS self._supported_flags |= SUPPORT_BRIGHTNESS
if 'color' in fibaro_device.properties: if 'color' in fibaro_device.properties:
@ -88,78 +92,92 @@ class FibaroLight(FibaroDevice, Light):
"""Flag supported features.""" """Flag supported features."""
return self._supported_flags return self._supported_flags
def turn_on(self, **kwargs): async def async_turn_on(self, **kwargs):
"""Turn the light on.""" """Turn the light on."""
with self._update_lock: async with self._update_lock:
if self._supported_flags & SUPPORT_BRIGHTNESS: await self.hass.async_add_executor_job(
target_brightness = kwargs.get(ATTR_BRIGHTNESS) partial(self._turn_on, **kwargs))
# No brightness specified, so we either restore it to def _turn_on(self, **kwargs):
# last brightness or switch it on at maximum level """Really turn the light on."""
if target_brightness is None: if self._supported_flags & SUPPORT_BRIGHTNESS:
if self._brightness == 0: target_brightness = kwargs.get(ATTR_BRIGHTNESS)
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: # No brightness specified, so we either restore it to
# Update based on parameters # last brightness or switch it on at maximum level
self._white = kwargs.get(ATTR_WHITE_VALUE, self._white) if target_brightness is None:
self._color = kwargs.get(ATTR_HS_COLOR, self._color) if self._brightness == 0:
rgb = color_util.color_hs_to_RGB(*self._color) if self._last_brightness:
self.call_set_color( self._brightness = self._last_brightness
int(rgb[0] * self._brightness / 99.0 + 0.5), else:
int(rgb[1] * self._brightness / 99.0 + 0.5), self._brightness = 100
int(rgb[2] * self._brightness / 99.0 + 0.5), else:
int(self._white * self._brightness / 99.0 + # We set it to the target brightness and turn it on
0.5)) self._brightness = scaleto100(target_brightness)
if self.state == 'off':
self.set_level(int(self._brightness))
return
if self._supported_flags & SUPPORT_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)) self.set_level(int(self._brightness))
return return
# The simplest case is left for last. No dimming, just switch on if self._supported_flags & SUPPORT_BRIGHTNESS:
self.call_turn_on() self.set_level(int(self._brightness))
return
def turn_off(self, **kwargs): # The simplest case is left for last. No dimming, just switch on
self.call_turn_on()
async def async_turn_off(self, **kwargs):
"""Turn the light off.""" """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 # Let's save the last brightness level before we switch it off
with self._update_lock: if (self._supported_flags & SUPPORT_BRIGHTNESS) and \
if (self._supported_flags & SUPPORT_BRIGHTNESS) and \ self._brightness and self._brightness > 0:
self._brightness and self._brightness > 0: self._last_brightness = self._brightness
self._last_brightness = self._brightness self._brightness = 0
self._brightness = 0 self.call_turn_off()
self.call_turn_off()
@property @property
def is_on(self): def is_on(self):
"""Return true if device is on.""" """Return true if device is on."""
return self.current_binary_state return self.current_binary_state
def update(self): async def async_update(self):
"""Call to update state.""" """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 # Brightness handling
with self._update_lock: if self._supported_flags & SUPPORT_BRIGHTNESS:
if self._supported_flags & SUPPORT_BRIGHTNESS: self._brightness = float(self.fibaro_device.properties.value)
self._brightness = float(self.fibaro_device.properties.value) # Color handling
# Color handling if self._supported_flags & SUPPORT_COLOR:
if self._supported_flags & SUPPORT_COLOR: # Fibaro communicates the color as an 'R, G, B, W' string
# Fibaro communicates the color as an 'R, G, B, W' string rgbw_s = self.fibaro_device.properties.color
rgbw_s = self.fibaro_device.properties.color if rgbw_s == '0,0,0,0' and\
if rgbw_s == '0,0,0,0' and\ 'lastColorSet' in self.fibaro_device.properties:
'lastColorSet' in self.fibaro_device.properties: rgbw_s = self.fibaro_device.properties.lastColorSet
rgbw_s = self.fibaro_device.properties.lastColorSet rgbw_list = [int(i) for i in rgbw_s.split(",")][:4]
rgbw_list = [int(i) for i in rgbw_s.split(",")][:4] if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]:
if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]: self._color = color_util.color_RGB_to_hs(*rgbw_list[:3])
self._color = color_util.color_RGB_to_hs(*rgbw_list[:3]) if (self._supported_flags & SUPPORT_WHITE_VALUE) and \
if (self._supported_flags & SUPPORT_WHITE_VALUE) and \ self.brightness != 0:
self.brightness != 0: self._white = min(255, max(0, rgbw_list[3]*100.0 /
self._white = min(255, max(0, rgbw_list[3]*100.0 / self._brightness))
self._brightness))