|
10 | 10 | from typing import TYPE_CHECKING, Any, Final
|
11 | 11 |
|
12 | 12 | from bleak.backends.scanner import AdvertisementDataCallback
|
13 |
| -from bleak_retry_connector import NO_RSSI_VALUE, BleakSlotManager |
| 13 | +from bleak_retry_connector import ( |
| 14 | + NO_RSSI_VALUE, |
| 15 | + AllocationChangeEvent, |
| 16 | + Allocations, |
| 17 | + BleakSlotManager, |
| 18 | +) |
14 | 19 | from bluetooth_adapters import (
|
15 | 20 | ADAPTER_ADDRESS,
|
16 | 21 | ADAPTER_PASSIVE_SCAN,
|
@@ -99,8 +104,10 @@ class BluetoothManager:
|
99 | 104 | "_adapters",
|
100 | 105 | "_advertisement_tracker",
|
101 | 106 | "_all_history",
|
| 107 | + "_allocations_callbacks", |
102 | 108 | "_bleak_callbacks",
|
103 | 109 | "_bluetooth_adapters",
|
| 110 | + "_cancel_allocation_callbacks", |
104 | 111 | "_cancel_unavailable_tracking",
|
105 | 112 | "_connectable_history",
|
106 | 113 | "_connectable_scanners",
|
@@ -146,12 +153,18 @@ def __init__(
|
146 | 153 | self._sources: dict[str, BaseHaScanner] = {}
|
147 | 154 | self._bluetooth_adapters = bluetooth_adapters
|
148 | 155 | self.slot_manager = slot_manager
|
| 156 | + self._cancel_allocation_callbacks = ( |
| 157 | + self.slot_manager.register_allocation_callback( |
| 158 | + self._async_slot_manager_changed |
| 159 | + ) |
| 160 | + ) |
149 | 161 | self._debug = _LOGGER.isEnabledFor(logging.DEBUG)
|
150 | 162 | self.shutdown = False
|
151 | 163 | self._loop: asyncio.AbstractEventLoop | None = None
|
152 | 164 | self._adapter_refresh_future: asyncio.Future[None] | None = None
|
153 | 165 | self._recovery_lock: asyncio.Lock = asyncio.Lock()
|
154 | 166 | self._disappeared_callbacks: set[Callable[[str], None]] = set()
|
| 167 | + self._allocations_callbacks: set[Callable[[Allocations], None]] = set() |
155 | 168 |
|
156 | 169 | @property
|
157 | 170 | def supports_passive_scan(self) -> bool:
|
@@ -203,13 +216,7 @@ def async_register_disappeared_callback(
|
203 | 216 | ) -> CALLBACK_TYPE:
|
204 | 217 | """Register a callback to be called when an address disappears."""
|
205 | 218 | self._disappeared_callbacks.add(callback)
|
206 |
| - return partial(self._async_remove_disappeared_callback, callback) |
207 |
| - |
208 |
| - def _async_remove_disappeared_callback( |
209 |
| - self, callback: Callable[[str], None] |
210 |
| - ) -> None: |
211 |
| - """Remove a disappeared callback.""" |
212 |
| - self._disappeared_callbacks.discard(callback) |
| 219 | + return partial(self._disappeared_callbacks.discard, callback) |
213 | 220 |
|
214 | 221 | async def _async_refresh_adapters(self) -> None:
|
215 | 222 | """Refresh the adapters."""
|
@@ -283,6 +290,7 @@ def async_stop(self) -> None:
|
283 | 290 | self._cancel_unavailable_tracking.cancel()
|
284 | 291 | self._cancel_unavailable_tracking = None
|
285 | 292 | uninstall_multiple_bleak_catcher()
|
| 293 | + self._cancel_allocation_callbacks() |
286 | 294 |
|
287 | 295 | def async_scanner_devices_by_address(
|
288 | 296 | self, address: str, connectable: bool
|
@@ -749,3 +757,24 @@ def async_set_fallback_availability_interval(
|
749 | 757 | ) -> None:
|
750 | 758 | """Override the fallback availability timeout for a MAC address."""
|
751 | 759 | self._fallback_intervals[address] = interval
|
| 760 | + |
| 761 | + def _async_slot_manager_changed(self, event: AllocationChangeEvent) -> None: |
| 762 | + """Handle slot manager changes.""" |
| 763 | + self.async_on_allocation_changed( |
| 764 | + self.slot_manager.get_allocations(event.adapter) |
| 765 | + ) |
| 766 | + |
| 767 | + def async_on_allocation_changed(self, allocations: Allocations) -> None: |
| 768 | + """Call allocation callbacks.""" |
| 769 | + for callback_ in self._allocations_callbacks: |
| 770 | + try: |
| 771 | + callback_(allocations) |
| 772 | + except Exception: |
| 773 | + _LOGGER.exception("Error in allocation callback") |
| 774 | + |
| 775 | + def async_register_allocation_callback( |
| 776 | + self, callback: Callable[[str], None] |
| 777 | + ) -> CALLBACK_TYPE: |
| 778 | + """Register a callback to be called when an allocations change.""" |
| 779 | + self._allocations_callbacks.add(callback) |
| 780 | + return partial(self._allocations_callbacks.discard, callback) |
0 commit comments