"""The LED Screen Controller integration.""" from __future__ import annotations import logging from datetime import timedelta from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ( DOMAIN, CONF_SERVER_URL, CONF_API_KEY, DEFAULT_SCAN_INTERVAL, TARGET_TYPE_KEY_COLORS, DATA_COORDINATOR, DATA_WS_MANAGER, DATA_EVENT_LISTENER, ) from .coordinator import WLEDScreenControllerCoordinator from .event_listener import EventStreamListener from .ws_manager import KeyColorsWebSocketManager _LOGGER = logging.getLogger(__name__) PLATFORMS: list[Platform] = [ Platform.SWITCH, Platform.SENSOR, Platform.NUMBER, Platform.LIGHT, ] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up LED Screen Controller from a config entry.""" server_url = entry.data[CONF_SERVER_URL] api_key = entry.data[CONF_API_KEY] session = async_get_clientsession(hass) coordinator = WLEDScreenControllerCoordinator( hass, session, server_url, api_key, update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), ) await coordinator.async_config_entry_first_refresh() ws_manager = KeyColorsWebSocketManager(hass, server_url, api_key) event_listener = EventStreamListener(hass, server_url, api_key, coordinator) await event_listener.start() # Create device entries for each target device_registry = dr.async_get(hass) if coordinator.data and "targets" in coordinator.data: for target_id, target_data in coordinator.data["targets"].items(): info = target_data["info"] target_type = info.get("target_type", "led") model = ( "Key Colors Target" if target_type == TARGET_TYPE_KEY_COLORS else "LED Target" ) device_registry.async_get_or_create( config_entry_id=entry.entry_id, identifiers={(DOMAIN, target_id)}, name=info.get("name", target_id), manufacturer="LED Screen Controller", model=model, configuration_url=server_url, ) # Store data hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = { DATA_COORDINATOR: coordinator, DATA_WS_MANAGER: ws_manager, DATA_EVENT_LISTENER: event_listener, } # Track target IDs to detect changes initial_target_ids = set( coordinator.data.get("targets", {}).keys() if coordinator.data else [] ) def _on_coordinator_update() -> None: """Manage WS connections and detect target list changes.""" if not coordinator.data: return targets = coordinator.data.get("targets", {}) # Start/stop WS connections for KC targets based on processing state for target_id, target_data in targets.items(): info = target_data.get("info", {}) state = target_data.get("state") or {} if info.get("target_type") == TARGET_TYPE_KEY_COLORS: if state.get("processing"): hass.async_create_task(ws_manager.start_listening(target_id)) else: hass.async_create_task(ws_manager.stop_listening(target_id)) # Reload if target list changed current_ids = set(targets.keys()) if current_ids != initial_target_ids: _LOGGER.info("Target list changed, reloading integration") hass.async_create_task( hass.config_entries.async_reload(entry.entry_id) ) coordinator.async_add_listener(_on_coordinator_update) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" entry_data = hass.data[DOMAIN][entry.entry_id] await entry_data[DATA_WS_MANAGER].shutdown() await entry_data[DATA_EVENT_LISTENER].shutdown() unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: hass.data[DOMAIN].pop(entry.entry_id) return unload_ok