LIFX: handle unavailable lights gracefully
Recent aiolifx allow sending messages to unregistered devices (as a no-op). This is handy because bulbs can disappear anytime we yield and constantly testing for availability is both error-prone and annoying. So keep the aiolifx device around until a new one registers on the same mac_addr.
This commit is contained in:
parent
494a776959
commit
78a3f259d6
2 changed files with 24 additions and 22 deletions
|
@ -93,6 +93,7 @@ class LIFXManager(object):
|
|||
if device.mac_addr in self.entities:
|
||||
entity = self.entities[device.mac_addr]
|
||||
entity.device = device
|
||||
entity.registered = True
|
||||
_LOGGER.debug("%s register AGAIN", entity.who)
|
||||
self.hass.async_add_job(entity.async_update_ha_state())
|
||||
else:
|
||||
|
@ -118,7 +119,7 @@ class LIFXManager(object):
|
|||
if device.mac_addr in self.entities:
|
||||
entity = self.entities[device.mac_addr]
|
||||
_LOGGER.debug("%s unregister", entity.who)
|
||||
entity.device = None
|
||||
entity.registered = False
|
||||
self.hass.async_add_job(entity.async_update_ha_state())
|
||||
|
||||
|
||||
|
@ -172,6 +173,7 @@ class LIFXLight(Light):
|
|||
def __init__(self, device):
|
||||
"""Initialize the light."""
|
||||
self.device = device
|
||||
self.registered = True
|
||||
self.product = device.product
|
||||
self.blocker = None
|
||||
self.effect_data = None
|
||||
|
@ -183,7 +185,7 @@ class LIFXLight(Light):
|
|||
@property
|
||||
def available(self):
|
||||
"""Return the availability of the device."""
|
||||
return self.device is not None
|
||||
return self.registered
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -345,7 +347,7 @@ class LIFXLight(Light):
|
|||
def async_update(self):
|
||||
"""Update bulb status (if it is available)."""
|
||||
_LOGGER.debug("%s async_update", self.who)
|
||||
if self.available and self.blocker is None:
|
||||
if self.blocker is None:
|
||||
yield from self.refresh_state()
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -357,11 +359,12 @@ class LIFXLight(Light):
|
|||
@asyncio.coroutine
|
||||
def refresh_state(self):
|
||||
"""Ask the device about its current state and update our copy."""
|
||||
msg = yield from AwaitAioLIFX(self).wait(self.device.get_color)
|
||||
if msg is not None:
|
||||
self.set_power(self.device.power_level)
|
||||
self.set_color(*self.device.color)
|
||||
self._name = self.device.label
|
||||
if self.available:
|
||||
msg = yield from AwaitAioLIFX(self).wait(self.device.get_color)
|
||||
if msg is not None:
|
||||
self.set_power(self.device.power_level)
|
||||
self.set_color(*self.device.color)
|
||||
self._name = self.device.label
|
||||
|
||||
def find_hsbk(self, **kwargs):
|
||||
"""Find the desired color from a number of possible inputs."""
|
||||
|
|
|
@ -176,18 +176,16 @@ class LIFXEffect(object):
|
|||
def async_setup(self, **kwargs):
|
||||
"""Prepare all lights for the effect."""
|
||||
for light in self.lights:
|
||||
# Remember the current state (as far as we know it)
|
||||
yield from light.refresh_state()
|
||||
if not light.device:
|
||||
self.lights.remove(light)
|
||||
else:
|
||||
light.effect_data = LIFXEffectData(
|
||||
self, light.is_on, light.device.color)
|
||||
light.effect_data = LIFXEffectData(
|
||||
self, light.is_on, light.device.color)
|
||||
|
||||
# Temporarily turn on power for the effect to be visible
|
||||
if kwargs[ATTR_POWER_ON] and not light.is_on:
|
||||
hsbk = self.from_poweroff_hsbk(light, **kwargs)
|
||||
light.device.set_color(hsbk)
|
||||
light.device.set_power(True)
|
||||
# Temporarily turn on power for the effect to be visible
|
||||
if kwargs[ATTR_POWER_ON] and not light.is_on:
|
||||
hsbk = self.from_poweroff_hsbk(light, **kwargs)
|
||||
light.device.set_color(hsbk)
|
||||
light.device.set_power(True)
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
@asyncio.coroutine
|
||||
|
@ -202,12 +200,13 @@ class LIFXEffect(object):
|
|||
self.lights.remove(light)
|
||||
|
||||
if light.effect_data and light.effect_data.effect == self:
|
||||
if light.device and not light.effect_data.power:
|
||||
if not light.effect_data.power:
|
||||
light.device.set_power(False)
|
||||
yield from asyncio.sleep(0.5)
|
||||
if light.device:
|
||||
light.device.set_color(light.effect_data.color)
|
||||
yield from asyncio.sleep(0.5)
|
||||
|
||||
light.device.set_color(light.effect_data.color)
|
||||
yield from asyncio.sleep(0.5)
|
||||
|
||||
light.effect_data = None
|
||||
yield from light.refresh_state()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue