Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Generic Omada API coordinator."""
2 
3 import asyncio
4 from datetime import timedelta
5 import logging
6 
7 from tplink_omada_client import OmadaSiteClient, OmadaSwitchPortDetails
8 from tplink_omada_client.clients import OmadaWirelessClient
9 from tplink_omada_client.devices import OmadaGateway, OmadaListDevice, OmadaSwitch
10 from tplink_omada_client.exceptions import OmadaClientException
11 
12 from homeassistant.core import HomeAssistant
13 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
14 
15 _LOGGER = logging.getLogger(__name__)
16 
17 POLL_SWITCH_PORT = 300
18 POLL_GATEWAY = 300
19 POLL_CLIENTS = 300
20 POLL_DEVICES = 300
21 
22 
23 class OmadaCoordinator[_T](DataUpdateCoordinator[dict[str, _T]]):
24  """Coordinator for synchronizing bulk Omada data."""
25 
26  def __init__(
27  self,
28  hass: HomeAssistant,
29  omada_client: OmadaSiteClient,
30  name: str,
31  poll_delay: int | None = 300,
32  ) -> None:
33  """Initialize my coordinator."""
34  super().__init__(
35  hass,
36  _LOGGER,
37  name=f"Omada API Data - {name}",
38  update_interval=timedelta(seconds=poll_delay) if poll_delay else None,
39  )
40  self.omada_clientomada_client = omada_client
41 
42  async def _async_update_data(self) -> dict[str, _T]:
43  """Fetch data from API endpoint."""
44  try:
45  async with asyncio.timeout(10):
46  return await self.poll_updatepoll_update()
47  except OmadaClientException as err:
48  raise UpdateFailed(f"Error communicating with API: {err}") from err
49 
50  async def poll_update(self) -> dict[str, _T]:
51  """Poll the current data from the controller."""
52  raise NotImplementedError("Update method not implemented")
53 
54 
55 class OmadaSwitchPortCoordinator(OmadaCoordinator[OmadaSwitchPortDetails]):
56  """Coordinator for getting details about ports on a switch."""
57 
58  def __init__(
59  self,
60  hass: HomeAssistant,
61  omada_client: OmadaSiteClient,
62  network_switch: OmadaSwitch,
63  ) -> None:
64  """Initialize my coordinator."""
65  super().__init__(
66  hass, omada_client, f"{network_switch.name} Ports", POLL_SWITCH_PORT
67  )
68  self._network_switch_network_switch = network_switch
69 
70  async def poll_update(self) -> dict[str, OmadaSwitchPortDetails]:
71  """Poll a switch's current state."""
72  ports = await self.omada_clientomada_client.get_switch_ports(self._network_switch_network_switch)
73  return {p.port_id: p for p in ports}
74 
75 
77  """Coordinator for getting details about the site's gateway."""
78 
79  def __init__(
80  self,
81  hass: HomeAssistant,
82  omada_client: OmadaSiteClient,
83  mac: str,
84  ) -> None:
85  """Initialize my coordinator."""
86  super().__init__(hass, omada_client, "Gateway", POLL_GATEWAY)
87  self.macmac = mac
88 
89  async def poll_update(self) -> dict[str, OmadaGateway]:
90  """Poll a the gateway's current state."""
91  gateway = await self.omada_clientomada_client.get_gateway(self.macmac)
92  return {self.macmac: gateway}
93 
94 
95 class OmadaDevicesCoordinator(OmadaCoordinator[OmadaListDevice]):
96  """Coordinator for generic device lists from the controller."""
97 
98  def __init__(
99  self,
100  hass: HomeAssistant,
101  omada_client: OmadaSiteClient,
102  ) -> None:
103  """Initialize my coordinator."""
104  super().__init__(hass, omada_client, "DeviceList", POLL_CLIENTS)
105 
106  async def poll_update(self) -> dict[str, OmadaListDevice]:
107  """Poll the site's current registered Omada devices."""
108  return {d.mac: d for d in await self.omada_clientomada_client.get_devices()}
109 
110 
111 class OmadaClientsCoordinator(OmadaCoordinator[OmadaWirelessClient]):
112  """Coordinator for getting details about the site's connected clients."""
113 
114  def __init__(self, hass: HomeAssistant, omada_client: OmadaSiteClient) -> None:
115  """Initialize my coordinator."""
116  super().__init__(hass, omada_client, "ClientsList", POLL_CLIENTS)
117 
118  async def poll_update(self) -> dict[str, OmadaWirelessClient]:
119  """Poll the site's current active wi-fi clients."""
120  return {
121  c.mac: c
122  async for c in self.omada_clientomada_client.get_connected_clients()
123  if isinstance(c, OmadaWirelessClient)
124  }