diff --git a/homeassistant/components/light/lifx/__init__.py b/homeassistant/components/light/lifx/__init__.py index f1b20f904d2..f13934011e9 100644 --- a/homeassistant/components/light/lifx/__init__.py +++ b/homeassistant/components/light/lifx/__init__.py @@ -32,7 +32,7 @@ from . import effects as lifx_effects _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['aiolifx==0.4.5'] +REQUIREMENTS = ['aiolifx==0.4.6'] UDP_BROADCAST_PORT = 56700 @@ -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): @@ -263,17 +265,19 @@ class LIFXLight(Light): """Return the list of supported effects.""" return lifx_effects.effect_list() - @callback + @asyncio.coroutine def update_after_transition(self, now): """Request new status after completion of the last transition.""" self.postponed_update = None - self.hass.async_add_job(self.async_update_ha_state(force_refresh=True)) + yield from self.refresh_state() + yield from self.async_update_ha_state() - @callback + @asyncio.coroutine def unblock_updates(self, now): """Allow async_update after the new state has settled on the bulb.""" self.blocker = None - self.hass.async_add_job(self.async_update_ha_state(force_refresh=True)) + yield from self.refresh_state() + yield from self.async_update_ha_state() def update_later(self, when): """Block immediate update requests and schedule one for later.""" @@ -343,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 @@ -355,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.""" diff --git a/homeassistant/components/light/lifx/effects.py b/homeassistant/components/light/lifx/effects.py index 07b97d03a12..a15360df33e 100644 --- a/homeassistant/components/light/lifx/effects.py +++ b/homeassistant/components/light/lifx/effects.py @@ -31,6 +31,8 @@ ATTR_CHANGE = 'change' WAVEFORM_SINE = 1 WAVEFORM_PULSE = 4 +NEUTRAL_WHITE = 3500 + LIFX_EFFECT_SCHEMA = vol.Schema({ vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Optional(ATTR_POWER_ON, default=True): cv.boolean, @@ -174,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 @@ -196,20 +196,23 @@ class LIFXEffect(object): @asyncio.coroutine def async_restore(self, light): """Restore to the original state (if we are still running).""" - if light.effect_data: - if light.effect_data.effect == self: - if light.device and 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.effect_data = None + if light in self.lights: self.lights.remove(light) + if light.effect_data and light.effect_data.effect == self: + if not light.effect_data.power: + light.device.set_power(False) + 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() + def from_poweroff_hsbk(self, light, **kwargs): """Return the color when starting from a powered off state.""" - return None + return [random.randint(0, 65535), 65535, 0, NEUTRAL_WHITE] class LIFXEffectBreathe(LIFXEffect): @@ -312,7 +315,7 @@ class LIFXEffectColorloop(LIFXEffect): int(65535/359*lhue), int(random.uniform(0.8, 1.0)*65535), brightness, - 4000, + NEUTRAL_WHITE, ] light.device.set_color(hsbk, None, transition) @@ -322,10 +325,6 @@ class LIFXEffectColorloop(LIFXEffect): yield from asyncio.sleep(period) - def from_poweroff_hsbk(self, light, **kwargs): - """Start from a random hue.""" - return [random.randint(0, 65535), 65535, 0, 4000] - class LIFXEffectStop(LIFXEffect): """A no-op effect, but starting it will stop an existing effect.""" diff --git a/requirements_all.txt b/requirements_all.txt index b375c904113..4f0edd805e1 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -48,7 +48,7 @@ aiodns==1.1.1 aiohttp_cors==0.5.3 # homeassistant.components.light.lifx -aiolifx==0.4.5 +aiolifx==0.4.6 # homeassistant.components.alarmdecoder alarmdecoder==0.12.1.0