Refactor _supported_features (#565)

* initial commit

* change features to dict

* another slight refactor
This commit is contained in:
Benjamin Auquite 2023-04-10 12:07:31 -05:00 committed by GitHub
commit a888afd6dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 31 deletions

View file

@ -273,6 +273,8 @@ VALIDATION_TUPLES = [
), ),
] ]
CONST_COLOR = "color"
def timedelta_as_int(value): def timedelta_as_int(value):
"""Convert a `datetime.timedelta` object to an integer. """Convert a `datetime.timedelta` object to an integer.

View file

@ -23,7 +23,11 @@ from homeassistant.components.light import (
ATTR_COLOR_NAME, ATTR_COLOR_NAME,
ATTR_COLOR_TEMP_KELVIN, ATTR_COLOR_TEMP_KELVIN,
ATTR_HS_COLOR, ATTR_HS_COLOR,
ATTR_MAX_COLOR_TEMP_KELVIN,
ATTR_MIN_COLOR_TEMP_KELVIN,
ATTR_RGB_COLOR, ATTR_RGB_COLOR,
ATTR_RGBW_COLOR,
ATTR_RGBWW_COLOR,
ATTR_SUPPORTED_COLOR_MODES, ATTR_SUPPORTED_COLOR_MODES,
ATTR_TRANSITION, ATTR_TRANSITION,
ATTR_XY_COLOR, ATTR_XY_COLOR,
@ -32,6 +36,7 @@ from homeassistant.components.light import (
COLOR_MODE_HS, COLOR_MODE_HS,
COLOR_MODE_RGB, COLOR_MODE_RGB,
COLOR_MODE_RGBW, COLOR_MODE_RGBW,
COLOR_MODE_RGBWW,
COLOR_MODE_XY, COLOR_MODE_XY,
) )
from homeassistant.components.light import ( from homeassistant.components.light import (
@ -129,6 +134,7 @@ from .const import (
CONF_TRANSITION, CONF_TRANSITION,
CONF_TURN_ON_LIGHTS, CONF_TURN_ON_LIGHTS,
CONF_USE_DEFAULTS, CONF_USE_DEFAULTS,
CONST_COLOR,
DOMAIN, DOMAIN,
EXTRA_VALIDATION, EXTRA_VALIDATION,
ICON_BRIGHTNESS, ICON_BRIGHTNESS,
@ -155,6 +161,16 @@ _SUPPORT_OPTS = {
"transition": SUPPORT_TRANSITION, "transition": SUPPORT_TRANSITION,
} }
VALID_COLOR_MODES = {
COLOR_MODE_BRIGHTNESS: ATTR_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP: ATTR_COLOR_TEMP_KELVIN,
COLOR_MODE_HS: ATTR_HS_COLOR,
COLOR_MODE_RGB: ATTR_RGB_COLOR,
COLOR_MODE_RGBW: ATTR_RGBW_COLOR,
COLOR_MODE_RGBWW: ATTR_RGBWW_COLOR,
COLOR_MODE_XY: ATTR_XY_COLOR,
}
_ORDER = (SUN_EVENT_SUNRISE, SUN_EVENT_NOON, SUN_EVENT_SUNSET, SUN_EVENT_MIDNIGHT) _ORDER = (SUN_EVENT_SUNRISE, SUN_EVENT_NOON, SUN_EVENT_SUNSET, SUN_EVENT_MIDNIGHT)
_ALLOWED_ORDERS = {_ORDER[i:] + _ORDER[:i] for i in range(len(_ORDER))} _ALLOWED_ORDERS = {_ORDER[i:] + _ORDER[:i] for i in range(len(_ORDER))}
@ -623,33 +639,51 @@ def _expand_light_groups(hass: HomeAssistant, lights: list[str]) -> list[str]:
return list(all_lights) return list(all_lights)
def _supported_to_attributes(supported):
supported_attributes = {}
supports_colors = False
for mode, attr in VALID_COLOR_MODES.items():
if mode not in supported:
continue
supported_attributes[attr] = True
if (
not supports_colors
and mode != COLOR_MODE_BRIGHTNESS
and mode != COLOR_MODE_COLOR_TEMP
):
supports_colors = True
return supported_attributes, supports_colors
def _supported_features(hass: HomeAssistant, light: str): def _supported_features(hass: HomeAssistant, light: str):
state = hass.states.get(light) state = hass.states.get(light)
supported_features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) legacy_supported_features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
supported = { legacy_supported = {
key for key, value in _SUPPORT_OPTS.items() if supported_features & value key for key, value in _SUPPORT_OPTS.items() if legacy_supported_features & value
} }
supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set()) supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set())
if COLOR_MODE_RGB in supported_color_modes: supported, supports_colors = _supported_to_attributes(
supported.add("color") legacy_supported.union(supported_color_modes)
)
min_kelvin = state.attributes.get(ATTR_MIN_COLOR_TEMP_KELVIN)
max_kelvin = state.attributes.get(ATTR_MAX_COLOR_TEMP_KELVIN)
supported.update(
{
ATTR_MIN_COLOR_TEMP_KELVIN: min_kelvin,
ATTR_MAX_COLOR_TEMP_KELVIN: max_kelvin,
}
)
if supports_colors:
# Adding brightness here, see # Adding brightness here, see
# comment https://github.com/basnijholt/adaptive-lighting/issues/112#issuecomment-836944011 # comment https://github.com/basnijholt/adaptive-lighting/issues/112#issuecomment-836944011
supported.add("brightness") supported[ATTR_BRIGHTNESS] = True
if COLOR_MODE_RGBW in supported_color_modes: if CONST_COLOR not in legacy_supported:
supported.add("color") # supports_colors = False
supported.add("brightness") # see above url _LOGGER.debug(
if COLOR_MODE_XY in supported_color_modes: "'supported_color_modes' supports color but the legacy 'supported_features'"
supported.add("color") " bitfield says we do not. Despite this we'll assume light '%s' supports colors",
supported.add("brightness") # see above url )
if COLOR_MODE_HS in supported_color_modes: return supported, supports_colors
supported.add("color")
supported.add("brightness") # see above url
if COLOR_MODE_COLOR_TEMP in supported_color_modes:
supported.add("color_temp")
supported.add("brightness") # see above url
if COLOR_MODE_BRIGHTNESS in supported_color_modes:
supported.add("brightness")
return supported
def color_difference_redmean( def color_difference_redmean(
@ -1104,12 +1138,12 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
# Build service data. # Build service data.
service_data = {ATTR_ENTITY_ID: light} service_data = {ATTR_ENTITY_ID: light}
features = _supported_features(self.hass, light) features, supports_colors = _supported_features(self.hass, light)
# Check transition == 0 to fix #378 # Check transition == 0 to fix #378
if "transition" in features and transition > 0: if ATTR_TRANSITION in features and transition > 0:
service_data[ATTR_TRANSITION] = transition service_data[ATTR_TRANSITION] = transition
if "brightness" in features and adapt_brightness: if ATTR_BRIGHTNESS in features and adapt_brightness:
brightness = round(255 * self._settings["brightness_pct"] / 100) brightness = round(255 * self._settings["brightness_pct"] / 100)
service_data[ATTR_BRIGHTNESS] = brightness service_data[ATTR_BRIGHTNESS] = brightness
@ -1118,19 +1152,18 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
and self._sun_light_settings.sleep_rgb_or_color_temp == "rgb_color" and self._sun_light_settings.sleep_rgb_or_color_temp == "rgb_color"
) )
if ( if (
"color_temp" in features ATTR_COLOR_TEMP_KELVIN in features
and adapt_color and adapt_color
and not (prefer_rgb_color and "color" in features) and not (prefer_rgb_color and supports_colors)
and not (sleep_rgb and "color" in features) and not (sleep_rgb and supports_colors)
): ):
_LOGGER.debug("%s: Setting color_temp of light %s", self._name, light) _LOGGER.debug("%s: Setting color_temp of light %s", self._name, light)
attributes = self.hass.states.get(light).attributes min_kelvin = features[ATTR_MIN_COLOR_TEMP_KELVIN]
min_kelvin = attributes["min_color_temp_kelvin"] max_kelvin = features[ATTR_MAX_COLOR_TEMP_KELVIN]
max_kelvin = attributes["max_color_temp_kelvin"]
color_temp_kelvin = self._settings["color_temp_kelvin"] color_temp_kelvin = self._settings["color_temp_kelvin"]
color_temp_kelvin = max(min(color_temp_kelvin, max_kelvin), min_kelvin) color_temp_kelvin = max(min(color_temp_kelvin, max_kelvin), min_kelvin)
service_data[ATTR_COLOR_TEMP_KELVIN] = color_temp_kelvin service_data[ATTR_COLOR_TEMP_KELVIN] = color_temp_kelvin
elif "color" in features and adapt_color: elif supports_colors and adapt_color:
_LOGGER.debug("%s: Setting rgb_color of light %s", self._name, light) _LOGGER.debug("%s: Setting rgb_color of light %s", self._name, light)
service_data[ATTR_RGB_COLOR] = self._settings["rgb_color"] service_data[ATTR_RGB_COLOR] = self._settings["rgb_color"]