"""Select platform for LED Screen Controller (CSS source & brightness source).""" from __future__ import annotations import logging from typing import Any 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, DATA_COORDINATOR, TARGET_TYPE_KEY_COLORS from .coordinator import WLEDScreenControllerCoordinator _LOGGER = logging.getLogger(__name__) NONE_OPTION = "— None —" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up LED Screen Controller select entities.""" data = hass.data[DOMAIN][entry.entry_id] coordinator: WLEDScreenControllerCoordinator = data[DATA_COORDINATOR] entities: list[SelectEntity] = [] if coordinator.data and "targets" in coordinator.data: for target_id, target_data in coordinator.data["targets"].items(): info = target_data["info"] # Only LED targets if info.get("target_type") == TARGET_TYPE_KEY_COLORS: continue entities.append( CSSSourceSelect(coordinator, target_id, entry.entry_id) ) entities.append( BrightnessSourceSelect(coordinator, target_id, entry.entry_id) ) async_add_entities(entities) class CSSSourceSelect(CoordinatorEntity, SelectEntity): """Select entity for choosing a color strip source for an LED target.""" _attr_has_entity_name = True _attr_icon = "mdi:palette" def __init__( self, coordinator: WLEDScreenControllerCoordinator, target_id: str, entry_id: str, ) -> None: super().__init__(coordinator) self._target_id = target_id self._entry_id = entry_id self._attr_unique_id = f"{target_id}_css_source" self._attr_translation_key = "color_strip_source" @property def device_info(self) -> dict[str, Any]: return {"identifiers": {(DOMAIN, self._target_id)}} @property def options(self) -> list[str]: if not self.coordinator.data: return [] sources = self.coordinator.data.get("css_sources") or [] return [s["name"] for s in sources] @property def current_option(self) -> str | None: if not self.coordinator.data: return None target_data = self.coordinator.data.get("targets", {}).get(self._target_id) if not target_data: return None current_id = target_data["info"].get("color_strip_source_id", "") sources = self.coordinator.data.get("css_sources") or [] for s in sources: if s["id"] == current_id: return s["name"] return None @property def available(self) -> bool: if not self.coordinator.data: return False return self._target_id in self.coordinator.data.get("targets", {}) async def async_select_option(self, option: str) -> None: source_id = self._name_to_id_map().get(option) if source_id is None: _LOGGER.error("CSS source not found: %s", option) return await self.coordinator.update_target( self._target_id, color_strip_source_id=source_id ) def _name_to_id_map(self) -> dict[str, str]: sources = (self.coordinator.data or {}).get("css_sources") or [] return {s["name"]: s["id"] for s in sources} class BrightnessSourceSelect(CoordinatorEntity, SelectEntity): """Select entity for choosing a brightness value source for an LED target.""" _attr_has_entity_name = True _attr_icon = "mdi:brightness-auto" def __init__( self, coordinator: WLEDScreenControllerCoordinator, target_id: str, entry_id: str, ) -> None: super().__init__(coordinator) self._target_id = target_id self._entry_id = entry_id self._attr_unique_id = f"{target_id}_brightness_source" self._attr_translation_key = "brightness_source" @property def device_info(self) -> dict[str, Any]: return {"identifiers": {(DOMAIN, self._target_id)}} @property def options(self) -> list[str]: if not self.coordinator.data: return [NONE_OPTION] sources = self.coordinator.data.get("value_sources") or [] return [NONE_OPTION] + [s["name"] for s in sources] @property def current_option(self) -> str | None: if not self.coordinator.data: return None target_data = self.coordinator.data.get("targets", {}).get(self._target_id) if not target_data: return None current_id = target_data["info"].get("brightness_value_source_id", "") if not current_id: return NONE_OPTION sources = self.coordinator.data.get("value_sources") or [] for s in sources: if s["id"] == current_id: return s["name"] return NONE_OPTION @property def available(self) -> bool: if not self.coordinator.data: return False return self._target_id in self.coordinator.data.get("targets", {}) async def async_select_option(self, option: str) -> None: if option == NONE_OPTION: source_id = "" else: name_map = { s["name"]: s["id"] for s in (self.coordinator.data or {}).get("value_sources") or [] } source_id = name_map.get(option) if source_id is None: _LOGGER.error("Value source not found: %s", option) return await self.coordinator.update_target( self._target_id, brightness_value_source_id=source_id )