"""Support for the Dynalite devices.""" from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Callable, Dict, List from .const import CONF_CHANNEL if TYPE_CHECKING: # pragma: no cover from .dynalite_devices import DynaliteDevices class DynaliteBaseDevice(ABC): """Base class for Dynalite devices.""" def __init__(self, area: int, bridge: "DynaliteDevices", hidden: bool) -> None: """Initialize the device.""" self._area = area self._bridge = bridge self._listeners: List[Callable[[DynaliteBaseDevice, bool], None]] = [] self._hidden = hidden @property def area_name(self) -> str: """Return the name of the area.""" return self._bridge.get_area_name(self._area) @property def get_master_area(self) -> str: """Get the master area when combining entities from different Dynet areas to the same area.""" return self._bridge.get_master_area(self._area) @property def hidden(self) -> bool: """Get whether the device should be hidden from the calling platform.""" return self._hidden def add_listener( self, listener: Callable[["DynaliteBaseDevice", bool], None] ) -> None: """Add a listener for changes.""" self._listeners.append(listener) def update_listeners(self, stop_fade: bool = False) -> None: """Update all listeners.""" for listener in self._listeners: listener(self, stop_fade) @abstractmethod def init_level(self, level: float): """Initialize the level.""" class DynaliteChannelBaseDevice(DynaliteBaseDevice): """Representation of a Dynalite Channel as a Home Assistant device.""" def __init__( self, area: int, channel: int, bridge: "DynaliteDevices", hidden: bool ) -> None: """Initialize the device.""" self._channel = channel super().__init__(area, bridge, hidden) @property def available(self) -> bool: """Return if device is available.""" return self._bridge.available(CONF_CHANNEL, self._area, self._channel) @property def name(self) -> str: """Return the name of the device.""" return self._bridge.get_channel_name(self._area, self._channel) @property def unique_id(self) -> str: """Return the ID of this device.""" return "dynalite_area_" + str(self._area) + "_channel_" + str(self._channel) def stop_fade(self) -> None: """Update the listeners if STOP FADE is received.""" self.update_listeners(True) class DynaliteMultiDevice(DynaliteBaseDevice): """Representation of two Dynalite Presets as an on/off switch.""" def __init__( self, num_devices: int, area: int, bridge: "DynaliteDevices", hidden: bool ) -> None: """Initialize the device.""" self._devices: Dict[int, DynaliteBaseDevice] = {} super().__init__(area, bridge, hidden) @property def name(self) -> str: """Return the name of the device.""" return self._bridge.get_multi_name(self._area) def get_device(self, devnum: int) -> DynaliteBaseDevice: """Get one of the devices.""" assert devnum in self._devices return self._devices[devnum] def set_device(self, devnum: int, device: DynaliteBaseDevice) -> None: """Set one of the attached devices.""" self._devices[devnum] = device device.add_listener(self.listener) def listener(self, device: DynaliteBaseDevice, stop_fade: bool) -> None: """Update the device since its internal devices changed.""" # pylint: disable=unused-argument self._bridge.update_device(self)