From 7dbcf635430b0ea958fb6ee83a1f0d7582915801 Mon Sep 17 00:00:00 2001 From: pezinek Date: Wed, 2 Aug 2017 06:26:27 +0200 Subject: [PATCH] flux_led: support for property "available" (#8764) * flux_led: support for property "available" * Implemented changes from code review * Implemented changes from code review * Implemented changes from code review --- homeassistant/components/light/flux_led.py | 159 +++++++++------------ 1 file changed, 70 insertions(+), 89 deletions(-) diff --git a/homeassistant/components/light/flux_led.py b/homeassistant/components/light/flux_led.py index 8fe60d5e19e..21012f81658 100644 --- a/homeassistant/components/light/flux_led.py +++ b/homeassistant/components/light/flux_led.py @@ -53,28 +53,32 @@ EFFECT_PURPLE_STROBE = 'purple_strobe' EFFECT_WHITE_STROBE = 'white_strobe' EFFECT_COLORJUMP = 'colorjump' +EFFECT_MAP = { + EFFECT_COLORLOOP: 0x25, + EFFECT_RED_FADE: 0x26, + EFFECT_GREEN_FADE: 0x27, + EFFECT_BLUE_FADE: 0x28, + EFFECT_YELLOW_FADE: 0x29, + EFFECT_CYAN_FADE: 0x2a, + EFFECT_PURPLE_FADE: 0x2b, + EFFECT_WHITE_FADE: 0x2c, + EFFECT_RED_GREEN_CROSS_FADE: 0x2d, + EFFECT_RED_BLUE_CROSS_FADE: 0x2e, + EFFECT_GREEN_BLUE_CROSS_FADE: 0x2f, + EFFECT_COLORSTROBE: 0x30, + EFFECT_RED_STROBE: 0x31, + EFFECT_GREEN_STROBE: 0x32, + EFFECT_BLUE_STOBE: 0x33, + EFFECT_YELLOW_STROBE: 0x34, + EFFECT_CYAN_STROBE: 0x35, + EFFECT_PURPLE_STROBE: 0x36, + EFFECT_WHITE_STROBE: 0x37, + EFFECT_COLORJUMP: 0x38 +} + FLUX_EFFECT_LIST = [ - EFFECT_COLORLOOP, EFFECT_RANDOM, - EFFECT_RED_FADE, - EFFECT_GREEN_FADE, - EFFECT_BLUE_FADE, - EFFECT_YELLOW_FADE, - EFFECT_CYAN_FADE, - EFFECT_PURPLE_FADE, - EFFECT_WHITE_FADE, - EFFECT_RED_GREEN_CROSS_FADE, - EFFECT_RED_BLUE_CROSS_FADE, - EFFECT_GREEN_BLUE_CROSS_FADE, - EFFECT_COLORSTROBE, - EFFECT_RED_STROBE, - EFFECT_GREEN_STROBE, - EFFECT_BLUE_STOBE, - EFFECT_YELLOW_STROBE, - EFFECT_CYAN_STROBE, - EFFECT_PURPLE_STROBE, - EFFECT_WHITE_STROBE, - EFFECT_COLORJUMP] + ].extend(EFFECT_MAP.keys()) DEVICE_SCHEMA = vol.Schema({ vol.Optional(CONF_NAME): cv.string, @@ -103,12 +107,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): device[CONF_PROTOCOL] = device_config[CONF_PROTOCOL] device[ATTR_MODE] = device_config[ATTR_MODE] light = FluxLight(device) - if light.is_valid: - lights.append(light) - light_ips.append(ipaddr) + lights.append(light) + light_ips.append(ipaddr) if not config.get(CONF_AUTOMATIC_ADD, False): - add_devices(lights) + add_devices(lights, True) return # Find the bulbs on the LAN @@ -122,11 +125,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): device[ATTR_MODE] = 'rgbw' device[CONF_PROTOCOL] = None light = FluxLight(device) - if light.is_valid: - lights.append(light) - light_ips.append(ipaddr) + lights.append(light) - add_devices(lights) + add_devices(lights, True) class FluxLight(Light): @@ -134,32 +135,37 @@ class FluxLight(Light): def __init__(self, device): """Initialize the light.""" - import flux_led - self._name = device['name'] self._ipaddr = device['ipaddr'] self._protocol = device[CONF_PROTOCOL] self._mode = device[ATTR_MODE] - self.is_valid = True + self._bulb = None + self._error_reported = False + + def _connect(self): + """Connect to Flux light.""" + import flux_led + + self._bulb = flux_led.WifiLedBulb(self._ipaddr, timeout=5) + if self._protocol: + self._bulb.setProtocol(self._protocol) + + # After bulb object is created the status is updated. We can + # now set the correct mode if it was not explicitly defined. + if not self._mode: + if self._bulb.rgbwcapable: + self._mode = MODE_RGBW + else: + self._mode = MODE_RGB + + def _disconnect(self): + """Disconnect from Flux light.""" self._bulb = None - try: - self._bulb = flux_led.WifiLedBulb(self._ipaddr) - if self._protocol: - self._bulb.setProtocol(self._protocol) - - # After bulb object is created the status is updated. We can - # now set the correct mode if it was not explicitly defined. - if not self._mode: - if self._bulb.rgbwcapable: - self._mode = MODE_RGBW - else: - self._mode = MODE_RGB - - except socket.error: - self.is_valid = False - _LOGGER.error( - "Failed to connect to bulb %s, %s", self._ipaddr, self._name) + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self._bulb is not None @property def unique_id(self): @@ -204,6 +210,7 @@ class FluxLight(Light): rgb = kwargs.get(ATTR_RGB_COLOR) brightness = kwargs.get(ATTR_BRIGHTNESS) effect = kwargs.get(ATTR_EFFECT) + if rgb is not None and brightness is not None: self._bulb.setRgb(*tuple(rgb), brightness=brightness) elif rgb is not None: @@ -218,46 +225,8 @@ class FluxLight(Light): self._bulb.setRgb(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - elif effect == EFFECT_COLORLOOP: - self._bulb.setPresetPattern(0x25, 50) - elif effect == EFFECT_RED_FADE: - self._bulb.setPresetPattern(0x26, 50) - elif effect == EFFECT_GREEN_FADE: - self._bulb.setPresetPattern(0x27, 50) - elif effect == EFFECT_BLUE_FADE: - self._bulb.setPresetPattern(0x28, 50) - elif effect == EFFECT_YELLOW_FADE: - self._bulb.setPresetPattern(0x29, 50) - elif effect == EFFECT_CYAN_FADE: - self._bulb.setPresetPattern(0x2a, 50) - elif effect == EFFECT_PURPLE_FADE: - self._bulb.setPresetPattern(0x2b, 50) - elif effect == EFFECT_WHITE_FADE: - self._bulb.setPresetPattern(0x2c, 50) - elif effect == EFFECT_RED_GREEN_CROSS_FADE: - self._bulb.setPresetPattern(0x2d, 50) - elif effect == EFFECT_RED_BLUE_CROSS_FADE: - self._bulb.setPresetPattern(0x2e, 50) - elif effect == EFFECT_GREEN_BLUE_CROSS_FADE: - self._bulb.setPresetPattern(0x2f, 50) - elif effect == EFFECT_COLORSTROBE: - self._bulb.setPresetPattern(0x30, 50) - elif effect == EFFECT_RED_STROBE: - self._bulb.setPresetPattern(0x31, 50) - elif effect == EFFECT_GREEN_STROBE: - self._bulb.setPresetPattern(0x32, 50) - elif effect == EFFECT_BLUE_STOBE: - self._bulb.setPresetPattern(0x33, 50) - elif effect == EFFECT_YELLOW_STROBE: - self._bulb.setPresetPattern(0x34, 50) - elif effect == EFFECT_CYAN_STROBE: - self._bulb.setPresetPattern(0x35, 50) - elif effect == EFFECT_PURPLE_STROBE: - self._bulb.setPresetPattern(0x36, 50) - elif effect == EFFECT_WHITE_STROBE: - self._bulb.setPresetPattern(0x37, 50) - elif effect == EFFECT_COLORJUMP: - self._bulb.setPresetPattern(0x38, 50) + elif effect in EFFECT_MAP: + self._bulb.setPresetPattern(EFFECT_MAP[effect], 50) def turn_off(self, **kwargs): """Turn the specified or all lights off.""" @@ -265,4 +234,16 @@ class FluxLight(Light): def update(self): """Synchronize state with bulb.""" - self._bulb.refreshState() + if not self.available: + try: + self._connect() + self._error_reported = False + except socket.error: + self._disconnect() + if not self._error_reported: + _LOGGER.warning("Failed to connect to bulb %s, %s", + self._ipaddr, self._name) + self._error_reported = True + return + + self._bulb.update_state(retry=2)