From bcd8f43e7bd0312f028343ecd4f82be91b80b7cd Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Fri, 14 May 2021 23:23:29 +0200 Subject: [PATCH] Update light intents to check supported_color_modes (#50625) --- homeassistant/components/light/intent.py | 29 ++++++++++++++++++++---- homeassistant/helpers/intent.py | 2 +- tests/components/light/test_intent.py | 14 +++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/light/intent.py b/homeassistant/components/light/intent.py index be9346cf85b..25475ca0cb5 100644 --- a/homeassistant/components/light/intent.py +++ b/homeassistant/components/light/intent.py @@ -2,7 +2,7 @@ import voluptuous as vol from homeassistant.const import ATTR_ENTITY_ID -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, State from homeassistant.helpers import intent import homeassistant.helpers.config_validation as cv import homeassistant.util.color as color_util @@ -10,10 +10,11 @@ import homeassistant.util.color as color_util from . import ( ATTR_BRIGHTNESS_PCT, ATTR_RGB_COLOR, + ATTR_SUPPORTED_COLOR_MODES, DOMAIN, SERVICE_TURN_ON, - SUPPORT_BRIGHTNESS, - SUPPORT_COLOR, + brightness_supported, + color_supported, ) INTENT_SET = "HassLightSet" @@ -24,6 +25,24 @@ async def async_setup_intents(hass: HomeAssistant) -> None: hass.helpers.intent.async_register(SetIntentHandler()) +def _test_supports_color(state: State) -> None: + """Test if state supports colors.""" + supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES) + if not color_supported(supported_color_modes): + raise intent.IntentHandleError( + f"Entity {state.name} does not support changing colors" + ) + + +def _test_supports_brightness(state: State) -> None: + """Test if state supports brightness.""" + supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES) + if not brightness_supported(supported_color_modes): + raise intent.IntentHandleError( + f"Entity {state.name} does not support changing brightness" + ) + + class SetIntentHandler(intent.IntentHandler): """Handle set color intents.""" @@ -46,14 +65,14 @@ class SetIntentHandler(intent.IntentHandler): speech_parts = [] if "color" in slots: - intent.async_test_feature(state, SUPPORT_COLOR, "changing colors") + _test_supports_color(state) service_data[ATTR_RGB_COLOR] = slots["color"]["value"] # Use original passed in value of the color because we don't have # human readable names for that internally. speech_parts.append(f"the color {intent_obj.slots['color']['value']}") if "brightness" in slots: - intent.async_test_feature(state, SUPPORT_BRIGHTNESS, "changing brightness") + _test_supports_brightness(state) service_data[ATTR_BRIGHTNESS_PCT] = slots["brightness"]["value"] speech_parts.append(f"{slots['brightness']['value']}% brightness") diff --git a/homeassistant/helpers/intent.py b/homeassistant/helpers/intent.py index 96cfbf0e1b5..cfc89240b78 100644 --- a/homeassistant/helpers/intent.py +++ b/homeassistant/helpers/intent.py @@ -119,7 +119,7 @@ def async_match_state( @callback def async_test_feature(state: State, feature: int, feature_name: str) -> None: - """Test is state supports a feature.""" + """Test if state supports a feature.""" if state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) & feature == 0: raise IntentHandleError(f"Entity {state.name} does not support {feature_name}") diff --git a/tests/components/light/test_intent.py b/tests/components/light/test_intent.py index 4adba921d5e..6a5add41cff 100644 --- a/tests/components/light/test_intent.py +++ b/tests/components/light/test_intent.py @@ -1,7 +1,11 @@ """Tests for the light intents.""" from homeassistant.components import light -from homeassistant.components.light import intent -from homeassistant.const import ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, SERVICE_TURN_ON +from homeassistant.components.light import ( + ATTR_SUPPORTED_COLOR_MODES, + COLOR_MODE_HS, + intent, +) +from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON from homeassistant.helpers.intent import IntentHandleError from tests.common import async_mock_service @@ -10,7 +14,7 @@ from tests.common import async_mock_service async def test_intent_set_color(hass): """Test the set color intent.""" hass.states.async_set( - "light.hello_2", "off", {ATTR_SUPPORTED_FEATURES: light.SUPPORT_COLOR} + "light.hello_2", "off", {ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_HS]} ) hass.states.async_set("switch.hello", "off") calls = async_mock_service(hass, light.DOMAIN, light.SERVICE_TURN_ON) @@ -55,9 +59,7 @@ async def test_intent_set_color_tests_feature(hass): async def test_intent_set_color_and_brightness(hass): """Test the set color intent.""" hass.states.async_set( - "light.hello_2", - "off", - {ATTR_SUPPORTED_FEATURES: (light.SUPPORT_COLOR | light.SUPPORT_BRIGHTNESS)}, + "light.hello_2", "off", {ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_HS]} ) hass.states.async_set("switch.hello", "off") calls = async_mock_service(hass, light.DOMAIN, light.SERVICE_TURN_ON)