Home Assistant Unofficial Reference 2024.12.1
bridge.py
Go to the documentation of this file.
1 """Code to handle a Dynalite bridge."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from types import MappingProxyType
7 from typing import Any
8 
9 from dynalite_devices_lib.dynalite_devices import (
10  CONF_AREA as dyn_CONF_AREA,
11  CONF_PRESET as dyn_CONF_PRESET,
12  NOTIFICATION_PACKET,
13  NOTIFICATION_PRESET,
14  DynaliteBaseDevice,
15  DynaliteDevices,
16  DynaliteNotification,
17 )
18 
19 from homeassistant.const import CONF_HOST
20 from homeassistant.core import HomeAssistant, callback
21 from homeassistant.helpers.dispatcher import async_dispatcher_send
22 
23 from .const import ATTR_AREA, ATTR_HOST, ATTR_PACKET, ATTR_PRESET, LOGGER, PLATFORMS
24 from .convert_config import convert_config
25 
26 
28  """Manages a single Dynalite bridge."""
29 
30  def __init__(self, hass: HomeAssistant, config: dict[str, Any]) -> None:
31  """Initialize the system based on host parameter."""
32  self.hasshass = hass
33  self.async_add_devices: dict[str, Callable] = {}
34  self.waiting_devices: dict[str, list[str]] = {}
35  self.hosthost = config[CONF_HOST]
36  # Configure the dynalite devices
37  self.dynalite_devicesdynalite_devices = DynaliteDevices(
38  new_device_func=self.add_devices_when_registeredadd_devices_when_registered,
39  update_device_func=self.update_deviceupdate_device,
40  notification_func=self.handle_notificationhandle_notification,
41  )
42  self.dynalite_devicesdynalite_devices.configure(config)
43 
44  async def async_setup(self) -> bool:
45  """Set up a Dynalite bridge."""
46  # Configure the dynalite devices
47  LOGGER.debug("Setting up bridge - host %s", self.hosthost)
48  return await self.dynalite_devicesdynalite_devices.async_setup()
49 
50  def reload_config(self, config: MappingProxyType[str, Any]) -> None:
51  """Reconfigure a bridge when config changes."""
52  LOGGER.debug("Reloading bridge - host %s, config %s", self.hosthost, config)
53  self.dynalite_devicesdynalite_devices.configure(convert_config(config))
54 
55  def update_signal(self, device: DynaliteBaseDevice | None = None) -> str:
56  """Create signal to use to trigger entity update."""
57  if device:
58  signal = f"dynalite-update-{self.host}-{device.unique_id}"
59  else:
60  signal = f"dynalite-update-{self.host}"
61  return signal
62 
63  @callback
64  def update_device(self, device: DynaliteBaseDevice | None = None) -> None:
65  """Call when a device or all devices should be updated."""
66  if not device:
67  # This is used to signal connection or disconnection, so all devices may become available or not.
68  log_string = (
69  "Connected" if self.dynalite_devicesdynalite_devices.connected else "Disconnected"
70  )
71  LOGGER.debug("%s to dynalite host", log_string)
72  async_dispatcher_send(self.hasshass, self.update_signalupdate_signal())
73  else:
74  async_dispatcher_send(self.hasshass, self.update_signalupdate_signal(device))
75 
76  @callback
77  def handle_notification(self, notification: DynaliteNotification) -> None:
78  """Handle a notification from the platform and issue events."""
79  if notification.notification == NOTIFICATION_PACKET:
80  self.hasshass.bus.async_fire(
81  "dynalite_packet",
82  {
83  ATTR_HOST: self.hosthost,
84  ATTR_PACKET: notification.data[NOTIFICATION_PACKET],
85  },
86  )
87  if notification.notification == NOTIFICATION_PRESET:
88  self.hasshass.bus.async_fire(
89  "dynalite_preset",
90  {
91  ATTR_HOST: self.hosthost,
92  ATTR_AREA: notification.data[dyn_CONF_AREA],
93  ATTR_PRESET: notification.data[dyn_CONF_PRESET],
94  },
95  )
96 
97  @callback
98  def register_add_devices(self, platform: str, async_add_devices: Callable) -> None:
99  """Add an async_add_entities for a category."""
100  self.async_add_devices[platform] = async_add_devices
101  if platform in self.waiting_devices:
102  self.async_add_devices[platform](self.waiting_devices[platform])
103 
104  def add_devices_when_registered(self, devices: list[DynaliteBaseDevice]) -> None:
105  """Add the devices to HA if the add devices callback was registered, otherwise queue until it is."""
106  for platform in PLATFORMS:
107  platform_devices = [
108  device for device in devices if device.category == platform
109  ]
110  if platform in self.async_add_devices:
111  self.async_add_devices[platform](platform_devices)
112  else: # handle it later when it is registered
113  if platform not in self.waiting_devices:
114  self.waiting_devices[platform] = []
115  self.waiting_devices[platform].extend(platform_devices)
None add_devices_when_registered(self, list[DynaliteBaseDevice] devices)
Definition: bridge.py:104
None update_device(self, DynaliteBaseDevice|None device=None)
Definition: bridge.py:64
None handle_notification(self, DynaliteNotification notification)
Definition: bridge.py:77
None reload_config(self, MappingProxyType[str, Any] config)
Definition: bridge.py:50
str update_signal(self, DynaliteBaseDevice|None device=None)
Definition: bridge.py:55
None register_add_devices(self, str platform, Callable async_add_devices)
Definition: bridge.py:98
None __init__(self, HomeAssistant hass, dict[str, Any] config)
Definition: bridge.py:30
dict[str, Any] convert_config(dict[str, Any]|MappingProxyType[str, Any] config)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193