"""Select entity for Xiaoxiang Smart BMS MOS gate control.""" from __future__ import annotations from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( DOMAIN, MOS_BOTH_OFF, MOS_CHARGE_OFF, MOS_DISCHARGE_OFF, MOS_NORMAL, ) from .coordinator import BmsCoordinator # Maps the human-readable option to the XX byte value in the write command _OPTION_TO_VALUE: dict[str, int] = { "Normal": MOS_NORMAL, "Charge Disabled": MOS_CHARGE_OFF, "Discharge Disabled": MOS_DISCHARGE_OFF, "Both Disabled": MOS_BOTH_OFF, } _OPTIONS = list(_OPTION_TO_VALUE) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: coordinator: BmsCoordinator = hass.data[DOMAIN][entry.entry_id] async_add_entities([BmsMosSelect(coordinator)]) class BmsMosSelect(CoordinatorEntity[BmsCoordinator], SelectEntity): """Dropdown to control the BMS charge/discharge MOSFET gates. Current state is derived from the MOS status bits returned by the BMS on every poll. Selecting an option sends the write command (0xE1) immediately and triggers a coordinator refresh so sensors update. """ _attr_has_entity_name = True _attr_name = "MOS Control" _attr_options = _OPTIONS _attr_icon = "mdi:electric-switch" def __init__(self, coordinator: BmsCoordinator) -> None: super().__init__(coordinator) self._attr_unique_id = f"{coordinator.address}_mos_control" self._attr_device_info = coordinator.device_info @property def current_option(self) -> str | None: data = self.coordinator.data if not data: return None charge = data.get("mos_charge_enabled", True) discharge = data.get("mos_discharge_enabled", True) if charge and discharge: return "Normal" if not charge and discharge: return "Charge Disabled" if charge and not discharge: return "Discharge Disabled" return "Both Disabled" async def async_select_option(self, option: str) -> None: value = _OPTION_TO_VALUE[option] await self.coordinator.async_write_mos(value)