1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-20 02:48:57 +00:00
Files
core/homeassistant/components/pooldose/select.py
2025-12-19 00:13:26 +01:00

161 lines
5.6 KiB
Python

"""Select entities for the Seko PoolDose integration."""
from __future__ import annotations
from dataclasses import dataclass
import logging
from typing import TYPE_CHECKING, Any, cast
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.const import EntityCategory, UnitOfVolume, UnitOfVolumeFlowRate
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import PooldoseConfigEntry
from .const import UNIT_MAPPING
from .entity import PooldoseEntity
if TYPE_CHECKING:
from .coordinator import PooldoseCoordinator
_LOGGER = logging.getLogger(__name__)
@dataclass(frozen=True, kw_only=True)
class PooldoseSelectEntityDescription(SelectEntityDescription):
"""Describes PoolDose select entity."""
use_unit_conversion: bool = False
SELECT_DESCRIPTIONS: tuple[PooldoseSelectEntityDescription, ...] = (
PooldoseSelectEntityDescription(
key="water_meter_unit",
translation_key="water_meter_unit",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
options=[UnitOfVolume.LITERS, UnitOfVolume.CUBIC_METERS],
use_unit_conversion=True,
),
PooldoseSelectEntityDescription(
key="flow_rate_unit",
translation_key="flow_rate_unit",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
options=[
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
UnitOfVolumeFlowRate.LITERS_PER_SECOND,
],
use_unit_conversion=True,
),
PooldoseSelectEntityDescription(
key="ph_type_dosing_set",
translation_key="ph_type_dosing_set",
entity_category=EntityCategory.CONFIG,
options=["alcalyne", "acid"],
),
PooldoseSelectEntityDescription(
key="ph_type_dosing_method",
translation_key="ph_type_dosing_method",
entity_category=EntityCategory.CONFIG,
options=["off", "proportional", "on_off", "timed"],
entity_registry_enabled_default=False,
),
PooldoseSelectEntityDescription(
key="orp_type_dosing_set",
translation_key="orp_type_dosing_set",
entity_category=EntityCategory.CONFIG,
options=["low", "high"],
entity_registry_enabled_default=False,
),
PooldoseSelectEntityDescription(
key="orp_type_dosing_method",
translation_key="orp_type_dosing_method",
entity_category=EntityCategory.CONFIG,
options=["off", "proportional", "on_off", "timed"],
entity_registry_enabled_default=False,
),
PooldoseSelectEntityDescription(
key="cl_type_dosing_set",
translation_key="cl_type_dosing_set",
entity_category=EntityCategory.CONFIG,
options=["low", "high"],
entity_registry_enabled_default=False,
),
PooldoseSelectEntityDescription(
key="cl_type_dosing_method",
translation_key="cl_type_dosing_method",
entity_category=EntityCategory.CONFIG,
options=["off", "proportional", "on_off", "timed"],
entity_registry_enabled_default=False,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: PooldoseConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up PoolDose select entities from a config entry."""
if TYPE_CHECKING:
assert config_entry.unique_id is not None
coordinator = config_entry.runtime_data
select_data = coordinator.data["select"]
serial_number = config_entry.unique_id
async_add_entities(
PooldoseSelect(coordinator, serial_number, coordinator.device_info, description)
for description in SELECT_DESCRIPTIONS
if description.key in select_data
)
class PooldoseSelect(PooldoseEntity, SelectEntity):
"""Select entity for the Seko PoolDose Python API."""
entity_description: PooldoseSelectEntityDescription
def __init__(
self,
coordinator: PooldoseCoordinator,
serial_number: str,
device_info: Any,
description: PooldoseSelectEntityDescription,
) -> None:
"""Initialize the select."""
super().__init__(coordinator, serial_number, device_info, description, "select")
self._async_update_attrs()
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._async_update_attrs()
super()._handle_coordinator_update()
def _async_update_attrs(self) -> None:
"""Update select attributes."""
data = cast(dict, self.get_data())
api_value = cast(str, data["value"])
# Convert API value to Home Assistant unit if unit conversion is enabled
if self.entity_description.use_unit_conversion:
# Map API value (e.g., "m3") to HA unit (e.g., "m³")
self._attr_current_option = UNIT_MAPPING.get(api_value, api_value)
else:
self._attr_current_option = api_value
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
# Convert Home Assistant unit to API value if unit conversion is enabled
if self.entity_description.use_unit_conversion:
# Invert UNIT_MAPPING to get API value from HA unit
reverse_map = {v: k for k, v in UNIT_MAPPING.items()}
api_value = reverse_map.get(option, option)
else:
api_value = option
await self.coordinator.client.set_select(self.entity_description.key, api_value)
self._attr_current_option = option
self.async_write_ha_state()