Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """SwitchBee integration Coordinator."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Mapping
6 from datetime import timedelta
7 import logging
8 
9 from switchbee.api import CentralUnitPolling, CentralUnitWsRPC
10 from switchbee.api.central_unit import SwitchBeeError
11 from switchbee.device import DeviceType, SwitchBeeBaseDevice
12 
13 from homeassistant.core import HomeAssistant, callback
14 from homeassistant.helpers.device_registry import format_mac
15 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
16 
17 from .const import DOMAIN, SCAN_INTERVAL_SEC
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 
22 class SwitchBeeCoordinator(DataUpdateCoordinator[Mapping[int, SwitchBeeBaseDevice]]):
23  """Class to manage fetching SwitchBee data API."""
24 
25  def __init__(
26  self,
27  hass: HomeAssistant,
28  swb_api: CentralUnitPolling | CentralUnitWsRPC,
29  ) -> None:
30  """Initialize."""
31  self.api: CentralUnitPolling | CentralUnitWsRPC = swb_api
32  self._reconnect_counts_reconnect_counts: int = 0
33  assert self.api.mac is not None
34  self.unique_idunique_id = (
35  self.api.unique_id
36  if self.api.unique_id is not None
37  else format_mac(self.api.mac)
38  )
39  super().__init__(
40  hass,
41  _LOGGER,
42  name=DOMAIN,
43  update_interval=timedelta(seconds=SCAN_INTERVAL_SEC[type(self.api)]),
44  )
45 
46  # Register callback for notification WsRPC
47  if isinstance(self.api, CentralUnitWsRPC):
48  self.api.subscribe_updates(self._async_handle_update_async_handle_update)
49 
50  @callback
51  def _async_handle_update(self, push_data: dict) -> None:
52  """Manually update data and notify listeners."""
53  assert isinstance(self.api, CentralUnitWsRPC)
54  _LOGGER.debug("Received update: %s", push_data)
55  self.async_set_updated_dataasync_set_updated_data(self.api.devices)
56 
57  async def _async_update_data(self) -> Mapping[int, SwitchBeeBaseDevice]:
58  """Update data via library."""
59 
60  if self._reconnect_counts_reconnect_counts != self.api.reconnect_count:
61  self._reconnect_counts_reconnect_counts = self.api.reconnect_count
62  _LOGGER.debug(
63  "Central Unit re-connected again due to invalid token, total %i",
64  self._reconnect_counts_reconnect_counts,
65  )
66 
67  # The devices are loaded once during the config_entry
68  if not self.api.devices:
69  # Try to load the devices from the CU for the first time
70  try:
71  await self.api.fetch_configuration(
72  [
73  DeviceType.Switch,
74  DeviceType.TimedSwitch,
75  DeviceType.GroupSwitch,
76  DeviceType.TimedPowerSwitch,
77  DeviceType.Scenario,
78  DeviceType.Dimmer,
79  DeviceType.Shutter,
80  DeviceType.Somfy,
81  DeviceType.Thermostat,
82  DeviceType.VRFAC,
83  ]
84  )
85  except SwitchBeeError as exp:
86  raise UpdateFailed(
87  f"Error communicating with API: {exp}"
88  ) from SwitchBeeError
89 
90  _LOGGER.debug("Loaded devices")
91 
92  # Get the state of the devices
93  try:
94  await self.api.fetch_states()
95  except SwitchBeeError as exp:
96  raise UpdateFailed(
97  f"Error communicating with API: {exp}"
98  ) from SwitchBeeError
99 
100  return self.api.devices
Mapping[int, SwitchBeeBaseDevice] _async_update_data(self)
Definition: coordinator.py:57
None __init__(self, HomeAssistant hass, CentralUnitPolling|CentralUnitWsRPC swb_api)
Definition: coordinator.py:29