"""Test reproduce state for Light.""" import pytest from homeassistant.components import light from homeassistant.core import HomeAssistant, State from homeassistant.helpers.state import async_reproduce_state from tests.common import async_mock_service VALID_BRIGHTNESS = {"brightness": 180} VALID_EFFECT = {"effect": "random"} VALID_COLOR_TEMP = {"color_temp": 240} VALID_HS_COLOR = {"hs_color": (345, 75)} VALID_RGB_COLOR = {"rgb_color": (255, 63, 111)} VALID_RGBW_COLOR = {"rgbw_color": (255, 63, 111, 10)} VALID_RGBWW_COLOR = {"rgbww_color": (255, 63, 111, 10, 20)} VALID_XY_COLOR = {"xy_color": (0.59, 0.274)} NONE_BRIGHTNESS = {"brightness": None} NONE_EFFECT = {"effect": None} NONE_COLOR_TEMP = {"color_temp": None} NONE_HS_COLOR = {"hs_color": None} NONE_RGB_COLOR = {"rgb_color": None} NONE_RGBW_COLOR = {"rgbw_color": None} NONE_RGBWW_COLOR = {"rgbww_color": None} NONE_XY_COLOR = {"xy_color": None} async def test_reproducing_states( hass: HomeAssistant, caplog: pytest.LogCaptureFixture ) -> None: """Test reproducing Light states.""" hass.states.async_set("light.entity_off", "off", {}) hass.states.async_set("light.entity_bright", "on", VALID_BRIGHTNESS) hass.states.async_set("light.entity_effect", "on", VALID_EFFECT) hass.states.async_set("light.entity_temp", "on", VALID_COLOR_TEMP) hass.states.async_set("light.entity_hs", "on", VALID_HS_COLOR) hass.states.async_set("light.entity_rgb", "on", VALID_RGB_COLOR) hass.states.async_set("light.entity_xy", "on", VALID_XY_COLOR) turn_on_calls = async_mock_service(hass, "light", "turn_on") turn_off_calls = async_mock_service(hass, "light", "turn_off") # These calls should do nothing as entities already in desired state await async_reproduce_state( hass, [ State("light.entity_off", "off"), State("light.entity_bright", "on", VALID_BRIGHTNESS), State("light.entity_effect", "on", VALID_EFFECT), State("light.entity_temp", "on", VALID_COLOR_TEMP), State("light.entity_hs", "on", VALID_HS_COLOR), State("light.entity_rgb", "on", VALID_RGB_COLOR), State("light.entity_xy", "on", VALID_XY_COLOR), ], ) assert len(turn_on_calls) == 0 assert len(turn_off_calls) == 0 # Test invalid state is handled await async_reproduce_state(hass, [State("light.entity_off", "not_supported")]) assert "not_supported" in caplog.text assert len(turn_on_calls) == 0 assert len(turn_off_calls) == 0 # Make sure correct services are called await async_reproduce_state( hass, [ State("light.entity_xy", "off"), State("light.entity_off", "on", VALID_BRIGHTNESS), State("light.entity_bright", "on", VALID_EFFECT), State("light.entity_effect", "on", VALID_COLOR_TEMP), State("light.entity_temp", "on", VALID_HS_COLOR), State("light.entity_hs", "on", VALID_RGB_COLOR), State("light.entity_rgb", "on", VALID_XY_COLOR), ], ) assert len(turn_on_calls) == 6 expected_calls = [] expected_off = dict(VALID_BRIGHTNESS) expected_off["entity_id"] = "light.entity_off" expected_calls.append(expected_off) expected_bright = dict(VALID_EFFECT) expected_bright["entity_id"] = "light.entity_bright" expected_calls.append(expected_bright) expected_effect = dict(VALID_COLOR_TEMP) expected_effect["entity_id"] = "light.entity_effect" expected_calls.append(expected_effect) expected_temp = dict(VALID_HS_COLOR) expected_temp["entity_id"] = "light.entity_temp" expected_calls.append(expected_temp) expected_hs = dict(VALID_RGB_COLOR) expected_hs["entity_id"] = "light.entity_hs" expected_calls.append(expected_hs) expected_rgb = dict(VALID_XY_COLOR) expected_rgb["entity_id"] = "light.entity_rgb" expected_calls.append(expected_rgb) for call in turn_on_calls: assert call.domain == "light" found = False for expected in expected_calls: if call.data["entity_id"] == expected["entity_id"]: # We found the matching entry assert call.data == expected found = True break # No entry found assert found assert len(turn_off_calls) == 1 assert turn_off_calls[0].domain == "light" assert turn_off_calls[0].data == {"entity_id": "light.entity_xy"} @pytest.mark.parametrize( "color_mode", ( light.ColorMode.COLOR_TEMP, light.ColorMode.BRIGHTNESS, light.ColorMode.HS, light.ColorMode.ONOFF, light.ColorMode.RGB, light.ColorMode.RGBW, light.ColorMode.RGBWW, light.ColorMode.UNKNOWN, light.ColorMode.WHITE, light.ColorMode.XY, ), ) async def test_filter_color_modes( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, color_mode ) -> None: """Test filtering of parameters according to color mode.""" hass.states.async_set("light.entity", "off", {}) all_colors = { **VALID_COLOR_TEMP, **VALID_HS_COLOR, **VALID_RGB_COLOR, **VALID_RGBW_COLOR, **VALID_RGBWW_COLOR, **VALID_XY_COLOR, **VALID_BRIGHTNESS, } turn_on_calls = async_mock_service(hass, "light", "turn_on") await async_reproduce_state( hass, [State("light.entity", "on", {**all_colors, "color_mode": color_mode})] ) expected_map = { light.ColorMode.COLOR_TEMP: {**VALID_BRIGHTNESS, **VALID_COLOR_TEMP}, light.ColorMode.BRIGHTNESS: VALID_BRIGHTNESS, light.ColorMode.HS: {**VALID_BRIGHTNESS, **VALID_HS_COLOR}, light.ColorMode.ONOFF: {**VALID_BRIGHTNESS}, light.ColorMode.RGB: {**VALID_BRIGHTNESS, **VALID_RGB_COLOR}, light.ColorMode.RGBW: {**VALID_BRIGHTNESS, **VALID_RGBW_COLOR}, light.ColorMode.RGBWW: {**VALID_BRIGHTNESS, **VALID_RGBWW_COLOR}, light.ColorMode.UNKNOWN: { **VALID_BRIGHTNESS, **VALID_HS_COLOR, }, light.ColorMode.WHITE: { **VALID_BRIGHTNESS, light.ATTR_WHITE: VALID_BRIGHTNESS[light.ATTR_BRIGHTNESS], }, light.ColorMode.XY: {**VALID_BRIGHTNESS, **VALID_XY_COLOR}, } expected = expected_map[color_mode] assert len(turn_on_calls) == 1 assert turn_on_calls[0].domain == "light" assert dict(turn_on_calls[0].data) == {"entity_id": "light.entity", **expected} # This should do nothing, the light is already in the desired state hass.states.async_set("light.entity", "on", {"color_mode": color_mode, **expected}) await async_reproduce_state( hass, [State("light.entity", "on", {**expected, "color_mode": color_mode})] ) assert len(turn_on_calls) == 1 @pytest.mark.parametrize( "saved_state", ( NONE_BRIGHTNESS, NONE_EFFECT, NONE_COLOR_TEMP, NONE_HS_COLOR, NONE_RGB_COLOR, NONE_RGBW_COLOR, NONE_RGBWW_COLOR, NONE_XY_COLOR, ), ) async def test_filter_none(hass: HomeAssistant, saved_state) -> None: """Test filtering of parameters which are None.""" hass.states.async_set("light.entity", "off", {}) turn_on_calls = async_mock_service(hass, "light", "turn_on") await async_reproduce_state(hass, [State("light.entity", "on", saved_state)]) assert len(turn_on_calls) == 1 assert turn_on_calls[0].domain == "light" assert dict(turn_on_calls[0].data) == {"entity_id": "light.entity"} # This should do nothing, the light is already in the desired state hass.states.async_set("light.entity", "on", {}) await async_reproduce_state(hass, [State("light.entity", "on", saved_state)]) assert len(turn_on_calls) == 1