Home Assistant Unofficial Reference 2024.12.1
update_coordinator.py
Go to the documentation of this file.
1 """Update coordinator for the Bluetooth integration."""
2 
3 from __future__ import annotations
4 
5 from abc import ABC, abstractmethod
6 import logging
7 
8 from habluetooth import BluetoothScanningMode
9 
10 from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
11 
12 from .api import (
13  async_address_present,
14  async_last_service_info,
15  async_register_callback,
16  async_track_unavailable,
17 )
18 from .match import BluetoothCallbackMatcher
19 from .models import BluetoothChange, BluetoothServiceInfoBleak
20 
21 
23  """Base class for passive bluetooth coordinator for bluetooth advertisements.
24 
25  The coordinator is responsible for tracking devices.
26  """
27 
28  def __init__(
29  self,
30  hass: HomeAssistant,
31  logger: logging.Logger,
32  address: str,
33  mode: BluetoothScanningMode,
34  connectable: bool,
35  ) -> None:
36  """Initialize the coordinator."""
37  self.hasshass = hass
38  self.loggerlogger = logger
39  self.addressaddress = address
40  self.connectableconnectable = connectable
41  self._on_stop: list[CALLBACK_TYPE] = []
42  self.modemode = mode
43  self._last_unavailable_time_last_unavailable_time = 0.0
44  self._last_name_last_name = address
45  # Subclasses are responsible for setting _available to True
46  # when the abstractmethod _async_handle_bluetooth_event is called.
47  self._available_available = async_address_present(hass, address, connectable)
48 
49  @callback
50  def async_start(self) -> CALLBACK_TYPE:
51  """Start the data updater."""
52  self._async_start_async_start()
53  return self._async_stop_async_stop
54 
55  @callback
56  @abstractmethod
58  self,
59  service_info: BluetoothServiceInfoBleak,
60  change: BluetoothChange,
61  ) -> None:
62  """Handle a bluetooth event."""
63 
64  @property
65  def name(self) -> str:
66  """Return last known name of the device."""
67  if service_info := async_last_service_info(
68  self.hasshass, self.addressaddress, self.connectableconnectable
69  ):
70  return service_info.name
71  return self._last_name_last_name
72 
73  @property
74  def last_seen(self) -> float:
75  """Return the last time the device was seen."""
76  # If the device is unavailable it will not have a service
77  # info and fall through below.
78  if service_info := async_last_service_info(
79  self.hasshass, self.addressaddress, self.connectableconnectable
80  ):
81  return service_info.time
82  # This is the time from the last advertisement that
83  # was set when the unavailable callback was called.
84  return self._last_unavailable_time_last_unavailable_time
85 
86  @callback
87  def _async_start(self) -> None:
88  """Start the callbacks."""
89  self._on_stop.append(
91  self.hasshass,
92  self._async_handle_bluetooth_event_async_handle_bluetooth_event,
94  address=self.addressaddress, connectable=self.connectableconnectable
95  ),
96  self.modemode,
97  )
98  )
99  self._on_stop.append(
101  self.hasshass,
102  self._async_handle_unavailable_async_handle_unavailable,
103  self.addressaddress,
104  self.connectableconnectable,
105  )
106  )
107 
108  @callback
109  def _async_stop(self) -> None:
110  """Stop the callbacks."""
111  for unsub in self._on_stop:
112  unsub()
113  self._on_stop.clear()
114 
115  @callback
117  self, service_info: BluetoothServiceInfoBleak
118  ) -> None:
119  """Handle the device going unavailable."""
120  self._last_unavailable_time_last_unavailable_time = service_info.time
121  self._last_name_last_name = service_info.name
122  self._available_available = False
None __init__(self, HomeAssistant hass, logging.Logger logger, str address, BluetoothScanningMode mode, bool connectable)
None _async_handle_bluetooth_event(self, BluetoothServiceInfoBleak service_info, BluetoothChange change)
bool async_address_present(HomeAssistant hass, str address, bool connectable=True)
Definition: api.py:104
Callable[[], None] async_register_callback(HomeAssistant hass, BluetoothCallback callback, BluetoothCallbackMatcher|None match_dict, BluetoothScanningMode mode)
Definition: api.py:115
Callable[[], None] async_track_unavailable(HomeAssistant hass, Callable[[BluetoothServiceInfoBleak], None] callback, str address, bool connectable=True)
Definition: api.py:162
BluetoothServiceInfoBleak|None async_last_service_info(HomeAssistant hass, str address, bool connectable=True)
Definition: api.py:80