From 3d90d6073ec2dbd25ffdacca71ccacf095407b73 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 15 Apr 2021 20:32:27 +0200 Subject: [PATCH] Add common light helpers to test for feature support (#49199) --- homeassistant/components/alexa/entities.py | 8 +++---- .../components/google_assistant/trait.py | 22 +++++++++---------- .../components/homekit/type_lights.py | 16 +++++++------- homeassistant/components/light/__init__.py | 21 ++++++++++++++++++ 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index cbeb3a869dd..c6ae05e9d6f 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -504,12 +504,12 @@ class LightCapabilities(AlexaEntity): """Yield the supported interfaces.""" yield AlexaPowerController(self.entity) - color_modes = self.entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) - if any(mode in color_modes for mode in light.COLOR_MODES_BRIGHTNESS): + color_modes = self.entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) + if light.brightness_supported(color_modes): yield AlexaBrightnessController(self.entity) - if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): + if light.color_supported(color_modes): yield AlexaColorController(self.entity) - if light.COLOR_MODE_COLOR_TEMP in color_modes: + if light.color_temp_supported(color_modes): yield AlexaColorTemperatureController(self.entity) yield AlexaEndpointHealth(self.hass, self.entity) diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 3bfce41ae2b..25013dad171 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -214,9 +214,9 @@ class BrightnessTrait(_Trait): @staticmethod def supported(domain, features, device_class, attributes): """Test if state is supported.""" - color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) if domain == light.DOMAIN: - return any(mode in color_modes for mode in light.COLOR_MODES_BRIGHTNESS) + color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) + return light.brightness_supported(color_modes) return False @@ -368,21 +368,21 @@ class ColorSettingTrait(_Trait): if domain != light.DOMAIN: return False - color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) - return light.COLOR_MODE_COLOR_TEMP in color_modes or any( - mode in color_modes for mode in light.COLOR_MODES_COLOR + color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) + return light.color_temp_supported(color_modes) or light.color_supported( + color_modes ) def sync_attributes(self): """Return color temperature attributes for a sync request.""" attrs = self.state.attributes - color_modes = attrs.get(light.ATTR_SUPPORTED_COLOR_MODES, []) + color_modes = attrs.get(light.ATTR_SUPPORTED_COLOR_MODES) response = {} - if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): + if light.color_supported(color_modes): response["colorModel"] = "hsv" - if light.COLOR_MODE_COLOR_TEMP in color_modes: + if light.color_temp_supported(color_modes): # Max Kelvin is Min Mireds K = 1000000 / mireds # Min Kelvin is Max Mireds K = 1000000 / mireds response["colorTemperatureRange"] = { @@ -398,10 +398,10 @@ class ColorSettingTrait(_Trait): def query_attributes(self): """Return color temperature query attributes.""" - color_modes = self.state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) + color_modes = self.state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) color = {} - if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): + if light.color_supported(color_modes): color_hs = self.state.attributes.get(light.ATTR_HS_COLOR) brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1) if color_hs is not None: @@ -411,7 +411,7 @@ class ColorSettingTrait(_Trait): "value": brightness / 255, } - if light.COLOR_MODE_COLOR_TEMP in color_modes: + if light.color_temp_supported(color_modes): temp = self.state.attributes.get(light.ATTR_COLOR_TEMP) # Some faulty integrations might put 0 in here, raising exception. if temp == 0: diff --git a/homeassistant/components/homekit/type_lights.py b/homeassistant/components/homekit/type_lights.py index 614d9427ba6..cb3c97fadb4 100644 --- a/homeassistant/components/homekit/type_lights.py +++ b/homeassistant/components/homekit/type_lights.py @@ -11,10 +11,10 @@ from homeassistant.components.light import ( ATTR_MAX_MIREDS, ATTR_MIN_MIREDS, ATTR_SUPPORTED_COLOR_MODES, - COLOR_MODE_COLOR_TEMP, - COLOR_MODES_BRIGHTNESS, - COLOR_MODES_COLOR, DOMAIN, + brightness_supported, + color_supported, + color_temp_supported, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -62,15 +62,15 @@ class Light(HomeAccessory): state = self.hass.states.get(self.entity_id) self._features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) - self._color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, []) + self._color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES) - if any(mode in self._color_modes for mode in COLOR_MODES_BRIGHTNESS): + if brightness_supported(self._color_modes): self.chars.append(CHAR_BRIGHTNESS) - if any(mode in self._color_modes for mode in COLOR_MODES_COLOR): + if color_supported(self._color_modes): self.chars.append(CHAR_HUE) self.chars.append(CHAR_SATURATION) - elif COLOR_MODE_COLOR_TEMP in self._color_modes: + elif color_temp_supported(self._color_modes): # ColorTemperature and Hue characteristic should not be # exposed both. Both states are tracked separately in HomeKit, # causing "source of truth" problems. @@ -132,7 +132,7 @@ class Light(HomeAccessory): events.append(f"color temperature at {char_values[CHAR_COLOR_TEMPERATURE]}") if ( - any(mode in self._color_modes for mode in COLOR_MODES_COLOR) + color_supported(self._color_modes) and CHAR_HUE in char_values and CHAR_SATURATION in char_values ): diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index bfdb723e159..1b55aa51c45 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -87,6 +87,27 @@ def valid_supported_color_modes(color_modes): return color_modes +def brightness_supported(color_modes): + """Test if brightness is supported.""" + if not color_modes: + return False + return any(mode in COLOR_MODES_BRIGHTNESS for mode in color_modes) + + +def color_supported(color_modes): + """Test if color is supported.""" + if not color_modes: + return False + return any(mode in COLOR_MODES_COLOR for mode in color_modes) + + +def color_temp_supported(color_modes): + """Test if color temperature is supported.""" + if not color_modes: + return False + return COLOR_MODE_COLOR_TEMP in color_modes + + # Float that represents transition time in seconds to make change. ATTR_TRANSITION = "transition"