"""Basisentitaet und Geraetedaten fuer ninstrip.""" from __future__ import annotations from typing import Any from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo, format_mac from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN from .coordinator import NinstripCoordinator def device_name(info: dict[str, Any]) -> str: """Der eigene Name des Geraets, sonst ' '.""" name = str(info.get("name") or "").strip() if name: return name mac4 = format_mac(info["mac"]).replace(":", "")[-4:] return f"{info.get('product') or 'ninstrip'} {mac4}" def strip_model(info: dict[str, Any]) -> str | None: """Kurzbeschreibung des Strips fuer die Geraeteseite, etwa 'ws2805, 60 Pixel'.""" strip = info.get("strip") if not isinstance(strip, dict): return None chip = strip.get("chipset") pixels = strip.get("pixel_count") if chip and pixels: return f"{chip}, {pixels} Pixel" return chip or None class NinstripEntity(CoordinatorEntity[NinstripCoordinator]): """Gemeinsame Basis: eindeutige Kennung aus der MAC, ein Geraet je Strip.""" _attr_has_entity_name = True def __init__(self, coordinator: NinstripCoordinator, key: str) -> None: super().__init__(coordinator) info = coordinator.data.info mac = format_mac(info["mac"]) self._attr_unique_id = f"{mac}_{key}" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, mac)}, connections={(dr.CONNECTION_NETWORK_MAC, mac)}, manufacturer="ninstrip", model=strip_model(info), model_id=info.get("product"), name=device_name(info), sw_version=info["fw_version"], ) class NinstripSacnEntity(NinstripEntity): """Basis fuer Entitaeten, die an den sACN-Einstellungen haengen. Firmware von vor sACN antwortet ohne sacn-Block. Die Entitaeten entstehen trotzdem - so werden sie nach einem Update beim naechsten Abfragen lebendig, ohne die Integration neu zu laden -, melden sich aber bis dahin nicht verfuegbar. Wie ha-ninlight. """ @property def available(self) -> bool: return super().available and self.coordinator.data.sacn is not None @property def sacn(self) -> dict[str, Any]: """Die sACN-Einstellungen; leer, solange das Geraet keine meldet.""" return self.coordinator.data.sacn or {}