From 080827fb6234098bcdf03a147605ca53f38a6392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20S=C5=82ota?= Date: Wed, 29 Jan 2020 12:11:22 +0100 Subject: [PATCH] Fix light.turn_on for emulated_hue (#31195) * Fix light.turn_on for emulated_hue HarmonyHub sends `{'xy': [0, 0], 'on': True, 'bri': 0}` when turning on lights that do not support brightness control. Unfortunately current logic always uses brightness value to control on/off state which makes no sense for lights that don't support brightness at all. This change fixes that behavior, making light without brightness control usable with HarmonyHub and probably some other remotes. * Test 'no_brightness' lights --- .../components/emulated_hue/hue_api.py | 5 +- tests/components/emulated_hue/test_hue_api.py | 72 ++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/emulated_hue/hue_api.py b/homeassistant/components/emulated_hue/hue_api.py index b054d69e7a4..459a13c066c 100644 --- a/homeassistant/components/emulated_hue/hue_api.py +++ b/homeassistant/components/emulated_hue/hue_api.py @@ -351,8 +351,9 @@ class HueOneLightChangeView(HomeAssistantView): if HUE_API_STATE_BRI in request_json: if entity.domain == light.DOMAIN: - parsed[STATE_ON] = parsed[STATE_BRIGHTNESS] > 0 - if not entity_features & SUPPORT_BRIGHTNESS: + if entity_features & SUPPORT_BRIGHTNESS: + parsed[STATE_ON] = parsed[STATE_BRIGHTNESS] > 0 + else: parsed[STATE_BRIGHTNESS] = None elif entity.domain == scene.DOMAIN: diff --git a/tests/components/emulated_hue/test_hue_api.py b/tests/components/emulated_hue/test_hue_api.py index 2fb5c48e768..349d53aaee5 100644 --- a/tests/components/emulated_hue/test_hue_api.py +++ b/tests/components/emulated_hue/test_hue_api.py @@ -32,10 +32,20 @@ from homeassistant.components.emulated_hue.hue_api import ( HueOneLightStateView, HueUsernameView, ) -from homeassistant.const import STATE_OFF, STATE_ON +from homeassistant.const import ( + ATTR_ENTITY_ID, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, + STATE_OFF, + STATE_ON, +) import homeassistant.util.dt as dt_util -from tests.common import async_fire_time_changed, get_test_instance_port +from tests.common import ( + async_fire_time_changed, + async_mock_service, + get_test_instance_port, +) HTTP_SERVER_PORT = get_test_instance_port() BRIDGE_SERVER_PORT = get_test_instance_port() @@ -231,6 +241,64 @@ async def test_light_without_brightness_supported(hass_hue, hue_client): assert light_without_brightness_json["type"] == "On/off light" +async def test_light_without_brightness_can_be_turned_off(hass_hue, hue_client): + """Test that light without brightness can be turned off.""" + hass_hue.states.async_set("light.no_brightness", "on", {}) + + # Check if light can be turned off + turn_off_calls = async_mock_service(hass_hue, light.DOMAIN, SERVICE_TURN_OFF) + + no_brightness_result = await perform_put_light_state( + hass_hue, hue_client, "light.no_brightness", False + ) + no_brightness_result_json = await no_brightness_result.json() + + assert no_brightness_result.status == 200 + assert "application/json" in no_brightness_result.headers["content-type"] + assert len(no_brightness_result_json) == 1 + + # Verify that SERVICE_TURN_OFF has been called + await hass_hue.async_block_till_done() + assert 1 == len(turn_off_calls) + call = turn_off_calls[-1] + + assert light.DOMAIN == call.domain + assert SERVICE_TURN_OFF == call.service + assert "light.no_brightness" in call.data[ATTR_ENTITY_ID] + + +async def test_light_without_brightness_can_be_turned_on(hass_hue, hue_client): + """Test that light without brightness can be turned on.""" + hass_hue.states.async_set("light.no_brightness", "off", {}) + + # Check if light can be turned on + turn_on_calls = async_mock_service(hass_hue, light.DOMAIN, SERVICE_TURN_ON) + + no_brightness_result = await perform_put_light_state( + hass_hue, + hue_client, + "light.no_brightness", + True, + # Some remotes, like HarmonyHub send brightness value regardless of light's features + brightness=0, + ) + + no_brightness_result_json = await no_brightness_result.json() + + assert no_brightness_result.status == 200 + assert "application/json" in no_brightness_result.headers["content-type"] + assert len(no_brightness_result_json) == 1 + + # Verify that SERVICE_TURN_ON has been called + await hass_hue.async_block_till_done() + assert 1 == len(turn_on_calls) + call = turn_on_calls[-1] + + assert light.DOMAIN == call.domain + assert SERVICE_TURN_ON == call.service + assert "light.no_brightness" in call.data[ATTR_ENTITY_ID] + + @pytest.mark.parametrize( "state,is_reachable", [