Migrate esphome climate platform to use _on_static_info_update (#95471)
This commit is contained in:
parent
03dac6e171
commit
25dc9f5942
1 changed files with 48 additions and 72 deletions
|
@ -11,6 +11,7 @@ from aioesphomeapi import (
|
|||
ClimatePreset,
|
||||
ClimateState,
|
||||
ClimateSwingMode,
|
||||
EntityInfo,
|
||||
)
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
|
@ -51,7 +52,7 @@ from homeassistant.const import (
|
|||
PRECISION_WHOLE,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .entity import (
|
||||
|
@ -140,71 +141,32 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
|
||||
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
|
||||
@property
|
||||
def precision(self) -> float:
|
||||
"""Return the precision of the climate device."""
|
||||
precicions = [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
|
||||
if self._static_info.visual_current_temperature_step != 0:
|
||||
step = self._static_info.visual_current_temperature_step
|
||||
else:
|
||||
step = self._static_info.visual_target_temperature_step
|
||||
for prec in precicions:
|
||||
if step >= prec:
|
||||
return prec
|
||||
# Fall back to highest precision, tenths
|
||||
return PRECISION_TENTHS
|
||||
|
||||
@property
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the list of available operation modes."""
|
||||
return [
|
||||
_CLIMATE_MODES.from_esphome(mode)
|
||||
for mode in self._static_info.supported_modes
|
||||
@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._attr_precision = self._get_precision()
|
||||
self._attr_hvac_modes = [
|
||||
_CLIMATE_MODES.from_esphome(mode) for mode in static_info.supported_modes
|
||||
]
|
||||
|
||||
@property
|
||||
def fan_modes(self) -> list[str]:
|
||||
"""Return the list of available fan modes."""
|
||||
return [
|
||||
_FAN_MODES.from_esphome(mode)
|
||||
for mode in self._static_info.supported_fan_modes
|
||||
] + self._static_info.supported_custom_fan_modes
|
||||
|
||||
@property
|
||||
def preset_modes(self) -> list[str]:
|
||||
"""Return preset modes."""
|
||||
return [
|
||||
self._attr_fan_modes = [
|
||||
_FAN_MODES.from_esphome(mode) for mode in static_info.supported_fan_modes
|
||||
] + static_info.supported_custom_fan_modes
|
||||
self._attr_preset_modes = [
|
||||
_PRESETS.from_esphome(preset)
|
||||
for preset in self._static_info.supported_presets_compat(self._api_version)
|
||||
] + self._static_info.supported_custom_presets
|
||||
|
||||
@property
|
||||
def swing_modes(self) -> list[str]:
|
||||
"""Return the list of available swing modes."""
|
||||
return [
|
||||
for preset in static_info.supported_presets_compat(self._api_version)
|
||||
] + static_info.supported_custom_presets
|
||||
self._attr_swing_modes = [
|
||||
_SWING_MODES.from_esphome(mode)
|
||||
for mode in self._static_info.supported_swing_modes
|
||||
for mode in static_info.supported_swing_modes
|
||||
]
|
||||
|
||||
@property
|
||||
def target_temperature_step(self) -> float:
|
||||
"""Return the supported step of target temperature."""
|
||||
# Round to one digit because of floating point math
|
||||
return round(self._static_info.visual_target_temperature_step, 1)
|
||||
|
||||
@property
|
||||
def min_temp(self) -> float:
|
||||
"""Return the minimum temperature."""
|
||||
return self._static_info.visual_min_temperature
|
||||
|
||||
@property
|
||||
def max_temp(self) -> float:
|
||||
"""Return the maximum temperature."""
|
||||
return self._static_info.visual_max_temperature
|
||||
|
||||
@property
|
||||
def supported_features(self) -> ClimateEntityFeature:
|
||||
"""Return the list of supported features."""
|
||||
self._attr_target_temperature_step = round(
|
||||
static_info.visual_target_temperature_step, 1
|
||||
)
|
||||
self._attr_min_temp = static_info.visual_min_temperature
|
||||
self._attr_max_temp = static_info.visual_max_temperature
|
||||
features = ClimateEntityFeature(0)
|
||||
if self._static_info.supports_two_point_target_temperature:
|
||||
features |= ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
|
@ -216,7 +178,21 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
features |= ClimateEntityFeature.FAN_MODE
|
||||
if self.swing_modes:
|
||||
features |= ClimateEntityFeature.SWING_MODE
|
||||
return features
|
||||
self._attr_supported_features = features
|
||||
|
||||
def _get_precision(self) -> float:
|
||||
"""Return the precision of the climate device."""
|
||||
precicions = [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
|
||||
static_info = self._static_info
|
||||
if static_info.visual_current_temperature_step != 0:
|
||||
step = static_info.visual_current_temperature_step
|
||||
else:
|
||||
step = static_info.visual_target_temperature_step
|
||||
for prec in precicions:
|
||||
if step >= prec:
|
||||
return prec
|
||||
# Fall back to highest precision, tenths
|
||||
return PRECISION_TENTHS
|
||||
|
||||
@property
|
||||
@esphome_state_property
|
||||
|
@ -237,16 +213,16 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
@esphome_state_property
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return current fan setting."""
|
||||
return self._state.custom_fan_mode or _FAN_MODES.from_esphome(
|
||||
self._state.fan_mode
|
||||
)
|
||||
state = self._state
|
||||
return state.custom_fan_mode or _FAN_MODES.from_esphome(state.fan_mode)
|
||||
|
||||
@property
|
||||
@esphome_state_property
|
||||
def preset_mode(self) -> str | None:
|
||||
"""Return current preset mode."""
|
||||
return self._state.custom_preset or _PRESETS.from_esphome(
|
||||
self._state.preset_compat(self._api_version)
|
||||
state = self._state
|
||||
return state.custom_preset or _PRESETS.from_esphome(
|
||||
state.preset_compat(self._api_version)
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -281,7 +257,7 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature (and operation mode if set)."""
|
||||
data: dict[str, Any] = {"key": self._static_info.key}
|
||||
data: dict[str, Any] = {"key": self._key}
|
||||
if ATTR_HVAC_MODE in kwargs:
|
||||
data["mode"] = _CLIMATE_MODES.from_hass(
|
||||
cast(HVACMode, kwargs[ATTR_HVAC_MODE])
|
||||
|
@ -297,12 +273,12 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set new target operation mode."""
|
||||
await self._client.climate_command(
|
||||
key=self._static_info.key, mode=_CLIMATE_MODES.from_hass(hvac_mode)
|
||||
key=self._key, mode=_CLIMATE_MODES.from_hass(hvac_mode)
|
||||
)
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set preset mode."""
|
||||
kwargs: dict[str, Any] = {"key": self._static_info.key}
|
||||
kwargs: dict[str, Any] = {"key": self._key}
|
||||
if preset_mode in self._static_info.supported_custom_presets:
|
||||
kwargs["custom_preset"] = preset_mode
|
||||
else:
|
||||
|
@ -311,7 +287,7 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set new fan mode."""
|
||||
kwargs: dict[str, Any] = {"key": self._static_info.key}
|
||||
kwargs: dict[str, Any] = {"key": self._key}
|
||||
if fan_mode in self._static_info.supported_custom_fan_modes:
|
||||
kwargs["custom_fan_mode"] = fan_mode
|
||||
else:
|
||||
|
@ -321,5 +297,5 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
|
|||
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
||||
"""Set new swing mode."""
|
||||
await self._client.climate_command(
|
||||
key=self._static_info.key, swing_mode=_SWING_MODES.from_hass(swing_mode)
|
||||
key=self._key, swing_mode=_SWING_MODES.from_hass(swing_mode)
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue