From 89959e7cda75400144ef1d3ec7c11ba651b8d085 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 11 Nov 2022 07:59:06 -0600 Subject: [PATCH] Reduce complexity of bluetooth scanners for local adapters (#81940) This is a small refactor to align the bluetooth scanner class to the same design used in the esphome scanner to pass the callback for new service infos in the constructor. The original thinking was that multiple callbacks would be needed to send the service infos to different paths, however with the creation of a central manager, this designed turned out to not be needed and can be simplified --- .../components/bluetooth/__init__.py | 5 +- homeassistant/components/bluetooth/scanner.py | 47 +++++++------------ 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index 8590d1ad90a..23165e2bc09 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -425,15 +425,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: passive = entry.options.get(CONF_PASSIVE) mode = BluetoothScanningMode.PASSIVE if passive else BluetoothScanningMode.ACTIVE - scanner = HaScanner(hass, mode, adapter, address) + new_info_callback = async_get_advertisement_callback(hass) + scanner = HaScanner(hass, mode, adapter, address, new_info_callback) try: scanner.async_setup() except RuntimeError as err: raise ConfigEntryNotReady( f"{adapter_human_name(adapter, address)}: {err}" ) from err - info_callback = async_get_advertisement_callback(hass) - entry.async_on_unload(scanner.async_register_callback(info_callback)) try: await scanner.async_start() except ScannerStartError as err: diff --git a/homeassistant/components/bluetooth/scanner.py b/homeassistant/components/bluetooth/scanner.py index 43c4706474a..c05894d3b44 100644 --- a/homeassistant/components/bluetooth/scanner.py +++ b/homeassistant/components/bluetooth/scanner.py @@ -125,6 +125,7 @@ class HaScanner(BaseHaScanner): mode: BluetoothScanningMode, adapter: str, address: str, + new_info_callback: Callable[[BluetoothServiceInfoBleak], None], ) -> None: """Init bluetooth discovery.""" source = address if address != DEFAULT_ADDRESS else adapter or SOURCE_LOCAL @@ -135,7 +136,7 @@ class HaScanner(BaseHaScanner): self._cancel_watchdog: CALLBACK_TYPE | None = None self._last_detection = 0.0 self._start_time = 0.0 - self._callbacks: list[Callable[[BluetoothServiceInfoBleak], None]] = [] + self._new_info_callback = new_info_callback self.name = adapter_human_name(adapter, address) @property @@ -168,22 +169,6 @@ class HaScanner(BaseHaScanner): "start_time": self._start_time, } - @hass_callback - def async_register_callback( - self, callback: Callable[[BluetoothServiceInfoBleak], None] - ) -> CALLBACK_TYPE: - """Register a callback. - - Currently this is used to feed the callbacks into the - central manager. - """ - - def _remove() -> None: - self._callbacks.remove(callback) - - self._callbacks.append(callback) - return _remove - @hass_callback def _async_detection_callback( self, @@ -206,21 +191,21 @@ class HaScanner(BaseHaScanner): # as the adapter is in a failure # state if all the data is empty. self._last_detection = callback_time - service_info = BluetoothServiceInfoBleak( - name=advertisement_data.local_name or device.name or device.address, - address=device.address, - rssi=advertisement_data.rssi, - manufacturer_data=advertisement_data.manufacturer_data, - service_data=advertisement_data.service_data, - service_uuids=advertisement_data.service_uuids, - source=self.source, - device=device, - advertisement=advertisement_data, - connectable=True, - time=callback_time, + self._new_info_callback( + BluetoothServiceInfoBleak( + name=advertisement_data.local_name or device.name or device.address, + address=device.address, + rssi=advertisement_data.rssi, + manufacturer_data=advertisement_data.manufacturer_data, + service_data=advertisement_data.service_data, + service_uuids=advertisement_data.service_uuids, + source=self.source, + device=device, + advertisement=advertisement_data, + connectable=True, + time=callback_time, + ) ) - for callback in self._callbacks: - callback(service_info) async def async_start(self) -> None: """Start bluetooth scanner."""