Fix LIFX effects (#16309)

pull/16324/head
Anders Melchiorsen 2018-08-31 10:17:11 +02:00 committed by Paulus Schoutsen
parent 8be7a0a9b9
commit 16a58bd1cf
2 changed files with 64 additions and 64 deletions

View File

@ -52,6 +52,8 @@ homeassistant/components/cover/template.py @PhracturedBlue
homeassistant/components/device_tracker/automatic.py @armills
homeassistant/components/device_tracker/tile.py @bachya
homeassistant/components/history_graph.py @andrey-git
homeassistant/components/light/lifx.py @amelchio
homeassistant/components/light/lifx_legacy.py @amelchio
homeassistant/components/light/tplink.py @rytilahti
homeassistant/components/light/yeelight.py @rytilahti
homeassistant/components/lock/nello.py @pschmitt
@ -65,6 +67,7 @@ homeassistant/components/media_player/sonos.py @amelchio
homeassistant/components/media_player/xiaomi_tv.py @fattdev
homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth
homeassistant/components/plant.py @ChristianKuehnel
homeassistant/components/scene/lifx_cloud.py @amelchio
homeassistant/components/sensor/airvisual.py @bachya
homeassistant/components/sensor/filter.py @dgomes
homeassistant/components/sensor/gearbest.py @HerrHofrat

View File

@ -167,9 +167,9 @@ async def async_setup_platform(hass,
return True
def lifx_features(device):
"""Return a feature map for this device, or a default map if unknown."""
return aiolifx().products.features_map.get(device.product) or \
def lifx_features(bulb):
"""Return a feature map for this bulb, or a default map if unknown."""
return aiolifx().products.features_map.get(bulb.product) or \
aiolifx().products.features_map.get(1)
@ -256,7 +256,7 @@ class LIFXManager:
async def start_effect(self, entities, service, **kwargs):
"""Start a light effect on entities."""
devices = [light.device for light in entities]
bulbs = [light.bulb for light in entities]
if service == SERVICE_EFFECT_PULSE:
effect = aiolifx_effects().EffectPulse(
@ -266,7 +266,7 @@ class LIFXManager:
mode=kwargs.get(ATTR_MODE),
hsbk=find_hsbk(**kwargs),
)
await self.effects_conductor.start(effect, devices)
await self.effects_conductor.start(effect, bulbs)
elif service == SERVICE_EFFECT_COLORLOOP:
preprocess_turn_on_alternatives(kwargs)
@ -282,12 +282,12 @@ class LIFXManager:
transition=kwargs.get(ATTR_TRANSITION),
brightness=brightness,
)
await self.effects_conductor.start(effect, devices)
await self.effects_conductor.start(effect, bulbs)
elif service == SERVICE_EFFECT_STOP:
await self.effects_conductor.stop(devices)
await self.effects_conductor.stop(bulbs)
def service_to_entities(self, service):
"""Return the known devices that a service call mentions."""
"""Return the known entities that a service call mentions."""
entity_ids = extract_entity_ids(self.hass, service)
if entity_ids:
entities = [entity for entity in self.entities.values()
@ -298,50 +298,50 @@ class LIFXManager:
return entities
@callback
def register(self, device):
def register(self, bulb):
"""Handle aiolifx detected bulb."""
self.hass.async_add_job(self.register_new_device(device))
self.hass.async_add_job(self.register_new_bulb(bulb))
async def register_new_device(self, device):
async def register_new_bulb(self, bulb):
"""Handle newly detected bulb."""
if device.mac_addr in self.entities:
entity = self.entities[device.mac_addr]
if bulb.mac_addr in self.entities:
entity = self.entities[bulb.mac_addr]
entity.registered = True
_LOGGER.debug("%s register AGAIN", entity.who)
await entity.update_hass()
else:
_LOGGER.debug("%s register NEW", device.ip_addr)
_LOGGER.debug("%s register NEW", bulb.ip_addr)
# Read initial state
ack = AwaitAioLIFX().wait
color_resp = await ack(device.get_color)
color_resp = await ack(bulb.get_color)
if color_resp:
version_resp = await ack(device.get_version)
version_resp = await ack(bulb.get_version)
if color_resp is None or version_resp is None:
_LOGGER.error("Failed to initialize %s", device.ip_addr)
device.registered = False
_LOGGER.error("Failed to initialize %s", bulb.ip_addr)
bulb.registered = False
else:
device.timeout = MESSAGE_TIMEOUT
device.retry_count = MESSAGE_RETRIES
device.unregister_timeout = UNAVAILABLE_GRACE
bulb.timeout = MESSAGE_TIMEOUT
bulb.retry_count = MESSAGE_RETRIES
bulb.unregister_timeout = UNAVAILABLE_GRACE
if lifx_features(device)["multizone"]:
entity = LIFXStrip(device, self.effects_conductor)
elif lifx_features(device)["color"]:
entity = LIFXColor(device, self.effects_conductor)
if lifx_features(bulb)["multizone"]:
entity = LIFXStrip(bulb, self.effects_conductor)
elif lifx_features(bulb)["color"]:
entity = LIFXColor(bulb, self.effects_conductor)
else:
entity = LIFXWhite(device, self.effects_conductor)
entity = LIFXWhite(bulb, self.effects_conductor)
_LOGGER.debug("%s register READY", entity.who)
self.entities[device.mac_addr] = entity
self.entities[bulb.mac_addr] = entity
self.async_add_entities([entity], True)
@callback
def unregister(self, device):
def unregister(self, bulb):
"""Handle aiolifx disappearing bulbs."""
if device.mac_addr in self.entities:
entity = self.entities[device.mac_addr]
if bulb.mac_addr in self.entities:
entity = self.entities[bulb.mac_addr]
_LOGGER.debug("%s unregister", entity.who)
entity.registered = False
self.hass.async_add_job(entity.async_update_ha_state())
@ -352,20 +352,17 @@ class AwaitAioLIFX:
def __init__(self):
"""Initialize the wrapper."""
self.device = None
self.message = None
self.event = asyncio.Event()
@callback
def callback(self, device, message):
def callback(self, bulb, message):
"""Handle responses."""
self.device = device
self.message = message
self.event.set()
async def wait(self, method):
"""Call an aiolifx method and wait for its response."""
self.device = None
self.message = None
self.event.clear()
method(callb=self.callback)
@ -387,9 +384,9 @@ def convert_16_to_8(value):
class LIFXLight(Light):
"""Representation of a LIFX light."""
def __init__(self, device, effects_conductor):
def __init__(self, bulb, effects_conductor):
"""Initialize the light."""
self.light = device
self.bulb = bulb
self.effects_conductor = effects_conductor
self.registered = True
self.postponed_update = None
@ -397,34 +394,34 @@ class LIFXLight(Light):
@property
def available(self):
"""Return the availability of the device."""
"""Return the availability of the bulb."""
return self.registered
@property
def unique_id(self):
"""Return a unique ID."""
return self.light.mac_addr
return self.bulb.mac_addr
@property
def name(self):
"""Return the name of the device."""
return self.light.label
"""Return the name of the bulb."""
return self.bulb.label
@property
def who(self):
"""Return a string identifying the device."""
return "%s (%s)" % (self.light.ip_addr, self.name)
"""Return a string identifying the bulb."""
return "%s (%s)" % (self.bulb.ip_addr, self.name)
@property
def min_mireds(self):
"""Return the coldest color_temp that this light supports."""
kelvin = lifx_features(self.light)['max_kelvin']
kelvin = lifx_features(self.bulb)['max_kelvin']
return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin))
@property
def max_mireds(self):
"""Return the warmest color_temp that this light supports."""
kelvin = lifx_features(self.light)['min_kelvin']
kelvin = lifx_features(self.bulb)['min_kelvin']
return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
@property
@ -432,8 +429,8 @@ class LIFXLight(Light):
"""Flag supported features."""
support = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION | SUPPORT_EFFECT
device_features = lifx_features(self.light)
if device_features['min_kelvin'] != device_features['max_kelvin']:
bulb_features = lifx_features(self.bulb)
if bulb_features['min_kelvin'] != bulb_features['max_kelvin']:
support |= SUPPORT_COLOR_TEMP
return support
@ -441,25 +438,25 @@ class LIFXLight(Light):
@property
def brightness(self):
"""Return the brightness of this light between 0..255."""
return convert_16_to_8(self.light.color[2])
return convert_16_to_8(self.bulb.color[2])
@property
def color_temp(self):
"""Return the color temperature."""
_, sat, _, kelvin = self.light.color
_, sat, _, kelvin = self.bulb.color
if sat:
return None
return color_util.color_temperature_kelvin_to_mired(kelvin)
@property
def is_on(self):
"""Return true if device is on."""
return self.light.power_level != 0
"""Return true if light is on."""
return self.bulb.power_level != 0
@property
def effect(self):
"""Return the name of the currently running effect."""
effect = self.effects_conductor.effect(self.light)
effect = self.effects_conductor.effect(self.bulb)
if effect:
return 'lifx_effect_' + effect.name
return None
@ -485,19 +482,19 @@ class LIFXLight(Light):
util.dt.utcnow() + timedelta(milliseconds=when))
async def async_turn_on(self, **kwargs):
"""Turn the device on."""
"""Turn the light on."""
kwargs[ATTR_POWER] = True
self.hass.async_add_job(self.set_state(**kwargs))
async def async_turn_off(self, **kwargs):
"""Turn the device off."""
"""Turn the light off."""
kwargs[ATTR_POWER] = False
self.hass.async_add_job(self.set_state(**kwargs))
async def set_state(self, **kwargs):
"""Set a color on the light and turn it on/off."""
async with self.lock:
bulb = self.light
bulb = self.bulb
await self.effects_conductor.stop([bulb])
@ -544,13 +541,13 @@ class LIFXLight(Light):
await self.update_during_transition(fade)
async def set_power(self, ack, pwr, duration=0):
"""Send a power change to the device."""
await ack(partial(self.light.set_power, pwr, duration=duration))
"""Send a power change to the bulb."""
await ack(partial(self.bulb.set_power, pwr, duration=duration))
async def set_color(self, ack, hsbk, kwargs, duration=0):
"""Send a color change to the device."""
hsbk = merge_hsbk(self.light.color, hsbk)
await ack(partial(self.light.set_color, hsbk, duration=duration))
"""Send a color change to the bulb."""
hsbk = merge_hsbk(self.bulb.color, hsbk)
await ack(partial(self.bulb.set_color, hsbk, duration=duration))
async def default_effect(self, **kwargs):
"""Start an effect with default parameters."""
@ -563,7 +560,7 @@ class LIFXLight(Light):
async def async_update(self):
"""Update bulb status."""
if self.available and not self.lock.locked():
await AwaitAioLIFX().wait(self.light.get_color)
await AwaitAioLIFX().wait(self.bulb.get_color)
class LIFXWhite(LIFXLight):
@ -600,7 +597,7 @@ class LIFXColor(LIFXLight):
@property
def hs_color(self):
"""Return the hs value."""
hue, sat, _, _ = self.light.color
hue, sat, _, _ = self.bulb.color
hue = hue / 65535 * 360
sat = sat / 65535 * 100
return (hue, sat) if sat else None
@ -610,8 +607,8 @@ class LIFXStrip(LIFXColor):
"""Representation of a LIFX light strip with multiple zones."""
async def set_color(self, ack, hsbk, kwargs, duration=0):
"""Send a color change to the device."""
bulb = self.light
"""Send a color change to the bulb."""
bulb = self.bulb
num_zones = len(bulb.color_zones)
zones = kwargs.get(ATTR_ZONES)
@ -659,7 +656,7 @@ class LIFXStrip(LIFXColor):
while self.available and zone < top:
# Each get_color_zones can update 8 zones at once
resp = await AwaitAioLIFX().wait(partial(
self.light.get_color_zones,
self.bulb.get_color_zones,
start_index=zone))
if resp:
zone += 8