From 6d24a65313f0c8413c71feeca79f2f0ff79d2b60 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 13 Apr 2020 15:33:04 +0200 Subject: [PATCH] Various light test improvements (#34131) --- homeassistant/components/demo/light.py | 13 +- homeassistant/components/light/__init__.py | 10 +- homeassistant/helpers/entity.py | 10 +- tests/components/demo/test_light.py | 111 ++-- .../device_sun_light_trigger/test_init.py | 46 +- tests/components/flux/test_switch.py | 12 +- tests/components/group/test_light.py | 475 +++++++++++------- 7 files changed, 418 insertions(+), 259 deletions(-) diff --git a/homeassistant/components/demo/light.py b/homeassistant/components/demo/light.py index ac7e53826b9..e6747fee2df 100644 --- a/homeassistant/components/demo/light.py +++ b/homeassistant/components/demo/light.py @@ -84,10 +84,7 @@ class DemoLight(Light): self._effect_list = effect_list self._effect = effect self._available = True - if ct is not None and hs_color is None: - self._color_mode = "ct" - else: - self._color_mode = "hs" + self._color_mode = "ct" if ct is not None and hs_color is None else "hs" @property def device_info(self): @@ -166,7 +163,7 @@ class DemoLight(Light): """Flag supported features.""" return SUPPORT_DEMO - def turn_on(self, **kwargs) -> None: + async def async_turn_on(self, **kwargs) -> None: """Turn the light on.""" self._state = True @@ -189,12 +186,12 @@ class DemoLight(Light): # As we have disabled polling, we need to inform # Home Assistant about updates in our state ourselves. - self.schedule_update_ha_state() + self.async_write_ha_state() - def turn_off(self, **kwargs) -> None: + async def async_turn_off(self, **kwargs) -> None: """Turn the light off.""" self._state = False # As we have disabled polling, we need to inform # Home Assistant about updates in our state ourselves. - self.schedule_update_ha_state() + self.async_write_ha_state() diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index e86de00b59f..4a960a6c884 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -191,11 +191,11 @@ async def async_setup(hass, config): def preprocess_data(data): """Preprocess the service data.""" - base = {} - - for entity_field in cv.ENTITY_SERVICE_FIELDS: - if entity_field in data: - base[entity_field] = data.pop(entity_field) + base = { + entity_field: data.pop(entity_field) + for entity_field in cv.ENTITY_SERVICE_FIELDS + if entity_field in data + } preprocess_turn_on_alternatives(data) turn_lights_off, off_params = preprocess_turn_off(data) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 62d46500451..7a3e1e8d52a 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -319,11 +319,7 @@ class Entity(ABC): else: state = self.state - if state is None: - state = STATE_UNKNOWN - else: - state = str(state) - + state = STATE_UNKNOWN if state is None else str(state) attr.update(self.state_attributes or {}) attr.update(self.device_state_attributes or {}) @@ -622,7 +618,7 @@ class ToggleEntity(Entity): async def async_turn_on(self, **kwargs): """Turn the entity on.""" - await self.hass.async_add_job(ft.partial(self.turn_on, **kwargs)) + await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs)) def turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" @@ -630,7 +626,7 @@ class ToggleEntity(Entity): async def async_turn_off(self, **kwargs): """Turn the entity off.""" - await self.hass.async_add_job(ft.partial(self.turn_off, **kwargs)) + await self.hass.async_add_executor_job(ft.partial(self.turn_off, **kwargs)) def toggle(self, **kwargs: Any) -> None: """Toggle the entity.""" diff --git a/tests/components/demo/test_light.py b/tests/components/demo/test_light.py index 5d0fee65aea..f48bc28c772 100644 --- a/tests/components/demo/test_light.py +++ b/tests/components/demo/test_light.py @@ -1,11 +1,25 @@ """The tests for the demo light component.""" import pytest -from homeassistant.components import light +from homeassistant.components.demo import DOMAIN +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, + ATTR_BRIGHTNESS_PCT, + ATTR_COLOR_TEMP, + ATTR_EFFECT, + ATTR_KELVIN, + ATTR_MAX_MIREDS, + ATTR_MIN_MIREDS, + ATTR_RGB_COLOR, + ATTR_WHITE_VALUE, + ATTR_XY_COLOR, + DOMAIN as LIGHT_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON from homeassistant.setup import async_setup_component -from tests.components.light import common - ENTITY_LIGHT = "light.bed_light" @@ -13,63 +27,96 @@ ENTITY_LIGHT = "light.bed_light" def setup_comp(hass): """Set up demo component.""" hass.loop.run_until_complete( - async_setup_component(hass, light.DOMAIN, {"light": {"platform": "demo"}}) + async_setup_component(hass, LIGHT_DOMAIN, {LIGHT_DOMAIN: {"platform": DOMAIN}}) ) async def test_state_attributes(hass): """Test light state attributes.""" - await common.async_turn_on(hass, ENTITY_LIGHT, xy_color=(0.4, 0.4), brightness=25) - state = hass.states.get(ENTITY_LIGHT) - assert light.is_on(hass, ENTITY_LIGHT) - assert (0.4, 0.4) == state.attributes.get(light.ATTR_XY_COLOR) - assert state.attributes.get(light.ATTR_BRIGHTNESS) == 25 - assert state.attributes.get(light.ATTR_RGB_COLOR) == (255, 234, 164) - assert state.attributes.get(light.ATTR_EFFECT) == "rainbow" - await common.async_turn_on( - hass, ENTITY_LIGHT, rgb_color=(251, 253, 255), white_value=254 + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_XY_COLOR: (0.4, 0.4), ATTR_BRIGHTNESS: 25}, + blocking=True, ) + state = hass.states.get(ENTITY_LIGHT) - assert state.attributes.get(light.ATTR_WHITE_VALUE) == 254 - assert state.attributes.get(light.ATTR_RGB_COLOR) == (250, 252, 255) - assert state.attributes.get(light.ATTR_XY_COLOR) == (0.319, 0.326) - await common.async_turn_on(hass, ENTITY_LIGHT, color_temp=400, effect="none") + assert state.state == STATE_ON + assert state.attributes.get(ATTR_XY_COLOR) == (0.4, 0.4) + assert state.attributes.get(ATTR_BRIGHTNESS) == 25 + assert state.attributes.get(ATTR_RGB_COLOR) == (255, 234, 164) + assert state.attributes.get(ATTR_EFFECT) == "rainbow" + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: ENTITY_LIGHT, + ATTR_RGB_COLOR: (251, 253, 255), + ATTR_WHITE_VALUE: 254, + }, + blocking=True, + ) + state = hass.states.get(ENTITY_LIGHT) - assert state.attributes.get(light.ATTR_COLOR_TEMP) == 400 - assert state.attributes.get(light.ATTR_MIN_MIREDS) == 153 - assert state.attributes.get(light.ATTR_MAX_MIREDS) == 500 - assert state.attributes.get(light.ATTR_EFFECT) == "none" - await common.async_turn_on(hass, ENTITY_LIGHT, kelvin=3000, brightness_pct=50) + assert state.attributes.get(ATTR_WHITE_VALUE) == 254 + assert state.attributes.get(ATTR_RGB_COLOR) == (250, 252, 255) + assert state.attributes.get(ATTR_XY_COLOR) == (0.319, 0.326) + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_EFFECT: "none", ATTR_COLOR_TEMP: 400}, + blocking=True, + ) + state = hass.states.get(ENTITY_LIGHT) - assert state.attributes.get(light.ATTR_COLOR_TEMP) == 333 - assert state.attributes.get(light.ATTR_BRIGHTNESS) == 127 + assert state.attributes.get(ATTR_COLOR_TEMP) == 400 + assert state.attributes.get(ATTR_MIN_MIREDS) == 153 + assert state.attributes.get(ATTR_MAX_MIREDS) == 500 + assert state.attributes.get(ATTR_EFFECT) == "none" + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_BRIGHTNESS_PCT: 50, ATTR_KELVIN: 3000}, + blocking=True, + ) + + state = hass.states.get(ENTITY_LIGHT) + assert state.attributes.get(ATTR_COLOR_TEMP) == 333 + assert state.attributes.get(ATTR_BRIGHTNESS) == 127 async def test_turn_off(hass): """Test light turn off method.""" await hass.services.async_call( - "light", "turn_on", {"entity_id": ENTITY_LIGHT}, blocking=True + LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_LIGHT}, blocking=True ) - assert light.is_on(hass, ENTITY_LIGHT) + state = hass.states.get(ENTITY_LIGHT) + assert state.state == STATE_ON await hass.services.async_call( - "light", "turn_off", {"entity_id": ENTITY_LIGHT}, blocking=True + LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_LIGHT}, blocking=True ) - assert not light.is_on(hass, ENTITY_LIGHT) + state = hass.states.get(ENTITY_LIGHT) + assert state.state == STATE_OFF async def test_turn_off_without_entity_id(hass): """Test light turn off all lights.""" await hass.services.async_call( - "light", "turn_on", {"entity_id": "all"}, blocking=True + LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "all"}, blocking=True ) - assert light.is_on(hass, ENTITY_LIGHT) + state = hass.states.get(ENTITY_LIGHT) + assert state.state == STATE_ON await hass.services.async_call( - "light", "turn_off", {"entity_id": "all"}, blocking=True + LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "all"}, blocking=True ) - assert not light.is_on(hass, ENTITY_LIGHT) + state = hass.states.get(ENTITY_LIGHT) + assert state.state == STATE_OFF diff --git a/tests/components/device_sun_light_trigger/test_init.py b/tests/components/device_sun_light_trigger/test_init.py index 9cc794380f9..1b51d93ae6c 100644 --- a/tests/components/device_sun_light_trigger/test_init.py +++ b/tests/components/device_sun_light_trigger/test_init.py @@ -12,12 +12,18 @@ from homeassistant.components import ( light, ) from homeassistant.components.device_tracker.const import DOMAIN -from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME +from homeassistant.const import ( + ATTR_ENTITY_ID, + CONF_PLATFORM, + STATE_HOME, + STATE_NOT_HOME, + STATE_OFF, + STATE_ON, +) from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util from tests.common import async_fire_time_changed -from tests.components.light import common as common_light @pytest.fixture @@ -74,7 +80,12 @@ async def test_lights_on_when_sun_sets(hass, scanner): hass, device_sun_light_trigger.DOMAIN, {device_sun_light_trigger.DOMAIN: {}} ) - await common_light.async_turn_off(hass) + await hass.services.async_call( + light.DOMAIN, + light.SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "test.light"}, + blocking=True, + ) test_time = test_time.replace(hour=3) with patch("homeassistant.util.dt.utcnow", return_value=test_time): @@ -82,7 +93,8 @@ async def test_lights_on_when_sun_sets(hass, scanner): await hass.async_block_till_done() assert all( - light.is_on(hass, ent_id) for ent_id in hass.states.async_entity_ids("light") + hass.states.get(ent_id).state == STATE_ON + for ent_id in hass.states.async_entity_ids("light") ) @@ -91,7 +103,12 @@ async def test_lights_turn_off_when_everyone_leaves(hass): assert await async_setup_component( hass, "light", {light.DOMAIN: {CONF_PLATFORM: "test"}} ) - await common_light.async_turn_on(hass) + await hass.services.async_call( + light.DOMAIN, + light.SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "test.light"}, + blocking=True, + ) hass.states.async_set("device_tracker.bla", STATE_HOME) assert await async_setup_component( @@ -103,7 +120,7 @@ async def test_lights_turn_off_when_everyone_leaves(hass): await hass.async_block_till_done() assert all( - not light.is_on(hass, ent_id) + hass.states.get(ent_id).state == STATE_OFF for ent_id in hass.states.async_entity_ids("light") ) @@ -112,7 +129,9 @@ async def test_lights_turn_on_when_coming_home_after_sun_set(hass, scanner): """Test lights turn on when coming home after sun set.""" test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC) with patch("homeassistant.util.dt.utcnow", return_value=test_time): - await common_light.async_turn_off(hass) + await hass.services.async_call( + light.DOMAIN, light.SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "all"}, blocking=True + ) assert await async_setup_component( hass, device_sun_light_trigger.DOMAIN, {device_sun_light_trigger.DOMAIN: {}} @@ -123,7 +142,8 @@ async def test_lights_turn_on_when_coming_home_after_sun_set(hass, scanner): await hass.async_block_till_done() assert all( - light.is_on(hass, ent_id) for ent_id in hass.states.async_entity_ids("light") + hass.states.get(ent_id).state == light.STATE_ON + for ent_id in hass.states.async_entity_ids("light") ) @@ -134,7 +154,9 @@ async def test_lights_turn_on_when_coming_home_after_sun_set_person(hass, scanne test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC) with patch("homeassistant.util.dt.utcnow", return_value=test_time): - await common_light.async_turn_off(hass) + await hass.services.async_call( + light.DOMAIN, light.SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "all"}, blocking=True + ) hass.states.async_set(device_1, STATE_NOT_HOME) hass.states.async_set(device_2, STATE_NOT_HOME) await hass.async_block_till_done() @@ -161,7 +183,7 @@ async def test_lights_turn_on_when_coming_home_after_sun_set_person(hass, scanne ) assert all( - not light.is_on(hass, ent_id) + hass.states.get(ent_id).state == STATE_OFF for ent_id in hass.states.async_entity_ids("light") ) assert hass.states.get(device_1).state == "not_home" @@ -173,7 +195,7 @@ async def test_lights_turn_on_when_coming_home_after_sun_set_person(hass, scanne await hass.async_block_till_done() assert all( - not light.is_on(hass, ent_id) + hass.states.get(ent_id).state == STATE_OFF for ent_id in hass.states.async_entity_ids("light") ) assert hass.states.get(device_1).state == "not_home" @@ -186,7 +208,7 @@ async def test_lights_turn_on_when_coming_home_after_sun_set_person(hass, scanne await hass.async_block_till_done() assert all( - light.is_on(hass, ent_id) + hass.states.get(ent_id).state == light.STATE_ON for ent_id in hass.states.async_entity_ids("light") ) assert hass.states.get(device_1).state == "home" diff --git a/tests/components/flux/test_switch.py b/tests/components/flux/test_switch.py index 13824dff9c3..c0befe8e69c 100644 --- a/tests/components/flux/test_switch.py +++ b/tests/components/flux/test_switch.py @@ -4,6 +4,7 @@ import pytest from homeassistant.components import light, switch from homeassistant.const import ( + ATTR_ENTITY_ID, CONF_PLATFORM, SERVICE_TURN_ON, STATE_ON, @@ -19,7 +20,6 @@ from tests.common import ( async_mock_service, mock_restore_cache, ) -from tests.components.light import common as common_light from tests.components.switch import common @@ -897,9 +897,13 @@ async def test_flux_with_multiple_lights(hass): ) ent1, ent2, ent3 = platform.ENTITIES - common_light.turn_on(hass, entity_id=ent2.entity_id) - await hass.async_block_till_done() - common_light.turn_on(hass, entity_id=ent3.entity_id) + + await hass.services.async_call( + light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ent2.entity_id}, blocking=True + ) + await hass.services.async_call( + light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ent3.entity_id}, blocking=True + ) await hass.async_block_till_done() state = hass.states.get(ent1.entity_id) diff --git a/tests/components/group/test_light.py b/tests/components/group/test_light.py index 1f1466981b6..94d78d62877 100644 --- a/tests/components/group/test_light.py +++ b/tests/components/group/test_light.py @@ -3,199 +3,248 @@ from unittest.mock import MagicMock import asynctest +from homeassistant.components.group import DOMAIN import homeassistant.components.group.light as group +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, + ATTR_COLOR_TEMP, + ATTR_EFFECT, + ATTR_EFFECT_LIST, + ATTR_FLASH, + ATTR_HS_COLOR, + ATTR_MAX_MIREDS, + ATTR_MIN_MIREDS, + ATTR_RGB_COLOR, + ATTR_TRANSITION, + ATTR_WHITE_VALUE, + ATTR_XY_COLOR, + DOMAIN as LIGHT_DOMAIN, + SERVICE_TOGGLE, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ( + ATTR_ENTITY_ID, + ATTR_SUPPORTED_FEATURES, + STATE_OFF, + STATE_ON, + STATE_UNAVAILABLE, +) from homeassistant.setup import async_setup_component -from tests.components.light import common - async def test_default_state(hass): """Test light group default state.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": [], "name": "Bedroom Group"}}, + LIGHT_DOMAIN, + {LIGHT_DOMAIN: {"platform": DOMAIN, "entities": [], "name": "Bedroom Group"}}, ) await hass.async_block_till_done() state = hass.states.get("light.bedroom_group") assert state is not None - assert state.state == "unavailable" - assert state.attributes["supported_features"] == 0 - assert state.attributes.get("brightness") is None - assert state.attributes.get("hs_color") is None - assert state.attributes.get("color_temp") is None - assert state.attributes.get("white_value") is None - assert state.attributes.get("effect_list") is None - assert state.attributes.get("effect") is None + assert state.state == STATE_UNAVAILABLE + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0 + assert state.attributes.get(ATTR_BRIGHTNESS) is None + assert state.attributes.get(ATTR_HS_COLOR) is None + assert state.attributes.get(ATTR_COLOR_TEMP) is None + assert state.attributes.get(ATTR_WHITE_VALUE) is None + assert state.attributes.get(ATTR_EFFECT_LIST) is None + assert state.attributes.get(ATTR_EFFECT) is None async def test_state_reporting(hass): """Test the state reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) - hass.states.async_set("light.test1", "on") - hass.states.async_set("light.test2", "unavailable") + hass.states.async_set("light.test1", STATE_ON) + hass.states.async_set("light.test2", STATE_UNAVAILABLE) await hass.async_block_till_done() - assert hass.states.get("light.light_group").state == "on" + assert hass.states.get("light.light_group").state == STATE_ON - hass.states.async_set("light.test1", "on") - hass.states.async_set("light.test2", "off") + hass.states.async_set("light.test1", STATE_ON) + hass.states.async_set("light.test2", STATE_OFF) await hass.async_block_till_done() - assert hass.states.get("light.light_group").state == "on" + assert hass.states.get("light.light_group").state == STATE_ON - hass.states.async_set("light.test1", "off") - hass.states.async_set("light.test2", "off") + hass.states.async_set("light.test1", STATE_OFF) + hass.states.async_set("light.test2", STATE_OFF) await hass.async_block_till_done() - assert hass.states.get("light.light_group").state == "off" + assert hass.states.get("light.light_group").state == STATE_OFF - hass.states.async_set("light.test1", "unavailable") - hass.states.async_set("light.test2", "unavailable") + hass.states.async_set("light.test1", STATE_UNAVAILABLE) + hass.states.async_set("light.test2", STATE_UNAVAILABLE) await hass.async_block_till_done() - assert hass.states.get("light.light_group").state == "unavailable" + assert hass.states.get("light.light_group").state == STATE_UNAVAILABLE async def test_brightness(hass): """Test brightness reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) hass.states.async_set( - "light.test1", "on", {"brightness": 255, "supported_features": 1} + "light.test1", STATE_ON, {ATTR_BRIGHTNESS: 255, ATTR_SUPPORTED_FEATURES: 1} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.state == "on" - assert state.attributes["supported_features"] == 1 - assert state.attributes["brightness"] == 255 + assert state.state == STATE_ON + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 1 + assert state.attributes[ATTR_BRIGHTNESS] == 255 hass.states.async_set( - "light.test2", "on", {"brightness": 100, "supported_features": 1} + "light.test2", STATE_ON, {ATTR_BRIGHTNESS: 100, ATTR_SUPPORTED_FEATURES: 1} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.state == "on" - assert state.attributes["brightness"] == 177 + assert state.state == STATE_ON + assert state.attributes[ATTR_BRIGHTNESS] == 177 hass.states.async_set( - "light.test1", "off", {"brightness": 255, "supported_features": 1} + "light.test1", STATE_OFF, {ATTR_BRIGHTNESS: 255, ATTR_SUPPORTED_FEATURES: 1} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.state == "on" - assert state.attributes["supported_features"] == 1 - assert state.attributes["brightness"] == 100 + assert state.state == STATE_ON + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 1 + assert state.attributes[ATTR_BRIGHTNESS] == 100 async def test_color(hass): """Test RGB reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) hass.states.async_set( - "light.test1", "on", {"hs_color": (0, 100), "supported_features": 16} + "light.test1", STATE_ON, {ATTR_HS_COLOR: (0, 100), ATTR_SUPPORTED_FEATURES: 16} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.state == "on" - assert state.attributes["supported_features"] == 16 - assert state.attributes["hs_color"] == (0, 100) + assert state.state == STATE_ON + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 16 + assert state.attributes[ATTR_HS_COLOR] == (0, 100) hass.states.async_set( - "light.test2", "on", {"hs_color": (0, 50), "supported_features": 16} + "light.test2", STATE_ON, {ATTR_HS_COLOR: (0, 50), ATTR_SUPPORTED_FEATURES: 16} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["hs_color"] == (0, 75) + assert state.attributes[ATTR_HS_COLOR] == (0, 75) hass.states.async_set( - "light.test1", "off", {"hs_color": (0, 0), "supported_features": 16} + "light.test1", STATE_OFF, {ATTR_HS_COLOR: (0, 0), ATTR_SUPPORTED_FEATURES: 16} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["hs_color"] == (0, 50) + assert state.attributes[ATTR_HS_COLOR] == (0, 50) async def test_white_value(hass): """Test white value reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) hass.states.async_set( - "light.test1", "on", {"white_value": 255, "supported_features": 128} + "light.test1", STATE_ON, {ATTR_WHITE_VALUE: 255, ATTR_SUPPORTED_FEATURES: 128} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["white_value"] == 255 + assert state.attributes[ATTR_WHITE_VALUE] == 255 hass.states.async_set( - "light.test2", "on", {"white_value": 100, "supported_features": 128} + "light.test2", STATE_ON, {ATTR_WHITE_VALUE: 100, ATTR_SUPPORTED_FEATURES: 128} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["white_value"] == 177 + assert state.attributes[ATTR_WHITE_VALUE] == 177 hass.states.async_set( - "light.test1", "off", {"white_value": 255, "supported_features": 128} + "light.test1", STATE_OFF, {ATTR_WHITE_VALUE: 255, ATTR_SUPPORTED_FEATURES: 128} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["white_value"] == 100 + assert state.attributes[ATTR_WHITE_VALUE] == 100 async def test_color_temp(hass): """Test color temp reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) hass.states.async_set( - "light.test1", "on", {"color_temp": 2, "supported_features": 2} + "light.test1", STATE_ON, {"color_temp": 2, ATTR_SUPPORTED_FEATURES: 2} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["color_temp"] == 2 + assert state.attributes[ATTR_COLOR_TEMP] == 2 hass.states.async_set( - "light.test2", "on", {"color_temp": 1000, "supported_features": 2} + "light.test2", STATE_ON, {"color_temp": 1000, ATTR_SUPPORTED_FEATURES: 2} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["color_temp"] == 501 + assert state.attributes[ATTR_COLOR_TEMP] == 501 hass.states.async_set( - "light.test1", "off", {"color_temp": 2, "supported_features": 2} + "light.test1", STATE_OFF, {"color_temp": 2, ATTR_SUPPORTED_FEATURES: 2} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["color_temp"] == 1000 + assert state.attributes[ATTR_COLOR_TEMP] == 1000 async def test_emulated_color_temp_group(hass): """Test emulated color temperature in a group.""" await async_setup_component( hass, - "light", + LIGHT_DOMAIN, { - "light": [ + LIGHT_DOMAIN: [ {"platform": "demo"}, { - "platform": "group", + "platform": DOMAIN, "entities": [ "light.bed_light", "light.ceiling_lights", @@ -207,97 +256,111 @@ async def test_emulated_color_temp_group(hass): ) await hass.async_block_till_done() - hass.states.async_set("light.bed_light", "on", {"supported_features": 2}) - await hass.async_block_till_done() - hass.states.async_set("light.ceiling_lights", "on", {"supported_features": 63}) - await hass.async_block_till_done() - hass.states.async_set("light.kitchen_lights", "on", {"supported_features": 61}) + hass.states.async_set("light.bed_light", STATE_ON, {ATTR_SUPPORTED_FEATURES: 2}) + hass.states.async_set( + "light.ceiling_lights", STATE_ON, {ATTR_SUPPORTED_FEATURES: 63} + ) + hass.states.async_set( + "light.kitchen_lights", STATE_ON, {ATTR_SUPPORTED_FEATURES: 61} + ) await hass.async_block_till_done() await hass.services.async_call( - "light", - "turn_on", - {"entity_id": "light.light_group", "color_temp": 200}, + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "light.light_group", ATTR_COLOR_TEMP: 200}, blocking=True, ) await hass.async_block_till_done() state = hass.states.get("light.bed_light") - assert state.state == "on" - assert state.attributes["color_temp"] == 200 - assert "hs_color" not in state.attributes.keys() + assert state.state == STATE_ON + assert state.attributes[ATTR_COLOR_TEMP] == 200 + assert ATTR_HS_COLOR not in state.attributes.keys() state = hass.states.get("light.ceiling_lights") - assert state.state == "on" - assert state.attributes["color_temp"] == 200 - assert "hs_color" not in state.attributes.keys() + assert state.state == STATE_ON + assert state.attributes[ATTR_COLOR_TEMP] == 200 + assert ATTR_HS_COLOR not in state.attributes.keys() state = hass.states.get("light.kitchen_lights") - assert state.state == "on" - assert state.attributes["hs_color"] == (27.001, 19.243) + assert state.state == STATE_ON + assert state.attributes[ATTR_HS_COLOR] == (27.001, 19.243) async def test_min_max_mireds(hass): """Test min/max mireds reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) - hass.states.async_set( - "light.test1", "on", {"min_mireds": 2, "max_mireds": 5, "supported_features": 2} - ) - await hass.async_block_till_done() - state = hass.states.get("light.light_group") - assert state.attributes["min_mireds"] == 2 - assert state.attributes["max_mireds"] == 5 - - hass.states.async_set( - "light.test2", - "on", - {"min_mireds": 7, "max_mireds": 1234567890, "supported_features": 2}, - ) - await hass.async_block_till_done() - state = hass.states.get("light.light_group") - assert state.attributes["min_mireds"] == 2 - assert state.attributes["max_mireds"] == 1234567890 - hass.states.async_set( "light.test1", - "off", - {"min_mireds": 1, "max_mireds": 2, "supported_features": 2}, + STATE_ON, + {ATTR_MIN_MIREDS: 2, ATTR_MAX_MIREDS: 5, ATTR_SUPPORTED_FEATURES: 2}, ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["min_mireds"] == 1 - assert state.attributes["max_mireds"] == 1234567890 + assert state.attributes[ATTR_MIN_MIREDS] == 2 + assert state.attributes[ATTR_MAX_MIREDS] == 5 + + hass.states.async_set( + "light.test2", + STATE_ON, + {ATTR_MIN_MIREDS: 7, ATTR_MAX_MIREDS: 1234567890, ATTR_SUPPORTED_FEATURES: 2}, + ) + await hass.async_block_till_done() + state = hass.states.get("light.light_group") + assert state.attributes[ATTR_MIN_MIREDS] == 2 + assert state.attributes[ATTR_MAX_MIREDS] == 1234567890 + + hass.states.async_set( + "light.test1", + STATE_OFF, + {ATTR_MIN_MIREDS: 1, ATTR_MAX_MIREDS: 2, ATTR_SUPPORTED_FEATURES: 2}, + ) + await hass.async_block_till_done() + state = hass.states.get("light.light_group") + assert state.attributes[ATTR_MIN_MIREDS] == 1 + assert state.attributes[ATTR_MAX_MIREDS] == 1234567890 async def test_effect_list(hass): """Test effect_list reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) hass.states.async_set( "light.test1", - "on", - {"effect_list": ["None", "Random", "Colorloop"], "supported_features": 4}, + STATE_ON, + {ATTR_EFFECT_LIST: ["None", "Random", "Colorloop"], ATTR_SUPPORTED_FEATURES: 4}, ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert set(state.attributes["effect_list"]) == {"None", "Random", "Colorloop"} + assert set(state.attributes[ATTR_EFFECT_LIST]) == {"None", "Random", "Colorloop"} hass.states.async_set( "light.test2", - "on", - {"effect_list": ["None", "Random", "Rainbow"], "supported_features": 4}, + STATE_ON, + {ATTR_EFFECT_LIST: ["None", "Random", "Rainbow"], ATTR_SUPPORTED_FEATURES: 4}, ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert set(state.attributes["effect_list"]) == { + assert set(state.attributes[ATTR_EFFECT_LIST]) == { "None", "Random", "Colorloop", @@ -306,12 +369,12 @@ async def test_effect_list(hass): hass.states.async_set( "light.test1", - "off", - {"effect_list": ["None", "Colorloop", "Seven"], "supported_features": 4}, + STATE_OFF, + {ATTR_EFFECT_LIST: ["None", "Colorloop", "Seven"], ATTR_SUPPORTED_FEATURES: 4}, ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert set(state.attributes["effect_list"]) == { + assert set(state.attributes[ATTR_EFFECT_LIST]) == { "None", "Random", "Colorloop", @@ -324,86 +387,91 @@ async def test_effect(hass): """Test effect reporting.""" await async_setup_component( hass, - "light", + LIGHT_DOMAIN, { - "light": { - "platform": "group", + LIGHT_DOMAIN: { + "platform": DOMAIN, "entities": ["light.test1", "light.test2", "light.test3"], } }, ) hass.states.async_set( - "light.test1", "on", {"effect": "None", "supported_features": 6} + "light.test1", STATE_ON, {ATTR_EFFECT: "None", ATTR_SUPPORTED_FEATURES: 6} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["effect"] == "None" + assert state.attributes[ATTR_EFFECT] == "None" hass.states.async_set( - "light.test2", "on", {"effect": "None", "supported_features": 6} + "light.test2", STATE_ON, {ATTR_EFFECT: "None", ATTR_SUPPORTED_FEATURES: 6} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["effect"] == "None" + assert state.attributes[ATTR_EFFECT] == "None" hass.states.async_set( - "light.test3", "on", {"effect": "Random", "supported_features": 6} + "light.test3", STATE_ON, {ATTR_EFFECT: "Random", ATTR_SUPPORTED_FEATURES: 6} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["effect"] == "None" + assert state.attributes[ATTR_EFFECT] == "None" hass.states.async_set( - "light.test1", "off", {"effect": "None", "supported_features": 6} + "light.test1", STATE_OFF, {ATTR_EFFECT: "None", ATTR_SUPPORTED_FEATURES: 6} ) hass.states.async_set( - "light.test2", "off", {"effect": "None", "supported_features": 6} + "light.test2", STATE_OFF, {ATTR_EFFECT: "None", ATTR_SUPPORTED_FEATURES: 6} ) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["effect"] == "Random" + assert state.attributes[ATTR_EFFECT] == "Random" async def test_supported_features(hass): """Test supported features reporting.""" await async_setup_component( hass, - "light", - {"light": {"platform": "group", "entities": ["light.test1", "light.test2"]}}, + LIGHT_DOMAIN, + { + LIGHT_DOMAIN: { + "platform": DOMAIN, + "entities": ["light.test1", "light.test2"], + } + }, ) - hass.states.async_set("light.test1", "on", {"supported_features": 0}) + hass.states.async_set("light.test1", STATE_ON, {ATTR_SUPPORTED_FEATURES: 0}) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["supported_features"] == 0 + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0 - hass.states.async_set("light.test2", "on", {"supported_features": 2}) + hass.states.async_set("light.test2", STATE_ON, {ATTR_SUPPORTED_FEATURES: 2}) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["supported_features"] == 2 + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 2 - hass.states.async_set("light.test1", "off", {"supported_features": 41}) + hass.states.async_set("light.test1", STATE_OFF, {ATTR_SUPPORTED_FEATURES: 41}) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["supported_features"] == 43 + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 43 - hass.states.async_set("light.test2", "off", {"supported_features": 256}) + hass.states.async_set("light.test2", STATE_OFF, {ATTR_SUPPORTED_FEATURES: 256}) await hass.async_block_till_done() state = hass.states.get("light.light_group") - assert state.attributes["supported_features"] == 41 + assert state.attributes[ATTR_SUPPORTED_FEATURES] == 41 async def test_service_calls(hass): """Test service calls.""" await async_setup_component( hass, - "light", + LIGHT_DOMAIN, { - "light": [ + LIGHT_DOMAIN: [ {"platform": "demo"}, { - "platform": "group", + "platform": DOMAIN, "entities": [ "light.bed_light", "light.ceiling_lights", @@ -415,50 +483,69 @@ async def test_service_calls(hass): ) await hass.async_block_till_done() - assert hass.states.get("light.light_group").state == "on" - await common.async_toggle(hass, "light.light_group") + assert hass.states.get("light.light_group").state == STATE_ON + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TOGGLE, + {ATTR_ENTITY_ID: "light.light_group"}, + blocking=True, + ) - assert hass.states.get("light.bed_light").state == "off" - assert hass.states.get("light.ceiling_lights").state == "off" - assert hass.states.get("light.kitchen_lights").state == "off" + assert hass.states.get("light.bed_light").state == STATE_OFF + assert hass.states.get("light.ceiling_lights").state == STATE_OFF + assert hass.states.get("light.kitchen_lights").state == STATE_OFF - await common.async_turn_on(hass, "light.light_group") + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "light.light_group"}, + blocking=True, + ) - assert hass.states.get("light.bed_light").state == "on" - assert hass.states.get("light.ceiling_lights").state == "on" - assert hass.states.get("light.kitchen_lights").state == "on" + assert hass.states.get("light.bed_light").state == STATE_ON + assert hass.states.get("light.ceiling_lights").state == STATE_ON + assert hass.states.get("light.kitchen_lights").state == STATE_ON - await common.async_turn_off(hass, "light.light_group") + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.light_group"}, + blocking=True, + ) - assert hass.states.get("light.bed_light").state == "off" - assert hass.states.get("light.ceiling_lights").state == "off" - assert hass.states.get("light.kitchen_lights").state == "off" + assert hass.states.get("light.bed_light").state == STATE_OFF + assert hass.states.get("light.ceiling_lights").state == STATE_OFF + assert hass.states.get("light.kitchen_lights").state == STATE_OFF - await common.async_turn_on( - hass, - "light.light_group", - brightness=128, - effect="Random", - rgb_color=(42, 255, 255), + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.light_group", + ATTR_BRIGHTNESS: 128, + ATTR_EFFECT: "Random", + ATTR_RGB_COLOR: (42, 255, 255), + }, + blocking=True, ) state = hass.states.get("light.bed_light") - assert state.state == "on" - assert state.attributes["brightness"] == 128 - assert state.attributes["effect"] == "Random" - assert state.attributes["rgb_color"] == (42, 255, 255) + assert state.state == STATE_ON + assert state.attributes[ATTR_BRIGHTNESS] == 128 + assert state.attributes[ATTR_EFFECT] == "Random" + assert state.attributes[ATTR_RGB_COLOR] == (42, 255, 255) state = hass.states.get("light.ceiling_lights") - assert state.state == "on" - assert state.attributes["brightness"] == 128 - assert state.attributes["effect"] == "Random" - assert state.attributes["rgb_color"] == (42, 255, 255) + assert state.state == STATE_ON + assert state.attributes[ATTR_BRIGHTNESS] == 128 + assert state.attributes[ATTR_EFFECT] == "Random" + assert state.attributes[ATTR_RGB_COLOR] == (42, 255, 255) state = hass.states.get("light.kitchen_lights") - assert state.state == "on" - assert state.attributes["brightness"] == 128 - assert state.attributes["effect"] == "Random" - assert state.attributes["rgb_color"] == (42, 255, 255) + assert state.state == STATE_ON + assert state.attributes[ATTR_BRIGHTNESS] == 128 + assert state.attributes[ATTR_EFFECT] == "Random" + assert state.attributes[ATTR_RGB_COLOR] == (42, 255, 255) async def test_invalid_service_calls(hass): @@ -474,27 +561,33 @@ async def test_invalid_service_calls(hass): with asynctest.patch.object(hass.services, "async_call") as mock_call: await grouped_light.async_turn_on(brightness=150, four_oh_four="404") - data = {"entity_id": ["light.test1", "light.test2"], "brightness": 150} - mock_call.assert_called_once_with("light", "turn_on", data, blocking=True) + data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_BRIGHTNESS: 150} + mock_call.assert_called_once_with( + LIGHT_DOMAIN, SERVICE_TURN_ON, data, blocking=True + ) mock_call.reset_mock() await grouped_light.async_turn_off(transition=4, four_oh_four="404") - data = {"entity_id": ["light.test1", "light.test2"], "transition": 4} - mock_call.assert_called_once_with("light", "turn_off", data, blocking=True) + data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_TRANSITION: 4} + mock_call.assert_called_once_with( + LIGHT_DOMAIN, SERVICE_TURN_OFF, data, blocking=True + ) mock_call.reset_mock() data = { - "brightness": 150, - "xy_color": (0.5, 0.42), - "rgb_color": (80, 120, 50), - "color_temp": 1234, - "white_value": 1, - "effect": "Sunshine", - "transition": 4, - "flash": "long", + ATTR_BRIGHTNESS: 150, + ATTR_XY_COLOR: (0.5, 0.42), + ATTR_RGB_COLOR: (80, 120, 50), + ATTR_COLOR_TEMP: 1234, + ATTR_WHITE_VALUE: 1, + ATTR_EFFECT: "Sunshine", + ATTR_TRANSITION: 4, + ATTR_FLASH: "long", } await grouped_light.async_turn_on(**data) - data["entity_id"] = ["light.test1", "light.test2"] - data.pop("rgb_color") - data.pop("xy_color") - mock_call.assert_called_once_with("light", "turn_on", data, blocking=True) + data[ATTR_ENTITY_ID] = ["light.test1", "light.test2"] + data.pop(ATTR_RGB_COLOR) + data.pop(ATTR_XY_COLOR) + mock_call.assert_called_once_with( + LIGHT_DOMAIN, SERVICE_TURN_ON, data, blocking=True + )