"""Platform for Ohme selects.""" from __future__ import annotations from collections.abc import Awaitable, Callable from dataclasses import dataclass from typing import Any, Final from ohme import ApiException, ChargerMode, OhmeApiClient from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @dataclass(frozen=True, kw_only=True) class OhmeSelectDescription(OhmeEntityDescription, SelectEntityDescription): """Class to describe an Ohme select entity.""" select_fn: Callable[[OhmeApiClient, Any], Awaitable[None]] current_option_fn: Callable[[OhmeApiClient], str | None] SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( key="charge_mode", translation_key="charge_mode", select_fn=lambda client, mode: client.async_set_mode(mode), options=[e.value for e in ChargerMode], current_option_fn=lambda client: client.mode.value if client.mode else None, available_fn=lambda client: client.mode is not None, ) async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ohme selects.""" coordinator = config_entry.runtime_data.charge_session_coordinator async_add_entities([OhmeSelect(coordinator, SELECT_DESCRIPTION)]) class OhmeSelect(OhmeEntity, SelectEntity): """Ohme select entity.""" entity_description: OhmeSelectDescription async def async_select_option(self, option: str) -> None: """Handle the selection of an option.""" try: await self.entity_description.select_fn(self.coordinator.client, option) except ApiException as e: raise HomeAssistantError( translation_key="api_failed", translation_domain=DOMAIN ) from e await self.coordinator.async_request_refresh() @property def current_option(self) -> str | None: """Return the current selected option.""" return self.entity_description.current_option_fn(self.coordinator.client)