Add common light helpers to test for feature support (#49199)

This commit is contained in:
Erik Montnemery 2021-04-15 20:32:27 +02:00 committed by GitHub
parent 236d274351
commit 3d90d6073e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 23 deletions

View File

@ -504,12 +504,12 @@ class LightCapabilities(AlexaEntity):
"""Yield the supported interfaces.""" """Yield the supported interfaces."""
yield AlexaPowerController(self.entity) yield AlexaPowerController(self.entity)
color_modes = self.entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) color_modes = self.entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES)
if any(mode in color_modes for mode in light.COLOR_MODES_BRIGHTNESS): if light.brightness_supported(color_modes):
yield AlexaBrightnessController(self.entity) 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) 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 AlexaColorTemperatureController(self.entity)
yield AlexaEndpointHealth(self.hass, self.entity) yield AlexaEndpointHealth(self.hass, self.entity)

View File

@ -214,9 +214,9 @@ class BrightnessTrait(_Trait):
@staticmethod @staticmethod
def supported(domain, features, device_class, attributes): def supported(domain, features, device_class, attributes):
"""Test if state is supported.""" """Test if state is supported."""
color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, [])
if domain == light.DOMAIN: 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 return False
@ -368,21 +368,21 @@ class ColorSettingTrait(_Trait):
if domain != light.DOMAIN: if domain != light.DOMAIN:
return False return False
color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES)
return light.COLOR_MODE_COLOR_TEMP in color_modes or any( return light.color_temp_supported(color_modes) or light.color_supported(
mode in color_modes for mode in light.COLOR_MODES_COLOR color_modes
) )
def sync_attributes(self): def sync_attributes(self):
"""Return color temperature attributes for a sync request.""" """Return color temperature attributes for a sync request."""
attrs = self.state.attributes attrs = self.state.attributes
color_modes = attrs.get(light.ATTR_SUPPORTED_COLOR_MODES, []) color_modes = attrs.get(light.ATTR_SUPPORTED_COLOR_MODES)
response = {} response = {}
if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): if light.color_supported(color_modes):
response["colorModel"] = "hsv" 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 # Max Kelvin is Min Mireds K = 1000000 / mireds
# Min Kelvin is Max Mireds K = 1000000 / mireds # Min Kelvin is Max Mireds K = 1000000 / mireds
response["colorTemperatureRange"] = { response["colorTemperatureRange"] = {
@ -398,10 +398,10 @@ class ColorSettingTrait(_Trait):
def query_attributes(self): def query_attributes(self):
"""Return color temperature query attributes.""" """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 = {} 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) color_hs = self.state.attributes.get(light.ATTR_HS_COLOR)
brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1) brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1)
if color_hs is not None: if color_hs is not None:
@ -411,7 +411,7 @@ class ColorSettingTrait(_Trait):
"value": brightness / 255, "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) temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
# Some faulty integrations might put 0 in here, raising exception. # Some faulty integrations might put 0 in here, raising exception.
if temp == 0: if temp == 0:

View File

@ -11,10 +11,10 @@ from homeassistant.components.light import (
ATTR_MAX_MIREDS, ATTR_MAX_MIREDS,
ATTR_MIN_MIREDS, ATTR_MIN_MIREDS,
ATTR_SUPPORTED_COLOR_MODES, ATTR_SUPPORTED_COLOR_MODES,
COLOR_MODE_COLOR_TEMP,
COLOR_MODES_BRIGHTNESS,
COLOR_MODES_COLOR,
DOMAIN, DOMAIN,
brightness_supported,
color_supported,
color_temp_supported,
) )
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
@ -62,15 +62,15 @@ class Light(HomeAccessory):
state = self.hass.states.get(self.entity_id) state = self.hass.states.get(self.entity_id)
self._features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) 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) 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_HUE)
self.chars.append(CHAR_SATURATION) 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 # ColorTemperature and Hue characteristic should not be
# exposed both. Both states are tracked separately in HomeKit, # exposed both. Both states are tracked separately in HomeKit,
# causing "source of truth" problems. # causing "source of truth" problems.
@ -132,7 +132,7 @@ class Light(HomeAccessory):
events.append(f"color temperature at {char_values[CHAR_COLOR_TEMPERATURE]}") events.append(f"color temperature at {char_values[CHAR_COLOR_TEMPERATURE]}")
if ( 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_HUE in char_values
and CHAR_SATURATION in char_values and CHAR_SATURATION in char_values
): ):

View File

@ -87,6 +87,27 @@ def valid_supported_color_modes(color_modes):
return 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. # Float that represents transition time in seconds to make change.
ATTR_TRANSITION = "transition" ATTR_TRANSITION = "transition"