Refactor light platform to avoid duplicate property calls (#106857)

This commit is contained in:
J. Nick Koston 2024-01-02 01:49:53 -10:00 committed by GitHub
parent 73bc65059b
commit 3f1263a533
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -345,6 +345,9 @@ def filter_turn_off_params(
light: LightEntity, params: dict[str, Any] light: LightEntity, params: dict[str, Any]
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Filter out params not used in turn off or not supported by the light.""" """Filter out params not used in turn off or not supported by the light."""
if not params:
return params
supported_features = light.supported_features_compat supported_features = light.supported_features_compat
if LightEntityFeature.FLASH not in supported_features: if LightEntityFeature.FLASH not in supported_features:
@ -947,8 +950,8 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
@property @property
def color_temp_kelvin(self) -> int | None: def color_temp_kelvin(self) -> int | None:
"""Return the CT color value in Kelvin.""" """Return the CT color value in Kelvin."""
if self._attr_color_temp_kelvin is None and self.color_temp: if self._attr_color_temp_kelvin is None and (color_temp := self.color_temp):
return color_util.color_temperature_mired_to_kelvin(self.color_temp) return color_util.color_temperature_mired_to_kelvin(color_temp)
return self._attr_color_temp_kelvin return self._attr_color_temp_kelvin
@cached_property @cached_property
@ -993,19 +996,21 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
supported_color_modes = self._light_internal_supported_color_modes supported_color_modes = self._light_internal_supported_color_modes
if ColorMode.COLOR_TEMP in supported_color_modes: if ColorMode.COLOR_TEMP in supported_color_modes:
data[ATTR_MIN_COLOR_TEMP_KELVIN] = self.min_color_temp_kelvin min_color_temp_kelvin = self.min_color_temp_kelvin
data[ATTR_MAX_COLOR_TEMP_KELVIN] = self.max_color_temp_kelvin max_color_temp_kelvin = self.max_color_temp_kelvin
if not self.max_color_temp_kelvin: data[ATTR_MIN_COLOR_TEMP_KELVIN] = min_color_temp_kelvin
data[ATTR_MAX_COLOR_TEMP_KELVIN] = max_color_temp_kelvin
if not max_color_temp_kelvin:
data[ATTR_MIN_MIREDS] = None data[ATTR_MIN_MIREDS] = None
else: else:
data[ATTR_MIN_MIREDS] = color_util.color_temperature_kelvin_to_mired( data[ATTR_MIN_MIREDS] = color_util.color_temperature_kelvin_to_mired(
self.max_color_temp_kelvin max_color_temp_kelvin
) )
if not self.min_color_temp_kelvin: if not min_color_temp_kelvin:
data[ATTR_MAX_MIREDS] = None data[ATTR_MAX_MIREDS] = None
else: else:
data[ATTR_MAX_MIREDS] = color_util.color_temperature_kelvin_to_mired( data[ATTR_MAX_MIREDS] = color_util.color_temperature_kelvin_to_mired(
self.min_color_temp_kelvin min_color_temp_kelvin
) )
if LightEntityFeature.EFFECT in supported_features: if LightEntityFeature.EFFECT in supported_features:
data[ATTR_EFFECT_LIST] = self.effect_list data[ATTR_EFFECT_LIST] = self.effect_list
@ -1018,30 +1023,27 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
self, color_mode: ColorMode | str self, color_mode: ColorMode | str
) -> dict[str, tuple[float, ...]]: ) -> dict[str, tuple[float, ...]]:
data: dict[str, tuple[float, ...]] = {} data: dict[str, tuple[float, ...]] = {}
if color_mode == ColorMode.HS and self.hs_color: if color_mode == ColorMode.HS and (hs_color := self.hs_color):
hs_color = self.hs_color
data[ATTR_HS_COLOR] = (round(hs_color[0], 3), round(hs_color[1], 3)) data[ATTR_HS_COLOR] = (round(hs_color[0], 3), round(hs_color[1], 3))
data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color) data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color)
data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color) data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color)
elif color_mode == ColorMode.XY and self.xy_color: elif color_mode == ColorMode.XY and (xy_color := self.xy_color):
xy_color = self.xy_color
data[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color) data[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
data[ATTR_RGB_COLOR] = color_util.color_xy_to_RGB(*xy_color) data[ATTR_RGB_COLOR] = color_util.color_xy_to_RGB(*xy_color)
data[ATTR_XY_COLOR] = (round(xy_color[0], 6), round(xy_color[1], 6)) data[ATTR_XY_COLOR] = (round(xy_color[0], 6), round(xy_color[1], 6))
elif color_mode == ColorMode.RGB and self.rgb_color: elif color_mode == ColorMode.RGB and (rgb_color := self.rgb_color):
rgb_color = self.rgb_color
data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color) data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3]) data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color) data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
elif color_mode == ColorMode.RGBW and self._light_internal_rgbw_color: elif color_mode == ColorMode.RGBW and (
rgbw_color = self._light_internal_rgbw_color rgbw_color := self._light_internal_rgbw_color
):
rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color) rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color)
data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color) data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3]) data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
data[ATTR_RGBW_COLOR] = tuple(int(x) for x in rgbw_color[0:4]) data[ATTR_RGBW_COLOR] = tuple(int(x) for x in rgbw_color[0:4])
data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color) data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
elif color_mode == ColorMode.RGBWW and self.rgbww_color: elif color_mode == ColorMode.RGBWW and (rgbww_color := self.rgbww_color):
rgbww_color = self.rgbww_color
rgb_color = color_util.color_rgbww_to_rgb( rgb_color = color_util.color_rgbww_to_rgb(
*rgbww_color, self.min_color_temp_kelvin, self.max_color_temp_kelvin *rgbww_color, self.min_color_temp_kelvin, self.max_color_temp_kelvin
) )
@ -1049,8 +1051,10 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3]) data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
data[ATTR_RGBWW_COLOR] = tuple(int(x) for x in rgbww_color[0:5]) data[ATTR_RGBWW_COLOR] = tuple(int(x) for x in rgbww_color[0:5])
data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color) data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
elif color_mode == ColorMode.COLOR_TEMP and self.color_temp_kelvin: elif color_mode == ColorMode.COLOR_TEMP and (
hs_color = color_util.color_temperature_to_hs(self.color_temp_kelvin) color_temp_kelvin := self.color_temp_kelvin
):
hs_color = color_util.color_temperature_to_hs(color_temp_kelvin)
data[ATTR_HS_COLOR] = (round(hs_color[0], 3), round(hs_color[1], 3)) data[ATTR_HS_COLOR] = (round(hs_color[0], 3), round(hs_color[1], 3))
data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color) data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color)
data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color) data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color)
@ -1062,22 +1066,26 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
"""Return state attributes.""" """Return state attributes."""
data: dict[str, Any] = {} data: dict[str, Any] = {}
supported_features = self.supported_features_compat supported_features = self.supported_features_compat
supported_color_modes = self._light_internal_supported_color_modes supported_color_modes = self.supported_color_modes
legacy_supported_color_modes = (
supported_color_modes or self._light_internal_supported_color_modes
)
supported_features_value = supported_features.value supported_features_value = supported_features.value
color_mode = self._light_internal_color_mode if self.is_on else None _is_on = self.is_on
color_mode = self._light_internal_color_mode if _is_on else None
if color_mode and color_mode not in supported_color_modes: if color_mode and color_mode not in legacy_supported_color_modes:
# Increase severity to warning in 2021.6, reject in 2021.10 # Increase severity to warning in 2021.6, reject in 2021.10
_LOGGER.debug( _LOGGER.debug(
"%s: set to unsupported color_mode: %s, supported_color_modes: %s", "%s: set to unsupported color_mode: %s, supported_color_modes: %s",
self.entity_id, self.entity_id,
color_mode, color_mode,
supported_color_modes, legacy_supported_color_modes,
) )
data[ATTR_COLOR_MODE] = color_mode data[ATTR_COLOR_MODE] = color_mode
if brightness_supported(self.supported_color_modes): if brightness_supported(supported_color_modes):
if color_mode in COLOR_MODES_BRIGHTNESS: if color_mode in COLOR_MODES_BRIGHTNESS:
data[ATTR_BRIGHTNESS] = self.brightness data[ATTR_BRIGHTNESS] = self.brightness
else: else:
@ -1085,20 +1093,19 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
elif supported_features_value & SUPPORT_BRIGHTNESS: elif supported_features_value & SUPPORT_BRIGHTNESS:
# Backwards compatibility for ambiguous / incomplete states # Backwards compatibility for ambiguous / incomplete states
# Add warning in 2021.6, remove in 2021.10 # Add warning in 2021.6, remove in 2021.10
if self.is_on: if _is_on:
data[ATTR_BRIGHTNESS] = self.brightness data[ATTR_BRIGHTNESS] = self.brightness
else: else:
data[ATTR_BRIGHTNESS] = None data[ATTR_BRIGHTNESS] = None
if color_temp_supported(self.supported_color_modes): if color_temp_supported(supported_color_modes):
if color_mode == ColorMode.COLOR_TEMP: if color_mode == ColorMode.COLOR_TEMP:
data[ATTR_COLOR_TEMP_KELVIN] = self.color_temp_kelvin color_temp_kelvin = self.color_temp_kelvin
if self.color_temp_kelvin: data[ATTR_COLOR_TEMP_KELVIN] = color_temp_kelvin
if color_temp_kelvin:
data[ data[
ATTR_COLOR_TEMP ATTR_COLOR_TEMP
] = color_util.color_temperature_kelvin_to_mired( ] = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin)
self.color_temp_kelvin
)
else: else:
data[ATTR_COLOR_TEMP] = None data[ATTR_COLOR_TEMP] = None
else: else:
@ -1107,43 +1114,42 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
elif supported_features_value & SUPPORT_COLOR_TEMP: elif supported_features_value & SUPPORT_COLOR_TEMP:
# Backwards compatibility # Backwards compatibility
# Add warning in 2021.6, remove in 2021.10 # Add warning in 2021.6, remove in 2021.10
if self.is_on: if _is_on:
data[ATTR_COLOR_TEMP_KELVIN] = self.color_temp_kelvin color_temp_kelvin = self.color_temp_kelvin
if self.color_temp_kelvin: data[ATTR_COLOR_TEMP_KELVIN] = color_temp_kelvin
if color_temp_kelvin:
data[ data[
ATTR_COLOR_TEMP ATTR_COLOR_TEMP
] = color_util.color_temperature_kelvin_to_mired( ] = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin)
self.color_temp_kelvin
)
else: else:
data[ATTR_COLOR_TEMP] = None data[ATTR_COLOR_TEMP] = None
else: else:
data[ATTR_COLOR_TEMP_KELVIN] = None data[ATTR_COLOR_TEMP_KELVIN] = None
data[ATTR_COLOR_TEMP] = None data[ATTR_COLOR_TEMP] = None
if color_supported(supported_color_modes) or color_temp_supported( if color_supported(legacy_supported_color_modes) or color_temp_supported(
supported_color_modes legacy_supported_color_modes
): ):
data[ATTR_HS_COLOR] = None data[ATTR_HS_COLOR] = None
data[ATTR_RGB_COLOR] = None data[ATTR_RGB_COLOR] = None
data[ATTR_XY_COLOR] = None data[ATTR_XY_COLOR] = None
if ColorMode.RGBW in supported_color_modes: if ColorMode.RGBW in legacy_supported_color_modes:
data[ATTR_RGBW_COLOR] = None data[ATTR_RGBW_COLOR] = None
if ColorMode.RGBWW in supported_color_modes: if ColorMode.RGBWW in legacy_supported_color_modes:
data[ATTR_RGBWW_COLOR] = None data[ATTR_RGBWW_COLOR] = None
if color_mode: if color_mode:
data.update(self._light_internal_convert_color(color_mode)) data.update(self._light_internal_convert_color(color_mode))
if LightEntityFeature.EFFECT in supported_features: if LightEntityFeature.EFFECT in supported_features:
data[ATTR_EFFECT] = self.effect if self.is_on else None data[ATTR_EFFECT] = self.effect if _is_on else None
return data return data
@property @property
def _light_internal_supported_color_modes(self) -> set[ColorMode] | set[str]: def _light_internal_supported_color_modes(self) -> set[ColorMode] | set[str]:
"""Calculate supported color modes with backwards compatibility.""" """Calculate supported color modes with backwards compatibility."""
if self.supported_color_modes is not None: if (_supported_color_modes := self.supported_color_modes) is not None:
return self.supported_color_modes return _supported_color_modes
# Backwards compatibility for supported_color_modes added in 2021.4 # Backwards compatibility for supported_color_modes added in 2021.4
# Add warning in 2021.6, remove in 2021.10 # Add warning in 2021.6, remove in 2021.10