Migrate esphome light platform to use _on_static_info_update (#94960)
parent
dcf8db36b7
commit
9876abcac9
|
@ -3,7 +3,13 @@ from __future__ import annotations
|
|||
|
||||
from typing import Any, cast
|
||||
|
||||
from aioesphomeapi import APIVersion, LightColorCapability, LightInfo, LightState
|
||||
from aioesphomeapi import (
|
||||
APIVersion,
|
||||
EntityInfo,
|
||||
LightColorCapability,
|
||||
LightInfo,
|
||||
LightState,
|
||||
)
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
|
@ -22,7 +28,7 @@ from homeassistant.components.light import (
|
|||
LightEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry
|
||||
|
@ -128,6 +134,8 @@ def _filter_color_modes(
|
|||
class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
||||
"""A light implementation for ESPHome."""
|
||||
|
||||
_native_supported_color_modes: list[int]
|
||||
|
||||
@property
|
||||
def _supports_color_mode(self) -> bool:
|
||||
"""Return whether the client supports the new color mode system natively."""
|
||||
|
@ -141,7 +149,7 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity on."""
|
||||
data: dict[str, Any] = {"key": self._static_info.key, "state": True}
|
||||
data: dict[str, Any] = {"key": self._key, "state": True}
|
||||
# The list of color modes that would fit this service call
|
||||
color_modes = self._native_supported_color_modes
|
||||
try_keep_current_mode = True
|
||||
|
@ -259,7 +267,7 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity off."""
|
||||
data: dict[str, Any] = {"key": self._static_info.key, "state": False}
|
||||
data: dict[str, Any] = {"key": self._key, "state": False}
|
||||
if ATTR_FLASH in kwargs:
|
||||
data["flash_length"] = FLASH_LENGTHS[kwargs[ATTR_FLASH]]
|
||||
if ATTR_TRANSITION in kwargs:
|
||||
|
@ -287,17 +295,18 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
@esphome_state_property
|
||||
def rgb_color(self) -> tuple[int, int, int] | None:
|
||||
"""Return the rgb color value [int, int, int]."""
|
||||
state = self._state
|
||||
if not self._supports_color_mode:
|
||||
return (
|
||||
round(self._state.red * 255),
|
||||
round(self._state.green * 255),
|
||||
round(self._state.blue * 255),
|
||||
round(state.red * 255),
|
||||
round(state.green * 255),
|
||||
round(state.blue * 255),
|
||||
)
|
||||
|
||||
return (
|
||||
round(self._state.red * self._state.color_brightness * 255),
|
||||
round(self._state.green * self._state.color_brightness * 255),
|
||||
round(self._state.blue * self._state.color_brightness * 255),
|
||||
round(state.red * state.color_brightness * 255),
|
||||
round(state.green * state.color_brightness * 255),
|
||||
round(state.blue * state.color_brightness * 255),
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -312,15 +321,17 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
@esphome_state_property
|
||||
def rgbww_color(self) -> tuple[int, int, int, int, int] | None:
|
||||
"""Return the rgbww color value [int, int, int, int, int]."""
|
||||
state = self._state
|
||||
rgb = cast("tuple[int, int, int]", self.rgb_color)
|
||||
if not _filter_color_modes(
|
||||
self._native_supported_color_modes, LightColorCapability.COLD_WARM_WHITE
|
||||
):
|
||||
# Try to reverse white + color temp to cwww
|
||||
min_ct = self._static_info.min_mireds
|
||||
max_ct = self._static_info.max_mireds
|
||||
color_temp = min(max(self._state.color_temperature, min_ct), max_ct)
|
||||
white = self._state.white
|
||||
static_info = self._static_info
|
||||
min_ct = static_info.min_mireds
|
||||
max_ct = static_info.max_mireds
|
||||
color_temp = min(max(state.color_temperature, min_ct), max_ct)
|
||||
white = state.white
|
||||
|
||||
ww_frac = (color_temp - min_ct) / (max_ct - min_ct)
|
||||
cw_frac = 1 - ww_frac
|
||||
|
@ -332,8 +343,8 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
)
|
||||
return (
|
||||
*rgb,
|
||||
round(self._state.cold_white * 255),
|
||||
round(self._state.warm_white * 255),
|
||||
round(state.cold_white * 255),
|
||||
round(state.warm_white * 255),
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -348,26 +359,24 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
"""Return the current effect."""
|
||||
return self._state.effect
|
||||
|
||||
@property
|
||||
def _native_supported_color_modes(self) -> list[int]:
|
||||
return self._static_info.supported_color_modes_compat(self._api_version)
|
||||
|
||||
@property
|
||||
def supported_features(self) -> LightEntityFeature:
|
||||
"""Flag supported features."""
|
||||
@callback
|
||||
def _on_static_info_update(self, static_info: EntityInfo) -> None:
|
||||
"""Set attrs from static info."""
|
||||
super()._on_static_info_update(static_info)
|
||||
static_info = self._static_info
|
||||
self._native_supported_color_modes = static_info.supported_color_modes_compat(
|
||||
self._api_version
|
||||
)
|
||||
flags = LightEntityFeature.FLASH
|
||||
|
||||
# All color modes except UNKNOWN,ON_OFF support transition
|
||||
modes = self._native_supported_color_modes
|
||||
if any(m not in (0, LightColorCapability.ON_OFF) for m in modes):
|
||||
flags |= LightEntityFeature.TRANSITION
|
||||
if self._static_info.effects:
|
||||
if static_info.effects:
|
||||
flags |= LightEntityFeature.EFFECT
|
||||
return flags
|
||||
self._attr_supported_features = flags
|
||||
|
||||
@property
|
||||
def supported_color_modes(self) -> set[str] | None:
|
||||
"""Flag supported color modes."""
|
||||
supported = set(map(_color_mode_to_ha, self._native_supported_color_modes))
|
||||
if ColorMode.ONOFF in supported and len(supported) > 1:
|
||||
supported.remove(ColorMode.ONOFF)
|
||||
|
@ -375,19 +384,7 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity):
|
|||
supported.remove(ColorMode.BRIGHTNESS)
|
||||
if ColorMode.WHITE in supported and len(supported) == 1:
|
||||
supported.remove(ColorMode.WHITE)
|
||||
return supported
|
||||
|
||||
@property
|
||||
def effect_list(self) -> list[str]:
|
||||
"""Return the list of supported effects."""
|
||||
return self._static_info.effects
|
||||
|
||||
@property
|
||||
def min_mireds(self) -> int:
|
||||
"""Return the coldest color_temp that this light supports."""
|
||||
return round(self._static_info.min_mireds)
|
||||
|
||||
@property
|
||||
def max_mireds(self) -> int:
|
||||
"""Return the warmest color_temp that this light supports."""
|
||||
return round(self._static_info.max_mireds)
|
||||
self._attr_supported_color_modes = supported
|
||||
self._attr_effect_list = static_info.effects
|
||||
self._attr_min_mireds = round(static_info.min_mireds)
|
||||
self._attr_max_mireds = round(static_info.max_mireds)
|
||||
|
|
Loading…
Reference in New Issue