core/homeassistant/components/light/hue.py

146 lines
4.3 KiB
Python
Raw Normal View History

""" Support for Hue lights. """
import logging
import socket
from datetime import datetime, timedelta
import homeassistant as ha
from homeassistant.components import ToggleDevice, ATTR_FRIENDLY_NAME
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
PHUE_CONFIG_FILE = "phue.conf"
def get_lights(hass, config):
""" Gets the Hue lights. """
logger = logging.getLogger(__name__)
try:
2014-11-22 22:39:40 +00:00
import phue
except ImportError:
logger.exception("Error while importing dependency phue.")
return []
host = config.get(ha.CONF_HOST, None)
try:
bridge = phue.Bridge(
host, config_file_path=hass.get_config_path(PHUE_CONFIG_FILE))
except socket.error: # Error connecting using Phue
logger.exception((
"Error while connecting to the bridge. "
"Did you follow the instructions to set it up?"))
return []
lights = {}
def update_lights(force_reload=False):
""" Updates the light states. """
now = datetime.now()
try:
time_scans = now - update_lights.last_updated
# force_reload == True, return if updated in last second
# force_reload == False, return if last update was less then
# MIN_TIME_BETWEEN_SCANS ago
if force_reload and time_scans.seconds < 1 or \
not force_reload and time_scans < MIN_TIME_BETWEEN_SCANS:
return
except AttributeError:
# First time we run last_updated is not set, continue as usual
pass
update_lights.last_updated = now
try:
api = bridge.get_api()
except socket.error:
# socket.error when we cannot reach Hue
logger.exception("Cannot reach the bridge")
return
api_states = api.get('lights')
if not isinstance(api_states, dict):
logger.error("Got unexpected result from Hue API")
return
for light_id, info in api_states.items():
if light_id not in lights:
lights[light_id] = HueLight(int(light_id), info,
bridge, update_lights)
else:
lights[light_id].info = info
update_lights()
return list(lights.values())
class HueLight(ToggleDevice):
""" Represents a Hue light """
def __init__(self, light_id, info, bridge, update_lights):
self.light_id = light_id
self.info = info
self.bridge = bridge
self.update_lights = update_lights
def get_name(self):
""" Get the mame of the Hue light. """
return self.info['name']
def turn_on(self, **kwargs):
""" Turn the specified or all lights on. """
command = {'on': True}
if kwargs.get(ATTR_TRANSITION) is not None:
# Transition time is in 1/10th seconds and cannot exceed
# 900 seconds.
command['transitiontime'] = min(9000, kwargs['transition'] * 10)
if kwargs.get(ATTR_BRIGHTNESS) is not None:
command['bri'] = kwargs['brightness']
if kwargs.get(ATTR_XY_COLOR) is not None:
command['xy'] = kwargs['xy_color']
self.bridge.set_light(self.light_id, command)
def turn_off(self, **kwargs):
""" Turn the specified or all lights off. """
command = {'on': False}
if kwargs.get('transition') is not None:
# Transition time is in 1/10th seconds and cannot exceed
# 900 seconds.
command['transitiontime'] = min(9000, kwargs['transition'] * 10)
self.bridge.set_light(self.light_id, command)
def is_on(self):
""" True if device is on. """
self.update_lights()
return self.info['state']['reachable'] and self.info['state']['on']
def get_state_attributes(self):
""" Returns optional state attributes. """
attr = {
ATTR_FRIENDLY_NAME: self.get_name()
}
if self.is_on():
attr[ATTR_BRIGHTNESS] = self.info['state']['bri']
attr[ATTR_XY_COLOR] = self.info['state']['xy']
return attr
def update(self):
""" Synchronize state with bridge. """
self.update_lights(True)