Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Provides the DataUpdateCoordinator."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 
8 from gardena_bluetooth.client import Client
9 from gardena_bluetooth.exceptions import (
10  CharacteristicNoAccess,
11  GardenaBluetoothException,
12 )
13 from gardena_bluetooth.parse import Characteristic, CharacteristicType
14 
15 from homeassistant.core import HomeAssistant
16 from homeassistant.exceptions import HomeAssistantError
17 from homeassistant.helpers.device_registry import DeviceInfo
18 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
19 
20 SCAN_INTERVAL = timedelta(seconds=60)
21 LOGGER = logging.getLogger(__name__)
22 
23 
25  """Raised if device can't be found."""
26 
27 
29  """Class to manage fetching data."""
30 
31  def __init__(
32  self,
33  hass: HomeAssistant,
34  logger: logging.Logger,
35  client: Client,
36  characteristics: set[str],
37  device_info: DeviceInfo,
38  address: str,
39  ) -> None:
40  """Initialize global data updater."""
41  super().__init__(
42  hass=hass,
43  logger=logger,
44  name="Gardena Bluetooth Data Update Coordinator",
45  update_interval=SCAN_INTERVAL,
46  )
47  self.addressaddress = address
48  self.datadatadata = {}
49  self.clientclient = client
50  self.characteristicscharacteristics = characteristics
51  self.device_infodevice_info = device_info
52 
53  async def async_shutdown(self) -> None:
54  """Shutdown coordinator and any connection."""
55  await super().async_shutdown()
56  await self.clientclient.disconnect()
57 
58  async def _async_update_data(self) -> dict[str, bytes]:
59  """Poll the device."""
60  uuids: set[str] = {
61  uuid for context in self.async_contextsasync_contexts() for uuid in context
62  }
63  if not uuids:
64  return {}
65 
66  data: dict[str, bytes] = {}
67  for uuid in uuids:
68  try:
69  data[uuid] = await self.clientclient.read_char_raw(uuid)
70  except CharacteristicNoAccess as exception:
71  LOGGER.debug("Unable to get data for %s due to %s", uuid, exception)
72  except (GardenaBluetoothException, DeviceUnavailable) as exception:
73  raise UpdateFailed(
74  f"Unable to update data for {uuid} due to {exception}"
75  ) from exception
76  return data
77 
79  self, char: Characteristic[CharacteristicType]
80  ) -> CharacteristicType | None:
81  """Read cached characteristic."""
82  if data := self.datadatadata.get(char.uuid):
83  return char.decode(data)
84  return None
85 
86  async def write(
87  self, char: Characteristic[CharacteristicType], value: CharacteristicType
88  ) -> None:
89  """Write characteristic to device."""
90  try:
91  await self.clientclient.write_char(char, value)
92  except (GardenaBluetoothException, DeviceUnavailable) as exception:
93  raise HomeAssistantError(
94  f"Unable to write characteristic {char} dur to {exception}"
95  ) from exception
96 
97  self.datadatadata[char.uuid] = char.encode(value)
98  await self.async_refreshasync_refresh()
CharacteristicType|None get_cached(self, Characteristic[CharacteristicType] char)
Definition: coordinator.py:80
None __init__(self, HomeAssistant hass, logging.Logger logger, Client client, set[str] characteristics, DeviceInfo device_info, str address)
Definition: coordinator.py:39
None write(self, Characteristic[CharacteristicType] char, CharacteristicType value)
Definition: coordinator.py:88
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88