Migrate esphome climate platform to use _on_static_info_update (#95471)

This commit is contained in:
J. Nick Koston 2023-06-28 13:37:35 -05:00 committed by GitHub
parent 03dac6e171
commit 25dc9f5942
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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)
)