From 2dba07da9482d539cf562613bf6d96ff85791792 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 11 Sep 2016 19:58:21 +0200 Subject: [PATCH 01/11] Update __init__.py addedattribute "WHITE_VALUE" to improve support for RGBW devices --- homeassistant/components/light/__init__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index f1bc83dfd1762..50a1b963032d7 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -39,6 +39,7 @@ SUPPORT_RGB_COLOR = 16 SUPPORT_TRANSITION = 32 SUPPORT_XY_COLOR = 64 +SUPPORT_WHITE_VALUE = 128 # Integer that represents transition time in seconds to make change. ATTR_TRANSITION = "transition" @@ -48,6 +49,7 @@ ATTR_XY_COLOR = "xy_color" ATTR_COLOR_TEMP = "color_temp" ATTR_COLOR_NAME = "color_name" +ATTR_WHITE_VALUE = "white_value" # int with value 0 .. 255 representing brightness of the light. ATTR_BRIGHTNESS = "brightness" @@ -73,6 +75,7 @@ 'color_temp': ATTR_COLOR_TEMP, 'rgb_color': ATTR_RGB_COLOR, 'xy_color': ATTR_XY_COLOR, + 'white_value': ATTR_WHITE_VALUE, 'supported_features': ATTR_SUPPORTED_FEATURES, } @@ -93,6 +96,7 @@ ATTR_COLOR_TEMP: vol.All(int, vol.Range(min=154, max=500)), ATTR_FLASH: vol.In([FLASH_SHORT, FLASH_LONG]), ATTR_EFFECT: vol.In([EFFECT_COLORLOOP, EFFECT_RANDOM, EFFECT_WHITE]), + ATTR_WHITE_VALUE: vol.All(int, vol.Range(min=0, max=255)), }) LIGHT_TURN_OFF_SCHEMA = vol.Schema({ @@ -122,7 +126,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, color_temp=None, profile=None, - flash=None, effect=None, color_name=None): + flash=None, effect=None, color_name=None, white_value=None): """Turn all or specified light on.""" data = { key: value for key, value in [ @@ -136,6 +140,7 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None, (ATTR_FLASH, flash), (ATTR_EFFECT, effect), (ATTR_COLOR_NAME, color_name), + (ATTR_WHITE_VALUE, white_value), ] if value is not None } @@ -282,6 +287,11 @@ def rgb_color(self): def color_temp(self): """Return the CT color value in mireds.""" return None + + @property + def white_value(self): + """Return the CT color value in mireds.""" + return None @property def state_attributes(self): From 474ea953d3ae455d146a711f5d45014260456dbb Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 01:18:48 +0200 Subject: [PATCH 02/11] Update services.yaml --- homeassistant/components/light/services.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/light/services.yaml b/homeassistant/components/light/services.yaml index d6a6931652ba5..afcc54d717fea 100644 --- a/homeassistant/components/light/services.yaml +++ b/homeassistant/components/light/services.yaml @@ -28,6 +28,10 @@ turn_on: description: Color temperature for the light in mireds (154-500) example: '250' + white_value: + description: Number between 0..255 indicating level of white + example: '250' + brightness: description: Number between 0..255 indicating brightness example: 120 From 61f0180c3deb0afca6e606882d1362d1beec3a70 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 01:19:36 +0200 Subject: [PATCH 03/11] Update __init__.py --- homeassistant/components/light/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 50a1b963032d7..4d643bd61f5e6 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -94,9 +94,9 @@ ATTR_XY_COLOR: vol.All(vol.ExactSequence((cv.small_float, cv.small_float)), vol.Coerce(tuple)), ATTR_COLOR_TEMP: vol.All(int, vol.Range(min=154, max=500)), + ATTR_WHITE_VALUE: vol.All(int, vol.Range(min=0, max=255)), ATTR_FLASH: vol.In([FLASH_SHORT, FLASH_LONG]), ATTR_EFFECT: vol.In([EFFECT_COLORLOOP, EFFECT_RANDOM, EFFECT_WHITE]), - ATTR_WHITE_VALUE: vol.All(int, vol.Range(min=0, max=255)), }) LIGHT_TURN_OFF_SCHEMA = vol.Schema({ @@ -125,8 +125,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, color_temp=None, profile=None, - flash=None, effect=None, color_name=None, white_value=None): + rgb_color=None, xy_color=None, color_temp=None, white_value=None, profile=None, + flash=None, effect=None, color_name=None): """Turn all or specified light on.""" data = { key: value for key, value in [ @@ -137,10 +137,10 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None, (ATTR_RGB_COLOR, rgb_color), (ATTR_XY_COLOR, xy_color), (ATTR_COLOR_TEMP, color_temp), + (ATTR_WHITE_VALUE, white_value), (ATTR_FLASH, flash), (ATTR_EFFECT, effect), (ATTR_COLOR_NAME, color_name), - (ATTR_WHITE_VALUE, white_value), ] if value is not None } @@ -287,7 +287,7 @@ def rgb_color(self): def color_temp(self): """Return the CT color value in mireds.""" return None - + @property def white_value(self): """Return the CT color value in mireds.""" From 8ec314ac45a1ea9e5a7fb5fc62eb456f1c2a49b6 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 10:28:25 +0200 Subject: [PATCH 04/11] Update __init__.py --- homeassistant/components/frontend/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index ab967fb114fbe..4536d7e201d28 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -45,9 +45,9 @@ def register_built_in_panel(hass, component_name, sidebar_title=None, else: url = None # use default url generate mechanism - register_panel(hass, component_name, os.path.join(STATIC_PATH, path), - FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, - url, config) + # register_panel(hass, component_name, os.path.join(STATIC_PATH, path), + # FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, + # url, config) def register_panel(hass, component_name, path, md5=None, sidebar_title=None, From efd00e0718a4c0458a68472e9eb9613611916384 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 10:46:31 +0200 Subject: [PATCH 05/11] Update __init__.py --- homeassistant/components/frontend/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 4536d7e201d28..8246e322965f0 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -45,9 +45,9 @@ def register_built_in_panel(hass, component_name, sidebar_title=None, else: url = None # use default url generate mechanism - # register_panel(hass, component_name, os.path.join(STATIC_PATH, path), - # FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, - # url, config) + register_panel(hass, component_name, os.path.join(STATIC_PATH, path), + FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, + url, config) def register_panel(hass, component_name, path, md5=None, sidebar_title=None, From c57a87ac0b3599fb1f457b4014ef727cec244295 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 10:51:58 +0200 Subject: [PATCH 06/11] Update __init__.py --- homeassistant/components/frontend/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 8246e322965f0..0f6ac0f16ec0e 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -45,9 +45,9 @@ def register_built_in_panel(hass, component_name, sidebar_title=None, else: url = None # use default url generate mechanism - register_panel(hass, component_name, os.path.join(STATIC_PATH, path), - FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, - url, config) + register_panel(hass, component_name, os.path.join(STATIC_PATH, path), + FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, + url, config) def register_panel(hass, component_name, path, md5=None, sidebar_title=None, From e48e45c8d3e985a830f5836c4a4e6656271f3488 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 10:52:38 +0200 Subject: [PATCH 07/11] Update __init__.py --- homeassistant/components/frontend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 0f6ac0f16ec0e..ab967fb114fbe 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -45,7 +45,7 @@ def register_built_in_panel(hass, component_name, sidebar_title=None, else: url = None # use default url generate mechanism - register_panel(hass, component_name, os.path.join(STATIC_PATH, path), + register_panel(hass, component_name, os.path.join(STATIC_PATH, path), FINGERPRINTS[path], sidebar_title, sidebar_icon, url_path, url, config) From 12b9bd89f632b24f1e86e55fe7d95375291bd8cd Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 11:21:48 +0200 Subject: [PATCH 08/11] Update __init__.py shortened line --- homeassistant/components/light/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 4d643bd61f5e6..3b784380028f3 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -125,8 +125,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, color_temp=None, white_value=None, profile=None, - flash=None, effect=None, color_name=None): + rgb_color=None, xy_color=None, color_temp=None, white_value=None, + profile=None, flash=None, effect=None, color_name=None): """Turn all or specified light on.""" data = { key: value for key, value in [ From b198d84493d5763c0be3f21fad5cfd6b254b4893 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 11:36:04 +0200 Subject: [PATCH 09/11] Update __init__.py --- 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 3b784380028f3..ce8832792b628 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -125,7 +125,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, color_temp=None, white_value=None, + rgb_color=None, xy_color=None, color_temp=None, white_value=None, profile=None, flash=None, effect=None, color_name=None): """Turn all or specified light on.""" data = { From 18ddcbc384beb77f4a2469853d2b6225828c6632 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Mon, 12 Sep 2016 12:46:21 +0200 Subject: [PATCH 10/11] Update __init__.py --- 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 ce8832792b628..85f611a679b59 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -290,7 +290,7 @@ def color_temp(self): @property def white_value(self): - """Return the CT color value in mireds.""" + """Return the white value of this light between 0..255.""" return None @property From 50accb0e16eac6ddd397401bffe434170d65749e Mon Sep 17 00:00:00 2001 From: MartinHjelmare Date: Mon, 19 Sep 2016 04:16:46 +0200 Subject: [PATCH 11/11] Add mysensors RGBW and light tests * Activate support for mysensors RGBW devices with support for white_value attribute. * Add white_value support in light demo platform. * Add tests for white_value and more for light component. * Add tests for light demo platform. * Fix import order in check_config. --- homeassistant/components/light/demo.py | 32 ++++++++++-- homeassistant/components/light/mysensors.py | 52 ++++++++++++------- homeassistant/scripts/check_config.py | 15 +++--- tests/components/light/test_demo.py | 57 +++++++++++++++++++++ tests/components/light/test_init.py | 48 +++++++++++------ 5 files changed, 157 insertions(+), 47 deletions(-) create mode 100644 tests/components/light/test_demo.py diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index 4eb0a61d9835d..ac8e017cb7df9 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -7,8 +7,9 @@ import random from homeassistant.components.light import ( - ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS, - SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light) + ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, ATTR_WHITE_VALUE, + ATTR_XY_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, + SUPPORT_WHITE_VALUE, Light) LIGHT_COLORS = [ [237, 224, 33], @@ -17,7 +18,8 @@ LIGHT_TEMPS = [240, 380] -SUPPORT_DEMO = SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_RGB_COLOR +SUPPORT_DEMO = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_RGB_COLOR | + SUPPORT_WHITE_VALUE) def setup_platform(hass, config, add_devices_callback, discovery_info=None): @@ -33,13 +35,17 @@ class DemoLight(Light): """Represenation of a demo light.""" # pylint: disable=too-many-arguments - def __init__(self, name, state, rgb=None, ct=None, brightness=180): + def __init__( + self, name, state, rgb=None, ct=None, brightness=180, + xy_color=(.5, .5), white=200): """Initialize the light.""" self._name = name self._state = state - self._rgb = rgb or random.choice(LIGHT_COLORS) + self._rgb = rgb self._ct = ct or random.choice(LIGHT_TEMPS) self._brightness = brightness + self._xy_color = xy_color + self._white = white @property def should_poll(self): @@ -56,6 +62,11 @@ def brightness(self): """Return the brightness of this light between 0..255.""" return self._brightness + @property + def xy_color(self): + """Return the XY color value [float, float].""" + return self._xy_color + @property def rgb_color(self): """Return the RBG color value.""" @@ -66,6 +77,11 @@ def color_temp(self): """Return the CT color temperature.""" return self._ct + @property + def white_value(self): + """Return the white value of this light between 0..255.""" + return self._white + @property def is_on(self): """Return true if light is on.""" @@ -89,6 +105,12 @@ def turn_on(self, **kwargs): if ATTR_BRIGHTNESS in kwargs: self._brightness = kwargs[ATTR_BRIGHTNESS] + if ATTR_XY_COLOR in kwargs: + self._xy_color = kwargs[ATTR_XY_COLOR] + + if ATTR_WHITE_VALUE in kwargs: + self._white = kwargs[ATTR_WHITE_VALUE] + self.update_ha_state() def turn_off(self, **kwargs): diff --git a/homeassistant/components/light/mysensors.py b/homeassistant/components/light/mysensors.py index c33793127a2b6..6f8e984b79943 100644 --- a/homeassistant/components/light/mysensors.py +++ b/homeassistant/components/light/mysensors.py @@ -9,17 +9,19 @@ from homeassistant.components import mysensors from homeassistant.components.light import (ATTR_BRIGHTNESS, ATTR_RGB_COLOR, + ATTR_WHITE_VALUE, SUPPORT_BRIGHTNESS, - SUPPORT_RGB_COLOR, Light) + SUPPORT_RGB_COLOR, + SUPPORT_WHITE_VALUE, Light) from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.util.color import rgb_hex_to_rgb_list _LOGGER = logging.getLogger(__name__) -ATTR_RGB_WHITE = 'rgb_white' ATTR_VALUE = 'value' ATTR_VALUE_TYPE = 'value_type' -SUPPORT_MYSENSORS = SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR +SUPPORT_MYSENSORS = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR | + SUPPORT_WHITE_VALUE) def setup_platform(hass, config, add_devices, discovery_info=None): @@ -41,13 +43,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): pres.S_DIMMER: MySensorsLightDimmer, } if float(gateway.protocol_version) >= 1.5: - # Add V_RGBW when rgb_white is implemented in the frontend map_sv_types.update({ pres.S_RGB_LIGHT: [set_req.V_RGB], + pres.S_RGBW_LIGHT: [set_req.V_RGBW], }) map_sv_types[pres.S_DIMMER].append(set_req.V_PERCENTAGE) device_class_map.update({ pres.S_RGB_LIGHT: MySensorsLightRGB, + pres.S_RGBW_LIGHT: MySensorsLightRGBW, }) devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( @@ -76,8 +79,8 @@ def rgb_color(self): return self._rgb @property - def rgb_white(self): # not implemented in the frontend yet - """Return the white value in RGBW, value between 0..255.""" + def white_value(self): + """Return the white value of this light between 0..255.""" return self._white @property @@ -99,13 +102,15 @@ def _turn_on_light(self): """Turn on light child device.""" set_req = self.gateway.const.SetReq - if not self._state and set_req.V_LIGHT in self._values: - self.gateway.set_child_value( - self.node_id, self.child_id, set_req.V_LIGHT, 1) + if self._state or set_req.V_LIGHT not in self._values: + return + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_LIGHT, 1) if self.gateway.optimistic: # optimistically assume that light has changed state self._state = True + self._values[set_req.V_LIGHT] = STATE_ON self.update_ha_state() def _turn_on_dimmer(self, **kwargs): @@ -113,30 +118,34 @@ def _turn_on_dimmer(self, **kwargs): set_req = self.gateway.const.SetReq brightness = self._brightness - if ATTR_BRIGHTNESS in kwargs and \ - kwargs[ATTR_BRIGHTNESS] != self._brightness: - brightness = kwargs[ATTR_BRIGHTNESS] - percent = round(100 * brightness / 255) - self.gateway.set_child_value( - self.node_id, self.child_id, set_req.V_DIMMER, percent) + if ATTR_BRIGHTNESS not in kwargs or \ + kwargs[ATTR_BRIGHTNESS] == self._brightness or \ + set_req.V_DIMMER not in self._values: + return + brightness = kwargs[ATTR_BRIGHTNESS] + percent = round(100 * brightness / 255) + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_DIMMER, percent) if self.gateway.optimistic: # optimistically assume that light has changed state self._brightness = brightness + self._values[set_req.V_DIMMER] = percent self.update_ha_state() def _turn_on_rgb_and_w(self, hex_template, **kwargs): """Turn on RGB or RGBW child device.""" rgb = self._rgb white = self._white + hex_color = self._values.get(self.value_type) - if ATTR_RGB_WHITE in kwargs and \ - kwargs[ATTR_RGB_WHITE] != self._white: - white = kwargs[ATTR_RGB_WHITE] + if ATTR_WHITE_VALUE in kwargs and \ + kwargs[ATTR_WHITE_VALUE] != self._white: + white = kwargs[ATTR_WHITE_VALUE] if ATTR_RGB_COLOR in kwargs and \ kwargs[ATTR_RGB_COLOR] != self._rgb: - rgb = kwargs[ATTR_RGB_COLOR] + rgb = list(kwargs[ATTR_RGB_COLOR]) if white is not None and hex_template == '%02x%02x%02x%02x': rgb.append(white) hex_color = hex_template % tuple(rgb) @@ -147,6 +156,8 @@ def _turn_on_rgb_and_w(self, hex_template, **kwargs): # optimistically assume that light has changed state self._rgb = rgb self._white = white + if hex_color: + self._values[self.value_type] = hex_color self.update_ha_state() def _turn_off_light(self, value_type=None, value=None): @@ -179,6 +190,7 @@ def _turn_off_rgb_or_w(self, value_type=None, value=None): def _turn_off_main(self, value_type=None, value=None): """Turn the device off.""" + set_req = self.gateway.const.SetReq if value_type is None or value is None: _LOGGER.warning( '%s: value_type %s, value = %s, ' @@ -190,6 +202,8 @@ def _turn_off_main(self, value_type=None, value=None): if self.gateway.optimistic: # optimistically assume that light has changed state self._state = False + self._values[value_type] = ( + STATE_OFF if set_req.V_LIGHT in self._values else value) self.update_ha_state() def _update_light(self): diff --git a/homeassistant/scripts/check_config.py b/homeassistant/scripts/check_config.py index d1bf12187e894..ce2ffe8b47273 100644 --- a/homeassistant/scripts/check_config.py +++ b/homeassistant/scripts/check_config.py @@ -1,17 +1,18 @@ """Script to ensure a configuration file exists.""" import argparse +import logging import os from glob import glob -import logging -from typing import List, Dict, Sequence -from unittest.mock import patch from platform import system +from unittest.mock import patch + +from typing import Dict, List, Sequence -from homeassistant.exceptions import HomeAssistantError import homeassistant.bootstrap as bootstrap import homeassistant.config as config_util import homeassistant.loader as loader import homeassistant.util.yaml as yaml +from homeassistant.exceptions import HomeAssistantError REQUIREMENTS = ('colorlog>2.1,<3',) if system() == 'Windows': # Ensure colorama installed for colorlog on Windows @@ -96,7 +97,7 @@ def run(script_args: List) -> int: if args.files: print(color(C_HEAD, 'yaml files'), '(used /', - color('red', 'not used')+')') + color('red', 'not used') + ')') # Python 3.5 gets a recursive, but not in 3.4 for yfn in sorted(glob(os.path.join(config_dir, '*.yaml')) + glob(os.path.join(config_dir, '*/*.yaml'))): @@ -250,12 +251,12 @@ def line_src(this): indent_str = indent_count * ' ' if listi or isinstance(layer, list): - indent_str = indent_str[:-1]+'-' + indent_str = indent_str[:-1] + '-' if isinstance(layer, Dict): for key, value in layer.items(): if isinstance(value, dict) or isinstance(value, list): print(indent_str, key + ':', line_src(value)) - dump_dict(value, indent_count+2) + dump_dict(value, indent_count + 2) else: print(indent_str, key + ':', value) indent_str = indent_count * ' ' diff --git a/tests/components/light/test_demo.py b/tests/components/light/test_demo.py new file mode 100644 index 0000000000000..72fb80500e4d9 --- /dev/null +++ b/tests/components/light/test_demo.py @@ -0,0 +1,57 @@ +"""The tests for the demo light component.""" +# pylint: disable=too-many-public-methods,protected-access +import unittest + +import homeassistant.components.light as light + +from tests.common import get_test_home_assistant + +ENTITY_LIGHT = 'light.bed_light' + + +class TestDemoClimate(unittest.TestCase): + """Test the demo climate hvac.""" + + def setUp(self): # pylint: disable=invalid-name + """Setup things to be run when tests are started.""" + self.hass = get_test_home_assistant() + self.assertTrue(light.setup(self.hass, {'light': { + 'platform': 'demo', + }})) + + def tearDown(self): # pylint: disable=invalid-name + """Stop down everything that was started.""" + self.hass.stop() + + def test_state_attributes(self): + """Test light state attributes.""" + light.turn_on( + self.hass, ENTITY_LIGHT, xy_color=(.4, .6), brightness=25) + self.hass.pool.block_till_done() + state = self.hass.states.get(ENTITY_LIGHT) + self.assertTrue(light.is_on(self.hass, ENTITY_LIGHT)) + self.assertEqual((.4, .6), state.attributes.get(light.ATTR_XY_COLOR)) + self.assertEqual(25, state.attributes.get(light.ATTR_BRIGHTNESS)) + self.assertEqual( + (82, 91, 0), state.attributes.get(light.ATTR_RGB_COLOR)) + light.turn_on( + self.hass, ENTITY_LIGHT, rgb_color=(251, 252, 253), + white_value=254) + self.hass.pool.block_till_done() + state = self.hass.states.get(ENTITY_LIGHT) + self.assertEqual(254, state.attributes.get(light.ATTR_WHITE_VALUE)) + self.assertEqual( + (251, 252, 253), state.attributes.get(light.ATTR_RGB_COLOR)) + light.turn_on(self.hass, ENTITY_LIGHT, color_temp=400) + self.hass.pool.block_till_done() + state = self.hass.states.get(ENTITY_LIGHT) + self.assertEqual(400, state.attributes.get(light.ATTR_COLOR_TEMP)) + + def test_turn_off(self): + """Test light turn off method.""" + light.turn_on(self.hass, ENTITY_LIGHT) + self.hass.pool.block_till_done() + self.assertTrue(light.is_on(self.hass, ENTITY_LIGHT)) + light.turn_off(self.hass, ENTITY_LIGHT) + self.hass.pool.block_till_done() + self.assertFalse(light.is_on(self.hass, ENTITY_LIGHT)) diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index 1f6619c8b120a..5625312bed312 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -54,7 +54,9 @@ def test_methods(self): brightness='brightness_val', rgb_color='rgb_color_val', xy_color='xy_color_val', - profile='profile_val') + profile='profile_val', + color_name='color_name_val', + white_value='white_val') self.hass.pool.block_till_done() @@ -71,6 +73,9 @@ def test_methods(self): self.assertEqual('rgb_color_val', call.data.get(light.ATTR_RGB_COLOR)) self.assertEqual('xy_color_val', call.data.get(light.ATTR_XY_COLOR)) self.assertEqual('profile_val', call.data.get(light.ATTR_PROFILE)) + self.assertEqual( + 'color_name_val', call.data.get(light.ATTR_COLOR_NAME)) + self.assertEqual('white_val', call.data.get(light.ATTR_WHITE_VALUE)) # Test turn_off turn_off_calls = mock_service( @@ -168,23 +173,28 @@ def test_services(self): # Ensure all attributes process correctly light.turn_on(self.hass, dev1.entity_id, - transition=10, brightness=20) + transition=10, brightness=20, color_name='blue') light.turn_on( - self.hass, dev2.entity_id, rgb_color=(255, 255, 255)) + self.hass, dev2.entity_id, rgb_color=(255, 255, 255), + white_value=255) light.turn_on(self.hass, dev3.entity_id, xy_color=(.4, .6)) self.hass.pool.block_till_done() - method, data = dev1.last_call('turn_on') + _, data = dev1.last_call('turn_on') self.assertEqual( {light.ATTR_TRANSITION: 10, - light.ATTR_BRIGHTNESS: 20}, + light.ATTR_BRIGHTNESS: 20, + light.ATTR_RGB_COLOR: (0, 0, 255)}, data) - method, data = dev2.last_call('turn_on') - self.assertEquals(data[light.ATTR_RGB_COLOR], (255, 255, 255)) + _, data = dev2.last_call('turn_on') + self.assertEqual( + {light.ATTR_RGB_COLOR: (255, 255, 255), + light.ATTR_WHITE_VALUE: 255}, + data) - method, data = dev3.last_call('turn_on') + _, data = dev3.last_call('turn_on') self.assertEqual({light.ATTR_XY_COLOR: (.4, .6)}, data) # One of the light profiles @@ -199,13 +209,13 @@ def test_services(self): self.hass.pool.block_till_done() - method, data = dev1.last_call('turn_on') + _, data = dev1.last_call('turn_on') self.assertEqual( {light.ATTR_BRIGHTNESS: prof_bri, light.ATTR_XY_COLOR: (prof_x, prof_y)}, data) - method, data = dev2.last_call('turn_on') + _, data = dev2.last_call('turn_on') self.assertEqual( {light.ATTR_BRIGHTNESS: 100, light.ATTR_XY_COLOR: (.4, .6)}, @@ -219,23 +229,29 @@ def test_services(self): self.hass.pool.block_till_done() - method, data = dev1.last_call('turn_on') + _, data = dev1.last_call('turn_on') self.assertEqual({}, data) - method, data = dev2.last_call('turn_on') + _, data = dev2.last_call('turn_on') self.assertEqual({}, data) - method, data = dev3.last_call('turn_on') + _, data = dev3.last_call('turn_on') self.assertEqual({}, data) # faulty attributes will not trigger a service call light.turn_on( self.hass, dev1.entity_id, profile=prof_name, brightness='bright', rgb_color='yellowish') + light.turn_on( + self.hass, dev2.entity_id, + white_value='high') self.hass.pool.block_till_done() - method, data = dev1.last_call('turn_on') + _, data = dev1.last_call('turn_on') + self.assertEqual({}, data) + + _, data = dev2.last_call('turn_on') self.assertEqual({}, data) def test_broken_light_profiles(self): @@ -269,13 +285,13 @@ def test_light_profiles(self): self.hass, {light.DOMAIN: {CONF_PLATFORM: 'test'}} )) - dev1, dev2, dev3 = platform.DEVICES + dev1, _, _ = platform.DEVICES light.turn_on(self.hass, dev1.entity_id, profile='test') self.hass.pool.block_till_done() - method, data = dev1.last_call('turn_on') + _, data = dev1.last_call('turn_on') self.assertEqual( {light.ATTR_XY_COLOR: (.4, .6), light.ATTR_BRIGHTNESS: 100},