From e25503bc4a4fbc3f8f894480d197bb4f12c1dcd3 Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Tue, 27 Oct 2015 22:34:49 +0000 Subject: [PATCH 1/7] Hue device capabilities. Color temperature support for light component and hue platform --- homeassistant/components/light/__init__.py | 25 +++++++++++-- homeassistant/components/light/hue.py | 37 +++++++++++++++++--- homeassistant/components/light/services.yaml | 4 +++ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index c1b1579b4b5..051218bde24 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -43,6 +43,9 @@ Supports following parameters: A list containing three integers representing the xy color you want the light to be. + - ct_color + An INT in mireds represending the color temperature you want the light to be + - brightness Integer between 0 and 255 representing how bright you want the light to be. @@ -77,6 +80,7 @@ ATTR_TRANSITION = "transition" # lists holding color values ATTR_RGB_COLOR = "rgb_color" ATTR_XY_COLOR = "xy_color" +ATTR_CT_COLOR = "ct_color" # int with value 0 .. 255 representing brightness of the light ATTR_BRIGHTNESS = "brightness" @@ -105,6 +109,7 @@ DISCOVERY_PLATFORMS = { PROP_TO_ATTR = { 'brightness': ATTR_BRIGHTNESS, 'color_xy': ATTR_XY_COLOR, + 'color_ct': ATTR_CT_COLOR, } _LOGGER = logging.getLogger(__name__) @@ -119,8 +124,8 @@ def is_on(hass, entity_id=None): # pylint: disable=too-many-arguments def turn_on(hass, entity_id=None, transition=None, brightness=None, - rgb_color=None, xy_color=None, profile=None, flash=None, - effect=None): + rgb_color=None, xy_color=None, ct_color=None, profile=None, + flash=None, effect=None): """ Turns all or specified light on. """ data = { key: value for key, value in [ @@ -130,6 +135,7 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None, (ATTR_BRIGHTNESS, brightness), (ATTR_RGB_COLOR, rgb_color), (ATTR_XY_COLOR, xy_color), + (ATTR_CT_COLOR, ct_color), (ATTR_FLASH, flash), (ATTR_EFFECT, effect), ] if value is not None @@ -240,6 +246,16 @@ def setup(hass, config): # ValueError if value could not be converted to float pass + if ATTR_CT_COLOR in dat: + # ct_color should be an int of mirads value + ctcolor = dat.get(ATTR_CT_COLOR) + + # Without this check, a ctcolor with value '99' would work + # These values are based on Philips Hue, may need ajustment later + if isinstance(ctcolor, int): + if 154 <= ctcolor <= 500: + params[ATTR_CT_COLOR] = ctcolor + if ATTR_RGB_COLOR in dat: try: # rgb_color should be a list containing 3 ints @@ -301,6 +317,11 @@ class Light(ToggleEntity): """ XY color value [float, float]. """ return None + @property + def color_ct(self): + """ CT color value in mirads. """ + return None + @property def device_state_attributes(self): """ Returns device specific state attributes. """ diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index eff9aef4f36..88db7b990ee 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -14,9 +14,9 @@ from homeassistant.loader import get_component import homeassistant.util as util from homeassistant.const import CONF_HOST, DEVICE_DEFAULT_NAME from homeassistant.components.light import ( - Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION, - ATTR_FLASH, FLASH_LONG, FLASH_SHORT, ATTR_EFFECT, - EFFECT_COLORLOOP) + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_CT_COLOR, + ATTR_TRANSITION, ATTR_FLASH, FLASH_LONG, FLASH_SHORT, + ATTR_EFFECT, EFFECT_COLORLOOP) REQUIREMENTS = ['phue==0.8'] MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) @@ -147,6 +147,16 @@ class HueLight(Light): self.bridge = bridge self.update_lights = update_lights + # Hue can control multiple type of lights + capability_map = { + 'Dimmable light': ['bri'], + 'Dimmable plug-in unit': ['bri'], + 'Color light': ['bri', 'xy'], + 'Extended color light': ['bri', 'xy', 'ct'], + 'unknown': []} + self.capabilities = capability_map.get( + self.info['type'], 'unknown') + @property def unique_id(self): """ Returns the id of this Hue light """ @@ -161,12 +171,26 @@ class HueLight(Light): @property def brightness(self): """ Brightness of this light between 0..255. """ - return self.info['state']['bri'] + if 'bri' in self.capabilities: + return self.info['state']['bri'] + else: + return None @property def color_xy(self): """ XY color value. """ - return self.info['state'].get('xy') + if 'xy' in self.capabilities: + return self.info['state'].get('xy') + else: + return None + + @property + def color_ct(self): + """ CT color value. """ + if 'ct' in self.capabilities: + return self.info['state'].get('ct') + else: + return None @property def is_on(self): @@ -190,6 +214,9 @@ class HueLight(Light): if ATTR_XY_COLOR in kwargs: command['xy'] = kwargs[ATTR_XY_COLOR] + if ATTR_CT_COLOR in kwargs: + command['ct'] = kwargs[ATTR_CT_COLOR] + flash = kwargs.get(ATTR_FLASH) if flash == FLASH_LONG: diff --git a/homeassistant/components/light/services.yaml b/homeassistant/components/light/services.yaml index ed8b4b663ea..17e06a038af 100644 --- a/homeassistant/components/light/services.yaml +++ b/homeassistant/components/light/services.yaml @@ -20,6 +20,10 @@ turn_on: description: Color for the light in XY-format example: '[0.52, 0.43]' + ct_color: + description: Color temperature for the light in mireds (154-500) + example: '250' + brightness: description: Number between 0..255 indicating brightness example: 120 From e4d33bc6d4f5e9a0e16cdba5ac0526178275b977 Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Tue, 27 Oct 2015 22:45:35 +0000 Subject: [PATCH 2/7] Included ct_color in code coverage --- homeassistant/components/light/demo.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index 40a8cc023c5..0d72ef0dafd 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -8,7 +8,7 @@ Demo platform that implements lights. import random from homeassistant.components.light import ( - Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR) + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_CT_COLOR) LIGHT_COLORS = [ @@ -16,22 +16,25 @@ LIGHT_COLORS = [ [0.460, 0.470], ] +LIGHT_TEMPS = [160, 300, 500] + def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Find and return demo lights. """ add_devices_callback([ DemoLight("Bed Light", False), - DemoLight("Ceiling Lights", True, LIGHT_COLORS[0]), - DemoLight("Kitchen Lights", True, LIGHT_COLORS[1]) + DemoLight("Ceiling Lights", True, LIGHT_TEMPS[1], LIGHT_COLORS[0]), + DemoLight("Kitchen Lights", True, LIGHT_TEMPS[0], LIGHT_COLORS[1]) ]) class DemoLight(Light): """ Provides a demo switch. """ - def __init__(self, name, state, xy=None, brightness=180): + def __init__(self, name, state, xy=None, ct=None, brightness=180): self._name = name self._state = state self._xy = xy or random.choice(LIGHT_COLORS) + self._ct = ct or random.choice(LIGHT_TEMPS) self._brightness = brightness @property @@ -54,6 +57,11 @@ class DemoLight(Light): """ XY color value. """ return self._xy + @property + def color_ct(self): + """ CT color temperature. """ + return self._ct + @property def is_on(self): """ True if device is on. """ @@ -66,6 +74,9 @@ class DemoLight(Light): if ATTR_XY_COLOR in kwargs: self._xy = kwargs[ATTR_XY_COLOR] + if ATTR_CT_COLOR in kwargs: + self._ct = kwargs[ATTR_CT_COLOR] + if ATTR_BRIGHTNESS in kwargs: self._brightness = kwargs[ATTR_BRIGHTNESS] From 805aecd6f90b4ff0fbc1f9394e4bfe9e2ed30446 Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Tue, 27 Oct 2015 22:49:45 +0000 Subject: [PATCH 3/7] pylint & flake cleanup --- homeassistant/components/light/demo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index 0d72ef0dafd..c3c70da5418 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -30,6 +30,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class DemoLight(Light): """ Provides a demo switch. """ + # pylint: disable=too-many-arguments def __init__(self, name, state, xy=None, ct=None, brightness=180): self._name = name self._state = state From 6bad702db4a3dd80787057543d4dbee5db0298f4 Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Wed, 28 Oct 2015 23:12:16 +0000 Subject: [PATCH 4/7] Renamed to color_temp, removed capabilities (not needed afterall) --- homeassistant/components/light/__init__.py | 24 +++++++------- homeassistant/components/light/demo.py | 8 ++--- homeassistant/components/light/hue.py | 35 +++++--------------- homeassistant/components/light/services.yaml | 2 +- 4 files changed, 25 insertions(+), 44 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 051218bde24..d9ec71c460b 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -43,7 +43,7 @@ Supports following parameters: A list containing three integers representing the xy color you want the light to be. - - ct_color + - color_temp An INT in mireds represending the color temperature you want the light to be - brightness @@ -80,7 +80,7 @@ ATTR_TRANSITION = "transition" # lists holding color values ATTR_RGB_COLOR = "rgb_color" ATTR_XY_COLOR = "xy_color" -ATTR_CT_COLOR = "ct_color" +ATTR_COLOR_TEMP = "color_temp" # int with value 0 .. 255 representing brightness of the light ATTR_BRIGHTNESS = "brightness" @@ -109,7 +109,7 @@ DISCOVERY_PLATFORMS = { PROP_TO_ATTR = { 'brightness': ATTR_BRIGHTNESS, 'color_xy': ATTR_XY_COLOR, - 'color_ct': ATTR_CT_COLOR, + 'color_temp': ATTR_COLOR_TEMP, } _LOGGER = logging.getLogger(__name__) @@ -124,7 +124,7 @@ def is_on(hass, entity_id=None): # pylint: disable=too-many-arguments def turn_on(hass, entity_id=None, transition=None, brightness=None, - rgb_color=None, xy_color=None, ct_color=None, profile=None, + rgb_color=None, xy_color=None, color_temp=None, profile=None, flash=None, effect=None): """ Turns all or specified light on. """ data = { @@ -135,7 +135,7 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None, (ATTR_BRIGHTNESS, brightness), (ATTR_RGB_COLOR, rgb_color), (ATTR_XY_COLOR, xy_color), - (ATTR_CT_COLOR, ct_color), + (ATTR_COLOR_TEMP, color_temp), (ATTR_FLASH, flash), (ATTR_EFFECT, effect), ] if value is not None @@ -246,15 +246,15 @@ def setup(hass, config): # ValueError if value could not be converted to float pass - if ATTR_CT_COLOR in dat: - # ct_color should be an int of mirads value - ctcolor = dat.get(ATTR_CT_COLOR) + if ATTR_COLOR_TEMP in dat: + # color_temp should be an int of mirads value + colortemp = dat.get(ATTR_COLOR_TEMP) # Without this check, a ctcolor with value '99' would work # These values are based on Philips Hue, may need ajustment later - if isinstance(ctcolor, int): - if 154 <= ctcolor <= 500: - params[ATTR_CT_COLOR] = ctcolor + if isinstance(colortemp, int): + if 154 <= colortemp <= 500: + params[ATTR_COLOR_TEMP] = colortemp if ATTR_RGB_COLOR in dat: try: @@ -318,7 +318,7 @@ class Light(ToggleEntity): return None @property - def color_ct(self): + def color_temp(self): """ CT color value in mirads. """ return None diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index c3c70da5418..76ac07a0073 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -8,7 +8,7 @@ Demo platform that implements lights. import random from homeassistant.components.light import ( - Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_CT_COLOR) + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_COLOR_TEMP) LIGHT_COLORS = [ @@ -59,7 +59,7 @@ class DemoLight(Light): return self._xy @property - def color_ct(self): + def color_temp(self): """ CT color temperature. """ return self._ct @@ -75,8 +75,8 @@ class DemoLight(Light): if ATTR_XY_COLOR in kwargs: self._xy = kwargs[ATTR_XY_COLOR] - if ATTR_CT_COLOR in kwargs: - self._ct = kwargs[ATTR_CT_COLOR] + if ATTR_COLOR_TEMP in kwargs: + self._ct = kwargs[ATTR_COLOR_TEMP] if ATTR_BRIGHTNESS in kwargs: self._brightness = kwargs[ATTR_BRIGHTNESS] diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 88db7b990ee..dcd05b9f4c9 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -14,7 +14,7 @@ from homeassistant.loader import get_component import homeassistant.util as util from homeassistant.const import CONF_HOST, DEVICE_DEFAULT_NAME from homeassistant.components.light import ( - Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_CT_COLOR, + Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_COLOR_TEMP, ATTR_TRANSITION, ATTR_FLASH, FLASH_LONG, FLASH_SHORT, ATTR_EFFECT, EFFECT_COLORLOOP) @@ -124,7 +124,7 @@ def request_configuration(host, hass, add_devices_callback): _CONFIGURING[host], "Failed to register, please try again.") return - + # pylint: disable=unused-argument def hue_configuration_callback(data): """ Actions to do when our configuration callback is called. """ setup_bridge(host, hass, add_devices_callback) @@ -147,16 +147,6 @@ class HueLight(Light): self.bridge = bridge self.update_lights = update_lights - # Hue can control multiple type of lights - capability_map = { - 'Dimmable light': ['bri'], - 'Dimmable plug-in unit': ['bri'], - 'Color light': ['bri', 'xy'], - 'Extended color light': ['bri', 'xy', 'ct'], - 'unknown': []} - self.capabilities = capability_map.get( - self.info['type'], 'unknown') - @property def unique_id(self): """ Returns the id of this Hue light """ @@ -171,26 +161,17 @@ class HueLight(Light): @property def brightness(self): """ Brightness of this light between 0..255. """ - if 'bri' in self.capabilities: - return self.info['state']['bri'] - else: - return None + return self.info['state']['bri'] @property def color_xy(self): """ XY color value. """ - if 'xy' in self.capabilities: - return self.info['state'].get('xy') - else: - return None + return self.info['state'].get('xy') @property - def color_ct(self): + def color_temp(self): """ CT color value. """ - if 'ct' in self.capabilities: - return self.info['state'].get('ct') - else: - return None + return self.info['state'].get('ct') @property def is_on(self): @@ -214,8 +195,8 @@ class HueLight(Light): if ATTR_XY_COLOR in kwargs: command['xy'] = kwargs[ATTR_XY_COLOR] - if ATTR_CT_COLOR in kwargs: - command['ct'] = kwargs[ATTR_CT_COLOR] + if ATTR_COLOR_TEMP in kwargs: + command['ct'] = kwargs[ATTR_COLOR_TEMP] flash = kwargs.get(ATTR_FLASH) diff --git a/homeassistant/components/light/services.yaml b/homeassistant/components/light/services.yaml index 17e06a038af..8a0c5b8fded 100644 --- a/homeassistant/components/light/services.yaml +++ b/homeassistant/components/light/services.yaml @@ -20,7 +20,7 @@ turn_on: description: Color for the light in XY-format example: '[0.52, 0.43]' - ct_color: + color_temp: description: Color temperature for the light in mireds (154-500) example: '250' From f456d2ff23dde27bad930939deb7a6960763e5ce Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Wed, 28 Oct 2015 23:16:25 +0000 Subject: [PATCH 5/7] styling fix --- homeassistant/components/light/hue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index dcd05b9f4c9..cd9ad21984f 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -124,6 +124,7 @@ def request_configuration(host, hass, add_devices_callback): _CONFIGURING[host], "Failed to register, please try again.") return + # pylint: disable=unused-argument def hue_configuration_callback(data): """ Actions to do when our configuration callback is called. """ From 194c6343ac89b754dbf5e4105ab850c3480cd92d Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Fri, 30 Oct 2015 19:01:42 +0000 Subject: [PATCH 6/7] Minor corrections to light and light/demo --- homeassistant/components/light/__init__.py | 3 +-- homeassistant/components/light/demo.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index d9ec71c460b..7c8a01407ac 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -252,8 +252,7 @@ def setup(hass, config): # Without this check, a ctcolor with value '99' would work # These values are based on Philips Hue, may need ajustment later - if isinstance(colortemp, int): - if 154 <= colortemp <= 500: + if isinstance(colortemp, int) and 154 <= colortemp <= 500: params[ATTR_COLOR_TEMP] = colortemp if ATTR_RGB_COLOR in dat: diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index 76ac07a0073..d12a288ccc3 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -16,7 +16,7 @@ LIGHT_COLORS = [ [0.460, 0.470], ] -LIGHT_TEMPS = [160, 300, 500] +LIGHT_TEMPS = [160, 500] def setup_platform(hass, config, add_devices_callback, discovery_info=None): From b76471c4b3267e2ed805cf82027d36559bc2fe22 Mon Sep 17 00:00:00 2001 From: Tom Duijf Date: Fri, 30 Oct 2015 19:15:38 +0000 Subject: [PATCH 7/7] :( .. pyliny --- homeassistant/components/light/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 7c8a01407ac..3bb2b1ab239 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -253,7 +253,7 @@ def setup(hass, config): # Without this check, a ctcolor with value '99' would work # These values are based on Philips Hue, may need ajustment later if isinstance(colortemp, int) and 154 <= colortemp <= 500: - params[ATTR_COLOR_TEMP] = colortemp + params[ATTR_COLOR_TEMP] = colortemp if ATTR_RGB_COLOR in dat: try: