mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
LIFX: add lifx_set_state service call (#7552)
* Move service helpers to LifxManager * Add lifx_set_color This is a synonym for light.turn_on except it does not actually turn on the light unless asked to. Thus, turn_on can be implemented just by asking. * Rename set_color to set_state * Support power=False with lifx_set_state
This commit is contained in:
parent
416b8e0efe
commit
1ab7103aea
@ -9,6 +9,7 @@ import logging
|
|||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
|
from os import path
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import async_timeout
|
import async_timeout
|
||||||
@ -16,15 +17,18 @@ import async_timeout
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
Light, PLATFORM_SCHEMA, ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_RGB_COLOR,
|
Light, DOMAIN, PLATFORM_SCHEMA, LIGHT_TURN_ON_SCHEMA,
|
||||||
|
ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_RGB_COLOR,
|
||||||
ATTR_XY_COLOR, ATTR_COLOR_TEMP, ATTR_TRANSITION, ATTR_EFFECT,
|
ATTR_XY_COLOR, ATTR_COLOR_TEMP, ATTR_TRANSITION, ATTR_EFFECT,
|
||||||
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR,
|
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR,
|
||||||
SUPPORT_XY_COLOR, SUPPORT_TRANSITION, SUPPORT_EFFECT)
|
SUPPORT_XY_COLOR, SUPPORT_TRANSITION, SUPPORT_EFFECT)
|
||||||
|
from homeassistant.config import load_yaml_config_file
|
||||||
from homeassistant.util.color import (
|
from homeassistant.util.color import (
|
||||||
color_temperature_mired_to_kelvin, color_temperature_kelvin_to_mired)
|
color_temperature_mired_to_kelvin, color_temperature_kelvin_to_mired)
|
||||||
from homeassistant import util
|
from homeassistant import util
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||||
|
from homeassistant.helpers.service import extract_entity_ids
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
import homeassistant.util.color as color_util
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
@ -41,7 +45,10 @@ BULB_LATENCY = 500
|
|||||||
|
|
||||||
CONF_SERVER = 'server'
|
CONF_SERVER = 'server'
|
||||||
|
|
||||||
|
SERVICE_LIFX_SET_STATE = 'lifx_set_state'
|
||||||
|
|
||||||
ATTR_HSBK = 'hsbk'
|
ATTR_HSBK = 'hsbk'
|
||||||
|
ATTR_POWER = 'power'
|
||||||
|
|
||||||
BYTE_MAX = 255
|
BYTE_MAX = 255
|
||||||
SHORT_MAX = 65535
|
SHORT_MAX = 65535
|
||||||
@ -53,6 +60,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||||||
vol.Optional(CONF_SERVER, default='0.0.0.0'): cv.string,
|
vol.Optional(CONF_SERVER, default='0.0.0.0'): cv.string,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
LIFX_SET_STATE_SCHEMA = LIGHT_TURN_ON_SCHEMA.extend({
|
||||||
|
ATTR_POWER: cv.boolean,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||||
@ -87,6 +98,41 @@ class LIFXManager(object):
|
|||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.async_add_devices = async_add_devices
|
self.async_add_devices = async_add_devices
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_service_handle(service):
|
||||||
|
"""Apply a service."""
|
||||||
|
tasks = []
|
||||||
|
for light in self.service_to_entities(service):
|
||||||
|
if service.service == SERVICE_LIFX_SET_STATE:
|
||||||
|
task = light.async_set_state(**service.data)
|
||||||
|
tasks.append(hass.async_add_job(task))
|
||||||
|
if tasks:
|
||||||
|
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||||
|
|
||||||
|
descriptions = self.get_descriptions()
|
||||||
|
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, SERVICE_LIFX_SET_STATE, async_service_handle,
|
||||||
|
descriptions.get(SERVICE_LIFX_SET_STATE),
|
||||||
|
schema=LIFX_SET_STATE_SCHEMA)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_descriptions():
|
||||||
|
"""Load and return descriptions for our own service calls."""
|
||||||
|
return load_yaml_config_file(
|
||||||
|
path.join(path.dirname(__file__), 'services.yaml'))
|
||||||
|
|
||||||
|
def service_to_entities(self, service):
|
||||||
|
"""Return the known devices that a service call mentions."""
|
||||||
|
entity_ids = extract_entity_ids(self.hass, service)
|
||||||
|
if entity_ids:
|
||||||
|
entities = [entity for entity in self.entities.values()
|
||||||
|
if entity.entity_id in entity_ids]
|
||||||
|
else:
|
||||||
|
entities = list(self.entities.values())
|
||||||
|
|
||||||
|
return entities
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def register(self, device):
|
def register(self, device):
|
||||||
"""Handle for newly detected bulb."""
|
"""Handle for newly detected bulb."""
|
||||||
@ -298,6 +344,18 @@ class LIFXLight(Light):
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_turn_on(self, **kwargs):
|
def async_turn_on(self, **kwargs):
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
|
kwargs[ATTR_POWER] = True
|
||||||
|
yield from self.async_set_state(**kwargs)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_turn_off(self, **kwargs):
|
||||||
|
"""Turn the device off."""
|
||||||
|
kwargs[ATTR_POWER] = False
|
||||||
|
yield from self.async_set_state(**kwargs)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_set_state(self, **kwargs):
|
||||||
|
"""Set a color on the light and turn it on/off."""
|
||||||
yield from self.stop_effect()
|
yield from self.stop_effect()
|
||||||
|
|
||||||
if ATTR_EFFECT in kwargs:
|
if ATTR_EFFECT in kwargs:
|
||||||
@ -309,39 +367,41 @@ class LIFXLight(Light):
|
|||||||
else:
|
else:
|
||||||
fade = 0
|
fade = 0
|
||||||
|
|
||||||
|
# These are both False if ATTR_POWER is not set
|
||||||
|
power_on = kwargs.get(ATTR_POWER, False)
|
||||||
|
power_off = not kwargs.get(ATTR_POWER, True)
|
||||||
|
|
||||||
hsbk, changed_color = self.find_hsbk(**kwargs)
|
hsbk, changed_color = self.find_hsbk(**kwargs)
|
||||||
_LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
|
_LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
|
||||||
self.who, self._power, fade, *hsbk)
|
self.who, self._power, fade, *hsbk)
|
||||||
|
|
||||||
if self._power == 0:
|
if self._power == 0:
|
||||||
|
if power_off:
|
||||||
|
self.device.set_power(False, None, 0)
|
||||||
if changed_color:
|
if changed_color:
|
||||||
self.device.set_color(hsbk, None, 0)
|
self.device.set_color(hsbk, None, 0)
|
||||||
self.device.set_power(True, None, fade)
|
if power_on:
|
||||||
|
self.device.set_power(True, None, fade)
|
||||||
else:
|
else:
|
||||||
self.device.set_power(True, None, 0) # racing for power status
|
if power_on:
|
||||||
|
self.device.set_power(True, None, 0)
|
||||||
if changed_color:
|
if changed_color:
|
||||||
self.device.set_color(hsbk, None, fade)
|
self.device.set_color(hsbk, None, fade)
|
||||||
|
if power_off:
|
||||||
|
self.device.set_power(False, None, fade)
|
||||||
|
|
||||||
self.update_later(0)
|
if power_on:
|
||||||
if fade < BULB_LATENCY:
|
self.update_later(0)
|
||||||
self.set_power(1)
|
|
||||||
self.set_color(*hsbk)
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def async_turn_off(self, **kwargs):
|
|
||||||
"""Turn the device off."""
|
|
||||||
yield from self.stop_effect()
|
|
||||||
|
|
||||||
if ATTR_TRANSITION in kwargs:
|
|
||||||
fade = int(kwargs[ATTR_TRANSITION] * 1000)
|
|
||||||
else:
|
else:
|
||||||
fade = 0
|
self.update_later(fade)
|
||||||
|
|
||||||
self.device.set_power(False, None, fade)
|
if fade <= BULB_LATENCY:
|
||||||
|
if power_on:
|
||||||
self.update_later(fade)
|
self.set_power(1)
|
||||||
if fade < BULB_LATENCY:
|
if power_off:
|
||||||
self.set_power(0)
|
self.set_power(0)
|
||||||
|
if changed_color:
|
||||||
|
self.set_color(*hsbk)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_update(self):
|
def async_update(self):
|
||||||
|
@ -2,16 +2,13 @@
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import random
|
import random
|
||||||
from os import path
|
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
DOMAIN, ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_RGB_COLOR, ATTR_EFFECT,
|
DOMAIN, ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_RGB_COLOR, ATTR_EFFECT,
|
||||||
ATTR_TRANSITION)
|
ATTR_TRANSITION)
|
||||||
from homeassistant.config import load_yaml_config_file
|
|
||||||
from homeassistant.const import (ATTR_ENTITY_ID)
|
from homeassistant.const import (ATTR_ENTITY_ID)
|
||||||
from homeassistant.helpers.service import extract_entity_ids
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -73,19 +70,12 @@ def setup(hass, lifx_manager):
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_service_handle(service):
|
def async_service_handle(service):
|
||||||
"""Apply a service."""
|
"""Apply a service."""
|
||||||
entity_ids = extract_entity_ids(hass, service)
|
entities = lifx_manager.service_to_entities(service)
|
||||||
if entity_ids:
|
if entities:
|
||||||
devices = [entity for entity in lifx_manager.entities.values()
|
yield from start_effect(hass, entities,
|
||||||
if entity.entity_id in entity_ids]
|
|
||||||
else:
|
|
||||||
devices = list(lifx_manager.entities.values())
|
|
||||||
|
|
||||||
if devices:
|
|
||||||
yield from start_effect(hass, devices,
|
|
||||||
service.service, **service.data)
|
service.service, **service.data)
|
||||||
|
|
||||||
descriptions = load_yaml_config_file(
|
descriptions = lifx_manager.get_descriptions()
|
||||||
path.join(path.dirname(__file__), 'services.yaml'))
|
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_EFFECT_BREATHE, async_service_handle,
|
DOMAIN, SERVICE_EFFECT_BREATHE, async_service_handle,
|
||||||
|
@ -1,3 +1,23 @@
|
|||||||
|
lifx_set_state:
|
||||||
|
description: Set a color/brightness and possibliy turn the light on/off
|
||||||
|
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to set a state on
|
||||||
|
example: 'light.garage'
|
||||||
|
|
||||||
|
'...':
|
||||||
|
description: All turn_on parameters can be used to specify a color
|
||||||
|
|
||||||
|
transition:
|
||||||
|
description: Duration in seconds it takes to get to the final state
|
||||||
|
example: 10
|
||||||
|
|
||||||
|
power:
|
||||||
|
description: Turn the light on (True) or off (False). Leave out to keep the power as it is.
|
||||||
|
example: True
|
||||||
|
|
||||||
|
|
||||||
lifx_effect_breathe:
|
lifx_effect_breathe:
|
||||||
description: Run a breathe effect by fading to a color and back.
|
description: Run a breathe effect by fading to a color and back.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user