Files
core/homeassistant/components/wallbox/select.py

109 lines
3.7 KiB
Python

"""Home Assistant component for accessing the Wallbox Portal API. The switch component creates a switch entity."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from requests import HTTPError
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 (
CHARGER_DATA_KEY,
CHARGER_ECO_SMART_KEY,
CHARGER_FEATURES_KEY,
CHARGER_PLAN_KEY,
CHARGER_POWER_BOOST_KEY,
CHARGER_SERIAL_NUMBER_KEY,
DOMAIN,
EcoSmartMode,
)
from .coordinator import WallboxConfigEntry, WallboxCoordinator
from .entity import WallboxEntity
@dataclass(frozen=True, kw_only=True)
class WallboxSelectEntityDescription(SelectEntityDescription):
"""Describes Wallbox select entity."""
current_option_fn: Callable[[WallboxCoordinator], str | None]
select_option_fn: Callable[[WallboxCoordinator, str], Awaitable[None]]
supported_fn: Callable[[WallboxCoordinator], bool]
SELECT_TYPES: dict[str, WallboxSelectEntityDescription] = {
CHARGER_ECO_SMART_KEY: WallboxSelectEntityDescription(
key=CHARGER_ECO_SMART_KEY,
translation_key=CHARGER_ECO_SMART_KEY,
options=[
EcoSmartMode.OFF,
EcoSmartMode.ECO_MODE,
EcoSmartMode.FULL_SOLAR,
],
select_option_fn=lambda coordinator, mode: coordinator.async_set_eco_smart(
mode
),
current_option_fn=lambda coordinator: coordinator.data[CHARGER_ECO_SMART_KEY],
supported_fn=lambda coordinator: coordinator.data[CHARGER_DATA_KEY][
CHARGER_PLAN_KEY
][CHARGER_FEATURES_KEY].count(CHARGER_POWER_BOOST_KEY),
)
}
async def async_setup_entry(
hass: HomeAssistant,
entry: WallboxConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Create wallbox select entities in HASS."""
coordinator: WallboxCoordinator = entry.runtime_data
if coordinator.data[CHARGER_ECO_SMART_KEY] != EcoSmartMode.DISABLED:
async_add_entities(
WallboxSelect(coordinator, description)
for ent in coordinator.data
if (
(description := SELECT_TYPES.get(ent))
and description.supported_fn(coordinator)
)
)
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
class WallboxSelect(WallboxEntity, SelectEntity):
"""Representation of the Wallbox portal."""
entity_description: WallboxSelectEntityDescription
def __init__(
self,
coordinator: WallboxCoordinator,
description: WallboxSelectEntityDescription,
) -> None:
"""Initialize a Wallbox select entity."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{description.key}-{coordinator.data[CHARGER_DATA_KEY][CHARGER_SERIAL_NUMBER_KEY]}"
@property
def current_option(self) -> str | None:
"""Return an option."""
return self.entity_description.current_option_fn(self.coordinator)
async def async_select_option(self, option: str) -> None:
"""Handle the selection of an option."""
try:
await self.entity_description.select_option_fn(self.coordinator, option)
except (ConnectionError, HTTPError) as e:
raise HomeAssistantError(
translation_key="api_failed", translation_domain=DOMAIN
) from e
await self.coordinator.async_request_refresh()