Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 81 additions & 21 deletions homeassistant/components/light/lifx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@
import asyncio
import sys
import math
from os import path
from functools import partial
from datetime import timedelta
import async_timeout

import voluptuous as vol

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,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR,
SUPPORT_XY_COLOR, SUPPORT_TRANSITION, SUPPORT_EFFECT)
from homeassistant.config import load_yaml_config_file
from homeassistant.util.color import (
color_temperature_mired_to_kelvin, color_temperature_kelvin_to_mired)
from homeassistant import util
from homeassistant.core import callback
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.util.color as color_util

Expand All @@ -41,7 +45,10 @@

CONF_SERVER = 'server'

SERVICE_LIFX_SET_STATE = 'lifx_set_state'

ATTR_HSBK = 'hsbk'
ATTR_POWER = 'power'

BYTE_MAX = 255
SHORT_MAX = 65535
Expand All @@ -53,6 +60,10 @@
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
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
Expand Down Expand Up @@ -87,6 +98,41 @@ def __init__(self, hass, async_add_devices):
self.hass = hass
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
def register(self, device):
"""Handle for newly detected bulb."""
Expand Down Expand Up @@ -298,6 +344,18 @@ def update_later(self, when):
@asyncio.coroutine
def async_turn_on(self, **kwargs):
"""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()

if ATTR_EFFECT in kwargs:
Expand All @@ -309,39 +367,41 @@ def async_turn_on(self, **kwargs):
else:
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)
_LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
self.who, self._power, fade, *hsbk)

if self._power == 0:
if power_off:
self.device.set_power(False, None, 0)
if changed_color:
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:
self.device.set_power(True, None, 0) # racing for power status
if power_on:
self.device.set_power(True, None, 0)
if changed_color:
self.device.set_color(hsbk, None, fade)
if power_off:
self.device.set_power(False, None, fade)

self.update_later(0)
if fade < BULB_LATENCY:
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)
if power_on:
self.update_later(0)
else:
fade = 0

self.device.set_power(False, None, fade)
self.update_later(fade)

self.update_later(fade)
if fade < BULB_LATENCY:
self.set_power(0)
if fade <= BULB_LATENCY:
if power_on:
self.set_power(1)
if power_off:
self.set_power(0)
if changed_color:
self.set_color(*hsbk)

@asyncio.coroutine
def async_update(self):
Expand Down
18 changes: 4 additions & 14 deletions homeassistant/components/light/lifx/effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
import logging
import asyncio
import random
from os import path

import voluptuous as vol

from homeassistant.components.light import (
DOMAIN, ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_RGB_COLOR, ATTR_EFFECT,
ATTR_TRANSITION)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_ENTITY_ID)
from homeassistant.helpers.service import extract_entity_ids
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -73,19 +70,12 @@ def setup(hass, lifx_manager):
@asyncio.coroutine
def async_service_handle(service):
"""Apply a service."""
entity_ids = extract_entity_ids(hass, service)
if entity_ids:
devices = [entity for entity in lifx_manager.entities.values()
if entity.entity_id in entity_ids]
else:
devices = list(lifx_manager.entities.values())

if devices:
yield from start_effect(hass, devices,
entities = lifx_manager.service_to_entities(service)
if entities:
yield from start_effect(hass, entities,
service.service, **service.data)

descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
descriptions = lifx_manager.get_descriptions()

hass.services.async_register(
DOMAIN, SERVICE_EFFECT_BREATHE, async_service_handle,
Expand Down
20 changes: 20 additions & 0 deletions homeassistant/components/light/lifx/services.yaml
Original file line number Diff line number Diff line change
@@ -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:
description: Run a breathe effect by fading to a color and back.

Expand Down