"""Базовая сущность fglair: DeviceInfo, значения из координатора.""" from __future__ import annotations from typing import Optional from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity from pyfglair import Prop, Value from .const import CONF_DSN, CONF_MODEL, CONF_NAME, DOMAIN from .coordinator import FglairCoordinator class FglairEntity(CoordinatorEntity[FglairCoordinator]): """Общий базис: unique_id = _, device_info — один прибор.""" _attr_has_entity_name = True def __init__( self, coordinator: FglairCoordinator, unique_suffix: str, translation_key: str, ) -> None: super().__init__(coordinator) data = coordinator.client.data dsn = data[CONF_DSN] self._attr_unique_id = f"{dsn}_{unique_suffix}" self._attr_translation_key = translation_key self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, dsn)}, name=data.get(CONF_NAME) or dsn, manufacturer="Fujitsu General", model=data.get(CONF_MODEL) or None, ) @property def available(self) -> bool: return self.coordinator.data.available and super().available def value(self, prop: Prop) -> Optional[Value]: return self.coordinator.data.values.get(prop) def raw_value(self, prop: Prop) -> Optional[int]: value = self.value(prop) return value.int_value if value is not None else None def display_value(self, prop: Prop) -> Optional[int]: """Значение свойства в единицах отображения (с ручной конверсией).""" raw = self.raw_value(prop) if raw is None: return None return self.coordinator.conversions.to_display(prop, raw) def capabilities(self) -> Optional[int]: return self.raw_value(Prop.DEVICE_CAPABILITIES) def capability(self, bit: int) -> Optional[bool]: caps = self.capabilities() if caps is None: return None return bool(caps & (1 << bit)) def supports_capability(self, bit: Optional[int]) -> bool: """None — считать поддержанным (capabilities ещё не пришли).""" if bit is None: return True cap = self.capability(bit) return True if cap is None else cap