From d3320963c370dc0aff0c4cf76ed4afaccfb3d61c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 13 Jun 2015 16:42:09 -0700 Subject: [PATCH] Refactor basic light structure --- homeassistant/components/light/__init__.py | 47 ++++++++++++++++++- homeassistant/components/light/demo.py | 40 ++++++++-------- homeassistant/components/light/hue.py | 25 +++++----- .../components/light/limitlessled.py | 38 +++++---------- homeassistant/components/light/tellstick.py | 39 +++++++-------- 5 files changed, 104 insertions(+), 85 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index ca887b97a19..51a3c61dbd5 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -53,6 +53,7 @@ import os import csv from homeassistant.helpers.entity_component import EntityComponent +from homeassistant.helpers.entity import ToggleEntity import homeassistant.util as util from homeassistant.const import ( @@ -96,6 +97,11 @@ DISCOVERY_PLATFORMS = { discovery.services.PHILIPS_HUE: 'hue', } +PROP_TO_ATTR = { + 'brightness': ATTR_BRIGHTNESS, + 'color_xy': ATTR_XY_COLOR, +} + _LOGGER = logging.getLogger(__name__) @@ -251,7 +257,8 @@ def setup(hass, config): light.turn_on(**params) for light in target_lights: - light.update_ha_state(True) + if light.should_poll: + light.update_ha_state(True) # Listen for light on and light off service calls hass.services.register(DOMAIN, SERVICE_TURN_ON, @@ -261,3 +268,41 @@ def setup(hass, config): handle_light_service) return True + + +class Light(ToggleEntity): + """ Represents a light within Home Assistant. """ + # pylint: disable=no-self-use + + @property + def brightness(self): + """ Brightness of this light between 0..255. """ + return None + + @property + def color_xy(self): + """ XY color value [float, float]. """ + return None + + @property + def device_state_attributes(self): + """ Returns device specific state attributes. """ + return None + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + data = {} + + if self.is_on: + for prop, attr in PROP_TO_ATTR.items(): + value = getattr(self, prop) + if value: + data[attr] = value + + device_attr = self.device_state_attributes + + if device_attr is not None: + data.update(device_attr) + + return data diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index 3949c765023..5c6b1ae6165 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -7,9 +7,8 @@ Demo platform that implements lights. """ import random -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME -from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_XY_COLOR +from homeassistant.components.light import ( + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR) LIGHT_COLORS = [ @@ -22,16 +21,16 @@ LIGHT_COLORS = [ def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Find and return demo lights. """ add_devices_callback([ - DemoLight("Bed Light", STATE_OFF), - DemoLight("Ceiling", STATE_ON), - DemoLight("Kitchen", STATE_ON) + DemoLight("Bed Light", False), + DemoLight("Ceiling", True), + DemoLight("Kitchen", True) ]) -class DemoLight(ToggleEntity): +class DemoLight(Light): """ Provides a demo switch. """ def __init__(self, name, state, xy=None, brightness=180): - self._name = name or DEVICE_DEFAULT_NAME + self._name = name self._state = state self._xy = xy or random.choice(LIGHT_COLORS) self._brightness = brightness @@ -47,27 +46,23 @@ class DemoLight(ToggleEntity): return self._name @property - def state(self): - """ Returns the name of the device if any. """ - return self._state + def brightness(self): + """ Brightness of this light between 0..255. """ + return self._brightness @property - def state_attributes(self): - """ Returns optional state attributes. """ - if self.is_on: - return { - ATTR_BRIGHTNESS: self._brightness, - ATTR_XY_COLOR: self._xy, - } + def color_xy(self): + """ XY color value. """ + return self._xy @property def is_on(self): """ True if device is on. """ - return self._state == STATE_ON + return self._state def turn_on(self, **kwargs): """ Turn the device on. """ - self._state = STATE_ON + self._state = True if ATTR_XY_COLOR in kwargs: self._xy = kwargs[ATTR_XY_COLOR] @@ -75,6 +70,9 @@ class DemoLight(ToggleEntity): if ATTR_BRIGHTNESS in kwargs: self._brightness = kwargs[ATTR_BRIGHTNESS] + self.update_ha_state() + def turn_off(self, **kwargs): """ Turn the device off. """ - self._state = STATE_OFF + self._state = False + self.update_ha_state() diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 683d8a1a4c9..65a288f82d5 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -6,10 +6,9 @@ from urllib.parse import urlparse from homeassistant.loader import get_component import homeassistant.util as util -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.const import CONF_HOST +from homeassistant.const import CONF_HOST, DEVICE_DEFAULT_NAME from homeassistant.components.light import ( - ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION, + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION, ATTR_FLASH, FLASH_LONG, FLASH_SHORT) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) @@ -131,7 +130,7 @@ def request_configuration(host, hass, add_devices_callback): ) -class HueLight(ToggleEntity): +class HueLight(Light): """ Represents a Hue light """ def __init__(self, light_id, info, bridge, update_lights): @@ -149,19 +148,17 @@ class HueLight(ToggleEntity): @property def name(self): """ Get the mame of the Hue light. """ - return self.info.get('name', 'No name') + return self.info.get('name', DEVICE_DEFAULT_NAME) @property - def state_attributes(self): - """ Returns optional state attributes. """ - attr = {} + def brightness(self): + """ Brightness of this light between 0..255. """ + return self.info['state']['bri'] - if self.is_on: - attr[ATTR_BRIGHTNESS] = self.info['state']['bri'] - if 'xy' in self.info['state']: - attr[ATTR_XY_COLOR] = self.info['state']['xy'] - - return attr + @property + def color_xy(self): + """ XY color value. """ + return self.info['state'].get('xy') @property def is_on(self): diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index deb98e2428e..649f642e077 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -23,9 +23,8 @@ light: """ import logging -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME -from homeassistant.components.light import ATTR_BRIGHTNESS +from homeassistant.const import DEVICE_DEFAULT_NAME +from homeassistant.components.light import Light, ATTR_BRIGHTNESS _LOGGER = logging.getLogger(__name__) @@ -43,18 +42,12 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): lights = [] for i in range(1, 5): if 'group_%d_name' % (i) in config: - lights.append( - LimitlessLED( - led, - i, - config['group_%d_name' % (i)] - ) - ) + lights.append(LimitlessLED(led, i, config['group_%d_name' % (i)])) add_devices_callback(lights) -class LimitlessLED(ToggleEntity): +class LimitlessLED(Light): """ Represents a LimitlessLED light """ def __init__(self, led, group, name): @@ -65,7 +58,7 @@ class LimitlessLED(ToggleEntity): self.led.off(self.group) self._name = name or DEVICE_DEFAULT_NAME - self._state = STATE_OFF + self._state = False self._brightness = 100 @property @@ -79,33 +72,26 @@ class LimitlessLED(ToggleEntity): return self._name @property - def state(self): - """ Returns the name of the device if any. """ - return self._state - - @property - def state_attributes(self): - """ Returns optional state attributes. """ - if self.is_on: - return { - ATTR_BRIGHTNESS: self._brightness, - } + def brightness(self): + return self._brightness @property def is_on(self): """ True if device is on. """ - return self._state == STATE_ON + return self._state def turn_on(self, **kwargs): """ Turn the device on. """ - self._state = STATE_ON + self._state = True if ATTR_BRIGHTNESS in kwargs: self._brightness = kwargs[ATTR_BRIGHTNESS] self.led.set_brightness(self._brightness, self.group) + self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ - self._state = STATE_OFF + self._state = False self.led.off(self.group) + self.update_ha_state() diff --git a/homeassistant/components/light/tellstick.py b/homeassistant/components/light/tellstick.py index 6d28c196326..d3c35ae0640 100644 --- a/homeassistant/components/light/tellstick.py +++ b/homeassistant/components/light/tellstick.py @@ -1,9 +1,8 @@ """ Support for Tellstick lights. """ import logging # pylint: disable=no-name-in-module, import-error -from homeassistant.components.light import ATTR_BRIGHTNESS +from homeassistant.components.light import Light, ATTR_BRIGHTNESS from homeassistant.const import ATTR_FRIENDLY_NAME -from homeassistant.helpers.entity import ToggleEntity import tellcore.constants as tellcore_constants @@ -27,7 +26,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): add_devices_callback(lights) -class TellstickLight(ToggleEntity): +class TellstickLight(Light): """ Represents a tellstick light """ last_sent_command_mask = (tellcore_constants.TELLSTICK_TURNON | tellcore_constants.TELLSTICK_TURNOFF | @@ -38,7 +37,7 @@ class TellstickLight(ToggleEntity): def __init__(self, tellstick): self.tellstick = tellstick self.state_attr = {ATTR_FRIENDLY_NAME: tellstick.name} - self.brightness = 0 + self._brightness = 0 @property def name(self): @@ -48,34 +47,28 @@ class TellstickLight(ToggleEntity): @property def is_on(self): """ True if switch is on. """ - return self.brightness > 0 + return self._brightness > 0 + + @property + def brightness(self): + """ Brightness of this light between 0..255. """ + return self._brightness def turn_off(self, **kwargs): """ Turns the switch off. """ self.tellstick.turn_off() - self.brightness = 0 + self._brightness = 0 def turn_on(self, **kwargs): """ Turns the switch on. """ brightness = kwargs.get(ATTR_BRIGHTNESS) if brightness is None: - self.brightness = 255 + self._brightness = 255 else: - self.brightness = brightness + self._brightness = brightness - self.tellstick.dim(self.brightness) - - @property - def state_attributes(self): - """ Returns optional state attributes. """ - attr = { - ATTR_FRIENDLY_NAME: self.name - } - - attr[ATTR_BRIGHTNESS] = int(self.brightness) - - return attr + self.tellstick.dim(self._brightness) def update(self): """ Update state of the light. """ @@ -83,12 +76,12 @@ class TellstickLight(ToggleEntity): self.last_sent_command_mask) if last_command == tellcore_constants.TELLSTICK_TURNON: - self.brightness = 255 + self._brightness = 255 elif last_command == tellcore_constants.TELLSTICK_TURNOFF: - self.brightness = 0 + self._brightness = 0 elif (last_command == tellcore_constants.TELLSTICK_DIM or last_command == tellcore_constants.TELLSTICK_UP or last_command == tellcore_constants.TELLSTICK_DOWN): last_sent_value = self.tellstick.last_sent_value() if last_sent_value is not None: - self.brightness = last_sent_value + self._brightness = last_sent_value