Refactor Bluetooth scanners to avoid the need to pass a callback (#105607)
This commit is contained in:
parent
aaccf19013
commit
5dbd0dede1
15 changed files with 30 additions and 68 deletions
|
@ -106,6 +106,7 @@ __all__ = [
|
|||
"async_scanner_by_source",
|
||||
"async_scanner_count",
|
||||
"async_scanner_devices_by_address",
|
||||
"async_get_advertisement_callback",
|
||||
"BaseHaScanner",
|
||||
"HomeAssistantRemoteScanner",
|
||||
"BluetoothCallbackMatcher",
|
||||
|
@ -287,9 +288,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
|
||||
passive = entry.options.get(CONF_PASSIVE)
|
||||
mode = BluetoothScanningMode.PASSIVE if passive else BluetoothScanningMode.ACTIVE
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
manager: HomeAssistantBluetoothManager = hass.data[DATA_MANAGER]
|
||||
scanner = HaScanner(mode, adapter, address, new_info_callback)
|
||||
scanner = HaScanner(mode, adapter, address)
|
||||
try:
|
||||
scanner.async_setup()
|
||||
except RuntimeError as err:
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
"bluetooth-auto-recovery==1.2.3",
|
||||
"bluetooth-data-tools==1.17.0",
|
||||
"dbus-fast==2.21.0",
|
||||
"habluetooth==0.11.1"
|
||||
"habluetooth==1.0.0"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ from aioesphomeapi import APIClient, BluetoothProxyFeature
|
|||
|
||||
from homeassistant.components.bluetooth import (
|
||||
HaBluetoothConnector,
|
||||
async_get_advertisement_callback,
|
||||
async_register_scanner,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -63,7 +62,6 @@ async def async_connect_scanner(
|
|||
"""Connect scanner."""
|
||||
assert entry.unique_id is not None
|
||||
source = str(entry.unique_id)
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
device_info = entry_data.device_info
|
||||
assert device_info is not None
|
||||
feature_flags = device_info.bluetooth_proxy_feature_flags_compat(
|
||||
|
@ -98,9 +96,7 @@ async def async_connect_scanner(
|
|||
partial(_async_can_connect, entry_data, bluetooth_device, source)
|
||||
),
|
||||
)
|
||||
scanner = ESPHomeScanner(
|
||||
source, entry.title, new_info_callback, connector, connectable
|
||||
)
|
||||
scanner = ESPHomeScanner(source, entry.title, connector, connectable)
|
||||
client_data.scanner = scanner
|
||||
coros: list[Coroutine[Any, Any, CALLBACK_TYPE]] = []
|
||||
# These calls all return a callback that can be used to unsubscribe
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
"""Bluetooth support for Ruuvi Gateway."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
import logging
|
||||
import time
|
||||
|
||||
from home_assistant_bluetooth import BluetoothServiceInfoBleak
|
||||
|
||||
from homeassistant.components.bluetooth import (
|
||||
FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS,
|
||||
MONOTONIC_TIME,
|
||||
BaseHaRemoteScanner,
|
||||
async_get_advertisement_callback,
|
||||
async_register_scanner,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -29,7 +25,6 @@ class RuuviGatewayScanner(BaseHaRemoteScanner):
|
|||
self,
|
||||
scanner_id: str,
|
||||
name: str,
|
||||
new_info_callback: Callable[[BluetoothServiceInfoBleak], None],
|
||||
*,
|
||||
coordinator: RuuviGatewayUpdateCoordinator,
|
||||
) -> None:
|
||||
|
@ -37,7 +32,6 @@ class RuuviGatewayScanner(BaseHaRemoteScanner):
|
|||
super().__init__(
|
||||
scanner_id,
|
||||
name,
|
||||
new_info_callback,
|
||||
connector=None,
|
||||
connectable=False,
|
||||
)
|
||||
|
@ -87,7 +81,6 @@ def async_connect_scanner(
|
|||
scanner = RuuviGatewayScanner(
|
||||
scanner_id=source,
|
||||
name=entry.title,
|
||||
new_info_callback=async_get_advertisement_callback(hass),
|
||||
coordinator=coordinator,
|
||||
)
|
||||
unload_callbacks = [
|
||||
|
|
|
@ -14,7 +14,6 @@ from aioshelly.ble.const import (
|
|||
|
||||
from homeassistant.components.bluetooth import (
|
||||
HaBluetoothConnector,
|
||||
async_get_advertisement_callback,
|
||||
async_register_scanner,
|
||||
)
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback as hass_callback
|
||||
|
@ -36,14 +35,13 @@ async def async_connect_scanner(
|
|||
device = coordinator.device
|
||||
entry = coordinator.entry
|
||||
source = format_mac(coordinator.mac).upper()
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
connector = HaBluetoothConnector(
|
||||
# no active connections to shelly yet
|
||||
client=None, # type: ignore[arg-type]
|
||||
source=source,
|
||||
can_connect=lambda: False,
|
||||
)
|
||||
scanner = ShellyBLEScanner(source, entry.title, new_info_callback, connector, False)
|
||||
scanner = ShellyBLEScanner(source, entry.title, connector, False)
|
||||
unload_callbacks = [
|
||||
async_register_scanner(hass, scanner, False),
|
||||
scanner.async_setup(),
|
||||
|
|
|
@ -23,7 +23,7 @@ dbus-fast==2.21.0
|
|||
fnv-hash-fast==0.5.0
|
||||
ha-av==10.1.1
|
||||
ha-ffmpeg==3.1.0
|
||||
habluetooth==0.11.1
|
||||
habluetooth==1.0.0
|
||||
hass-nabucasa==0.74.0
|
||||
hassil==1.5.1
|
||||
home-assistant-bluetooth==1.11.0
|
||||
|
|
|
@ -984,7 +984,7 @@ ha-philipsjs==3.1.1
|
|||
habitipy==0.2.0
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
habluetooth==0.11.1
|
||||
habluetooth==1.0.0
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.74.0
|
||||
|
|
|
@ -783,7 +783,7 @@ ha-philipsjs==3.1.1
|
|||
habitipy==0.2.0
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
habluetooth==0.11.1
|
||||
habluetooth==1.0.0
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.74.0
|
||||
|
|
|
@ -40,6 +40,14 @@ async def test_monotonic_time() -> None:
|
|||
assert MONOTONIC_TIME() == pytest.approx(time.monotonic(), abs=0.1)
|
||||
|
||||
|
||||
async def test_async_get_advertisement_callback(
|
||||
hass: HomeAssistant, enable_bluetooth: None
|
||||
) -> None:
|
||||
"""Test getting advertisement callback."""
|
||||
callback = bluetooth.async_get_advertisement_callback(hass)
|
||||
assert callback is not None
|
||||
|
||||
|
||||
async def test_async_scanner_devices_by_address_connectable(
|
||||
hass: HomeAssistant, enable_bluetooth: None
|
||||
) -> None:
|
||||
|
@ -63,13 +71,10 @@ async def test_async_scanner_devices_by_address_connectable(
|
|||
MONOTONIC_TIME(),
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeInjectableScanner(
|
||||
"esp32", "esp32", new_info_callback, connector, False
|
||||
)
|
||||
scanner = FakeInjectableScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
switchbot_device = generate_ble_device(
|
||||
|
|
|
@ -111,11 +111,10 @@ async def test_remote_scanner(
|
|||
rssi=-100,
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, True)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, True)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
@ -178,11 +177,10 @@ async def test_remote_scanner_expires_connectable(
|
|||
rssi=-100,
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, True)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, True)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
@ -233,11 +231,10 @@ async def test_remote_scanner_expires_non_connectable(
|
|||
rssi=-100,
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, False)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
@ -308,11 +305,10 @@ async def test_base_scanner_connecting_behavior(
|
|||
rssi=-100,
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, False)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
@ -366,7 +362,6 @@ async def test_restore_history_remote_adapter(
|
|||
scanner = BaseHaRemoteScanner(
|
||||
"atom-bluetooth-proxy-ceaac4",
|
||||
"atom-bluetooth-proxy-ceaac4",
|
||||
lambda adv: None,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -381,7 +376,6 @@ async def test_restore_history_remote_adapter(
|
|||
scanner = BaseHaRemoteScanner(
|
||||
"atom-bluetooth-proxy-ceaac4",
|
||||
"atom-bluetooth-proxy-ceaac4",
|
||||
lambda adv: None,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -413,11 +407,10 @@ async def test_device_with_ten_minute_advertising_interval(
|
|||
rssi=-100,
|
||||
)
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, False)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
@ -505,11 +498,10 @@ async def test_scanner_stops_responding(
|
|||
"""Test we mark a scanner are not scanning when it stops responding."""
|
||||
manager = _get_manager()
|
||||
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, False)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
|
|
@ -454,11 +454,10 @@ async def test_diagnostics_remote_adapter(
|
|||
|
||||
assert await hass.config_entries.async_setup(entry1.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
new_info_callback = manager.scanner_adv_received
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
scanner = FakeScanner("esp32", "esp32", new_info_callback, connector, False)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, False)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ from homeassistant.components.bluetooth import (
|
|||
BluetoothServiceInfoBleak,
|
||||
HaBluetoothConnector,
|
||||
async_ble_device_from_address,
|
||||
async_get_advertisement_callback,
|
||||
async_get_fallback_availability_interval,
|
||||
async_get_learned_advertising_interval,
|
||||
async_scanner_count,
|
||||
|
@ -720,14 +719,12 @@ async def test_goes_unavailable_connectable_only_and_recovers(
|
|||
MONOTONIC_TIME(),
|
||||
)
|
||||
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
connectable_scanner = FakeScanner(
|
||||
"connectable",
|
||||
"connectable",
|
||||
new_info_callback,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -750,7 +747,6 @@ async def test_goes_unavailable_connectable_only_and_recovers(
|
|||
not_connectable_scanner = FakeScanner(
|
||||
"not_connectable",
|
||||
"not_connectable",
|
||||
new_info_callback,
|
||||
connector,
|
||||
False,
|
||||
)
|
||||
|
@ -800,7 +796,6 @@ async def test_goes_unavailable_connectable_only_and_recovers(
|
|||
connectable_scanner_2 = FakeScanner(
|
||||
"connectable",
|
||||
"connectable",
|
||||
new_info_callback,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -896,14 +891,12 @@ async def test_goes_unavailable_dismisses_discovery_and_makes_discoverable(
|
|||
self._discovered_device_timestamps.clear()
|
||||
self._previous_service_info.clear()
|
||||
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
connector = (
|
||||
HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False),
|
||||
)
|
||||
non_connectable_scanner = FakeScanner(
|
||||
"connectable",
|
||||
"connectable",
|
||||
new_info_callback,
|
||||
connector,
|
||||
False,
|
||||
)
|
||||
|
|
|
@ -184,7 +184,6 @@ async def test_wrapped_bleak_client_set_disconnected_callback_after_connected(
|
|||
scanner = FakeScanner(
|
||||
"esp32_has_connection_slot",
|
||||
"esp32_has_connection_slot",
|
||||
lambda info: None,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -291,7 +290,7 @@ async def test_ble_device_with_proxy_client_out_of_connections(
|
|||
return None
|
||||
|
||||
connector = HaBluetoothConnector(MockBleakClient, "esp32", lambda: False)
|
||||
scanner = FakeScanner("esp32", "esp32", lambda info: None, connector, True)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, True)
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
inject_advertisement_with_source(
|
||||
hass, switchbot_proxy_device_no_connection_slot, switchbot_adv, "esp32"
|
||||
|
@ -356,7 +355,7 @@ async def test_ble_device_with_proxy_clear_cache(
|
|||
return None
|
||||
|
||||
connector = HaBluetoothConnector(MockBleakClient, "esp32", lambda: True)
|
||||
scanner = FakeScanner("esp32", "esp32", lambda info: None, connector, True)
|
||||
scanner = FakeScanner("esp32", "esp32", connector, True)
|
||||
cancel = manager.async_register_scanner(scanner, True)
|
||||
inject_advertisement_with_source(
|
||||
hass, switchbot_proxy_device_with_connection_slot, switchbot_adv, "esp32"
|
||||
|
@ -464,7 +463,6 @@ async def test_ble_device_with_proxy_client_out_of_connections_uses_best_availab
|
|||
scanner = FakeScanner(
|
||||
"esp32_has_connection_slot",
|
||||
"esp32_has_connection_slot",
|
||||
lambda info: None,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
@ -577,7 +575,6 @@ async def test_ble_device_with_proxy_client_out_of_connections_uses_best_availab
|
|||
scanner = FakeScanner(
|
||||
"esp32_has_connection_slot",
|
||||
"esp32_has_connection_slot",
|
||||
lambda info: None,
|
||||
connector,
|
||||
True,
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Tests for the Bluetooth integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from contextlib import contextmanager
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -18,10 +17,8 @@ import pytest
|
|||
from homeassistant.components.bluetooth import (
|
||||
MONOTONIC_TIME,
|
||||
BaseHaRemoteScanner,
|
||||
BluetoothServiceInfoBleak,
|
||||
HaBluetoothConnector,
|
||||
HomeAssistantBluetoothManager,
|
||||
async_get_advertisement_callback,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
|
@ -43,12 +40,11 @@ class FakeScanner(BaseHaRemoteScanner):
|
|||
self,
|
||||
scanner_id: str,
|
||||
name: str,
|
||||
new_info_callback: Callable[[BluetoothServiceInfoBleak], None],
|
||||
connector: None,
|
||||
connectable: bool,
|
||||
) -> None:
|
||||
"""Initialize the scanner."""
|
||||
super().__init__(scanner_id, name, new_info_callback, connector, connectable)
|
||||
super().__init__(scanner_id, name, connector, connectable)
|
||||
self._details: dict[str, str | HaBluetoothConnector] = {}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
@ -182,13 +178,8 @@ def _generate_scanners_with_fake_devices(hass):
|
|||
)
|
||||
hci1_device_advs[device.address] = (device, adv_data)
|
||||
|
||||
new_info_callback = async_get_advertisement_callback(hass)
|
||||
scanner_hci0 = FakeScanner(
|
||||
"00:00:00:00:00:01", "hci0", new_info_callback, None, True
|
||||
)
|
||||
scanner_hci1 = FakeScanner(
|
||||
"00:00:00:00:00:02", "hci1", new_info_callback, None, True
|
||||
)
|
||||
scanner_hci0 = FakeScanner("00:00:00:00:00:01", "hci0", None, True)
|
||||
scanner_hci1 = FakeScanner("00:00:00:00:00:02", "hci1", None, True)
|
||||
|
||||
for device, adv_data in hci0_device_advs.values():
|
||||
scanner_hci0.inject_advertisement(device, adv_data)
|
||||
|
|
|
@ -43,9 +43,7 @@ async def client_data_fixture(
|
|||
),
|
||||
api_version=APIVersion(1, 9),
|
||||
title=ESP_NAME,
|
||||
scanner=ESPHomeScanner(
|
||||
ESP_MAC_ADDRESS, ESP_NAME, lambda info: None, connector, True
|
||||
),
|
||||
scanner=ESPHomeScanner(ESP_MAC_ADDRESS, ESP_NAME, connector, True),
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue