Files
core/homeassistant/components/sofar/select.py
T

90 lines
3.0 KiB
Python

"""Support for Sofar selects."""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from enum import IntEnum
from typing import override
from sofar_modbus.modern.device import SofarInverter
from sofar_modbus.modern.enums import ChargerUseMode, EpsControlMode
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import SofarConfigEntry
from .entity import SofarEntity, SofarEntityDescription
PARALLEL_UPDATES = 1
def _enum_options(enum_type: type[IntEnum]) -> list[str]:
"""The select options a device enum maps to."""
return [member.name.lower() for member in enum_type]
@dataclass(frozen=True, kw_only=True)
class SofarSelectEntityDescription(SelectEntityDescription, SofarEntityDescription):
"""Describe a Sofar select entity."""
options_enum: type[IntEnum]
write_fn: Callable[[SofarInverter, int], Awaitable[None]]
SELECT_DESCRIPTIONS: tuple[SofarSelectEntityDescription, ...] = (
SofarSelectEntityDescription(
key="charger_use_mode",
component="charger",
translation_key="charger_use_mode",
options=_enum_options(ChargerUseMode),
options_enum=ChargerUseMode,
write_fn=lambda device, value: device.charger.write("charger_use_mode", value),
),
SofarSelectEntityDescription(
key="eps_control",
component="eps",
translation_key="eps_control",
options=_enum_options(EpsControlMode),
options_enum=EpsControlMode,
write_fn=lambda device, value: device.eps.async_write_control(
EpsControlMode(value)
),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: SofarConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Sofar Inverter Modbus select platform."""
runtime_data = entry.runtime_data
served = runtime_data.served_components
async_add_entities(
SofarSelect(runtime_data, description)
for description in SELECT_DESCRIPTIONS
if description.component in served
)
class SofarSelect(SofarEntity, SelectEntity):
"""Defines a Sofar select entity."""
entity_description: SofarSelectEntityDescription
@property
@override
def current_option(self) -> str | None:
"""Return the currently selected option."""
component = getattr(self.coordinator.device, self.entity_description.component)
value: IntEnum | None = getattr(component, self.entity_description.key)
return value.name.lower() if value is not None else None
@override
async def async_select_option(self, option: str) -> None:
"""Write the selected option to the device."""
value = self.entity_description.options_enum[option.upper()]
await self.entity_description.write_fn(self.coordinator.device, value.value)
await self.coordinator.async_request_refresh()