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, ClimatePreset,
ClimateState, ClimateState,
ClimateSwingMode, ClimateSwingMode,
EntityInfo,
) )
from homeassistant.components.climate import ( from homeassistant.components.climate import (
@ -51,7 +52,7 @@ from homeassistant.const import (
PRECISION_WHOLE, PRECISION_WHOLE,
UnitOfTemperature, UnitOfTemperature,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .entity import ( from .entity import (
@ -140,71 +141,32 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
_attr_temperature_unit = UnitOfTemperature.CELSIUS _attr_temperature_unit = UnitOfTemperature.CELSIUS
@property @callback
def precision(self) -> float: def _on_static_info_update(self, static_info: EntityInfo) -> None:
"""Return the precision of the climate device.""" """Set attrs from static info."""
precicions = [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS] super()._on_static_info_update(static_info)
if self._static_info.visual_current_temperature_step != 0: static_info = self._static_info
step = self._static_info.visual_current_temperature_step self._attr_precision = self._get_precision()
else: self._attr_hvac_modes = [
step = self._static_info.visual_target_temperature_step _CLIMATE_MODES.from_esphome(mode) for mode in static_info.supported_modes
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
] ]
self._attr_fan_modes = [
@property _FAN_MODES.from_esphome(mode) for mode in static_info.supported_fan_modes
def fan_modes(self) -> list[str]: ] + static_info.supported_custom_fan_modes
"""Return the list of available fan modes.""" self._attr_preset_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 [
_PRESETS.from_esphome(preset) _PRESETS.from_esphome(preset)
for preset in self._static_info.supported_presets_compat(self._api_version) for preset in static_info.supported_presets_compat(self._api_version)
] + self._static_info.supported_custom_presets ] + static_info.supported_custom_presets
self._attr_swing_modes = [
@property
def swing_modes(self) -> list[str]:
"""Return the list of available swing modes."""
return [
_SWING_MODES.from_esphome(mode) _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 # Round to one digit because of floating point math
return round(self._static_info.visual_target_temperature_step, 1) self._attr_target_temperature_step = round(
static_info.visual_target_temperature_step, 1
@property )
def min_temp(self) -> float: self._attr_min_temp = static_info.visual_min_temperature
"""Return the minimum temperature.""" self._attr_max_temp = static_info.visual_max_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."""
features = ClimateEntityFeature(0) features = ClimateEntityFeature(0)
if self._static_info.supports_two_point_target_temperature: if self._static_info.supports_two_point_target_temperature:
features |= ClimateEntityFeature.TARGET_TEMPERATURE_RANGE features |= ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
@ -216,7 +178,21 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
features |= ClimateEntityFeature.FAN_MODE features |= ClimateEntityFeature.FAN_MODE
if self.swing_modes: if self.swing_modes:
features |= ClimateEntityFeature.SWING_MODE 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 @property
@esphome_state_property @esphome_state_property
@ -237,16 +213,16 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
@esphome_state_property @esphome_state_property
def fan_mode(self) -> str | None: def fan_mode(self) -> str | None:
"""Return current fan setting.""" """Return current fan setting."""
return self._state.custom_fan_mode or _FAN_MODES.from_esphome( state = self._state
self._state.fan_mode return state.custom_fan_mode or _FAN_MODES.from_esphome(state.fan_mode)
)
@property @property
@esphome_state_property @esphome_state_property
def preset_mode(self) -> str | None: def preset_mode(self) -> str | None:
"""Return current preset mode.""" """Return current preset mode."""
return self._state.custom_preset or _PRESETS.from_esphome( state = self._state
self._state.preset_compat(self._api_version) return state.custom_preset or _PRESETS.from_esphome(
state.preset_compat(self._api_version)
) )
@property @property
@ -281,7 +257,7 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
async def async_set_temperature(self, **kwargs: Any) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature (and operation mode if set).""" """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: if ATTR_HVAC_MODE in kwargs:
data["mode"] = _CLIMATE_MODES.from_hass( data["mode"] = _CLIMATE_MODES.from_hass(
cast(HVACMode, kwargs[ATTR_HVAC_MODE]) 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: async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target operation mode.""" """Set new target operation mode."""
await self._client.climate_command( 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: async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set preset mode.""" """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: if preset_mode in self._static_info.supported_custom_presets:
kwargs["custom_preset"] = preset_mode kwargs["custom_preset"] = preset_mode
else: else:
@ -311,7 +287,7 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
async def async_set_fan_mode(self, fan_mode: str) -> None: async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set new fan mode.""" """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: if fan_mode in self._static_info.supported_custom_fan_modes:
kwargs["custom_fan_mode"] = fan_mode kwargs["custom_fan_mode"] = fan_mode
else: else:
@ -321,5 +297,5 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
async def async_set_swing_mode(self, swing_mode: str) -> None: async def async_set_swing_mode(self, swing_mode: str) -> None:
"""Set new swing mode.""" """Set new swing mode."""
await self._client.climate_command( 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)
) )