1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-17 23:53:49 +01:00
Files
core/homeassistant/components/home_connect/fan.py
J. Diego Rodríguez Royo ce47abe1d3 Add climate entity for air conditioner to Home Connect (#155981)
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: emontnemery <erik@montnemery.com>
2026-03-16 15:19:57 +01:00

204 lines
7.2 KiB
Python

"""Provides fan entities for Home Connect."""
import logging
from typing import cast
from aiohomeconnect.model import EventKey, OptionKey
from homeassistant.components.fan import (
FanEntity,
FanEntityDescription,
FanEntityFeature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .common import setup_home_connect_entry
from .coordinator import HomeConnectApplianceCoordinator, HomeConnectConfigEntry
from .entity import HomeConnectEntity
_LOGGER = logging.getLogger(__name__)
PARALLEL_UPDATES = 1
FAN_SPEED_MODE_OPTIONS = {
"auto": "HeatingVentilationAirConditioning.AirConditioner.EnumType.FanSpeedMode.Automatic",
"manual": "HeatingVentilationAirConditioning.AirConditioner.EnumType.FanSpeedMode.Manual",
}
FAN_SPEED_MODE_OPTIONS_INVERTED = {v: k for k, v in FAN_SPEED_MODE_OPTIONS.items()}
AIR_CONDITIONER_ENTITY_DESCRIPTION = FanEntityDescription(
key="air_conditioner",
translation_key="air_conditioner",
name=None,
)
def _get_entities_for_appliance(
appliance_coordinator: HomeConnectApplianceCoordinator,
) -> list[HomeConnectEntity]:
"""Get a list of entities."""
return (
[HomeConnectAirConditioningFanEntity(appliance_coordinator)]
if appliance_coordinator.data.options
and any(
option in appliance_coordinator.data.options
for option in (
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE,
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE,
)
)
else []
)
async def async_setup_entry(
hass: HomeAssistant,
entry: HomeConnectConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Home Connect fan entities."""
setup_home_connect_entry(
hass,
entry,
_get_entities_for_appliance,
async_add_entities,
lambda appliance_coordinator, _: _get_entities_for_appliance(
appliance_coordinator
),
)
class HomeConnectAirConditioningFanEntity(HomeConnectEntity, FanEntity):
"""Representation of a Home Connect fan entity."""
def __init__(
self,
coordinator: HomeConnectApplianceCoordinator,
) -> None:
"""Initialize the entity."""
self._attr_preset_modes = list(FAN_SPEED_MODE_OPTIONS.keys())
self._original_speed_modes_keys = set(FAN_SPEED_MODE_OPTIONS_INVERTED)
super().__init__(
coordinator,
AIR_CONDITIONER_ENTITY_DESCRIPTION,
context_override=(
EventKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE
),
)
self.update_preset_mode()
@callback
def _handle_coordinator_update_preset_mode(self) -> None:
"""Handle updated data from the coordinator."""
self.update_preset_mode()
self.async_write_ha_state()
_LOGGER.debug(
"Updated %s (fan mode), new state: %s", self.entity_id, self.preset_mode
)
async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
self.async_on_remove(
self.coordinator.async_add_listener(
self._handle_coordinator_update_preset_mode,
EventKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE,
)
)
def update_native_value(self) -> None:
"""Set the speed percentage and speed mode values."""
option_value = None
option_key = OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE
if event := self.appliance.events.get(EventKey(option_key)):
option_value = event.value
self._attr_percentage = (
cast(int, option_value) if option_value is not None else None
)
@property
def supported_features(self) -> FanEntityFeature:
"""Return the supported features for this fan entity."""
features = FanEntityFeature(0)
if (
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE
in self.appliance.options
):
features |= FanEntityFeature.SET_SPEED
if (
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE
in self.appliance.options
):
features |= FanEntityFeature.PRESET_MODE
return features
def update_preset_mode(self) -> None:
"""Set the preset mode value."""
option_value = None
option_key = OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE
if event := self.appliance.events.get(EventKey(option_key)):
option_value = event.value
self._attr_preset_mode = (
FAN_SPEED_MODE_OPTIONS_INVERTED.get(cast(str, option_value))
if option_value is not None
else None
)
if (
(
option_definition := self.appliance.options.get(
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE
)
)
and (option_constraints := option_definition.constraints)
and option_constraints.allowed_values
and (
allowed_values_without_none := {
value
for value in option_constraints.allowed_values
if value is not None
}
)
and self._original_speed_modes_keys != allowed_values_without_none
):
self._original_speed_modes_keys = allowed_values_without_none
self._attr_preset_modes = [
key
for key, value in FAN_SPEED_MODE_OPTIONS.items()
if value in self._original_speed_modes_keys
]
async def async_set_percentage(self, percentage: int) -> None:
"""Set the speed of the fan, as a percentage."""
await super().async_set_option_with_key(
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE,
percentage,
)
_LOGGER.debug(
"Updated %s's speed percentage option, new state: %s",
self.entity_id,
percentage,
)
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new target fan mode."""
await super().async_set_option_with_key(
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE,
FAN_SPEED_MODE_OPTIONS[preset_mode],
)
_LOGGER.debug(
"Updated %s's speed mode option, new state: %s", self.entity_id, self.state
)
@property
def available(self) -> bool:
"""Return True if entity is available."""
return super().available and any(
option in self.appliance.options
for option in (
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_MODE,
OptionKey.HEATING_VENTILATION_AIR_CONDITIONING_AIR_CONDITIONER_FAN_SPEED_PERCENTAGE,
)
)