mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Expose bluetooth address reachability diagnostics API (#172578)
This commit is contained in:
@@ -27,6 +27,7 @@ from bluetooth_data_tools import monotonic_time_coarse as MONOTONIC_TIME
|
||||
from habluetooth import (
|
||||
BaseHaRemoteScanner,
|
||||
BaseHaScanner,
|
||||
BluetoothReachabilityIntent,
|
||||
BluetoothScannerDevice,
|
||||
BluetoothScanningMode,
|
||||
HaBluetoothConnector,
|
||||
@@ -55,6 +56,7 @@ from . import passive_update_processor, websocket_api
|
||||
from .api import (
|
||||
_get_manager,
|
||||
async_address_present,
|
||||
async_address_reachability_diagnostics,
|
||||
async_ble_device_from_address,
|
||||
async_clear_address_from_match_history,
|
||||
async_clear_advertisement_history,
|
||||
@@ -108,12 +110,14 @@ __all__ = [
|
||||
"BluetoothCallback",
|
||||
"BluetoothCallbackMatcher",
|
||||
"BluetoothChange",
|
||||
"BluetoothReachabilityIntent",
|
||||
"BluetoothScannerDevice",
|
||||
"BluetoothScanningMode",
|
||||
"BluetoothServiceInfo",
|
||||
"BluetoothServiceInfoBleak",
|
||||
"HaBluetoothConnector",
|
||||
"async_address_present",
|
||||
"async_address_reachability_diagnostics",
|
||||
"async_ble_device_from_address",
|
||||
"async_clear_address_from_match_history",
|
||||
"async_clear_advertisement_history",
|
||||
|
||||
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING, cast
|
||||
from bleak import BleakScanner
|
||||
from habluetooth import (
|
||||
BaseHaScanner,
|
||||
BluetoothReachabilityIntent,
|
||||
BluetoothScannerDevice,
|
||||
BluetoothScanningMode,
|
||||
HaBleakScannerWrapper,
|
||||
@@ -108,6 +109,14 @@ def async_ble_device_from_address(
|
||||
return _get_manager(hass).async_ble_device_from_address(address, connectable)
|
||||
|
||||
|
||||
@hass_callback
|
||||
def async_address_reachability_diagnostics(
|
||||
hass: HomeAssistant, address: str, intent: BluetoothReachabilityIntent
|
||||
) -> str:
|
||||
"""Return a human readable explanation of why an address may be unreachable."""
|
||||
return _get_manager(hass).async_address_reachability_diagnostics(address, intent)
|
||||
|
||||
|
||||
@hass_callback
|
||||
def async_scanner_devices_by_address(
|
||||
hass: HomeAssistant, address: str, connectable: bool = True
|
||||
|
||||
@@ -10,9 +10,11 @@ from homeassistant.components.bluetooth import (
|
||||
MONOTONIC_TIME,
|
||||
BaseHaRemoteScanner,
|
||||
BluetoothChange,
|
||||
BluetoothReachabilityIntent,
|
||||
BluetoothScanningMode,
|
||||
BluetoothServiceInfo,
|
||||
HaBluetoothConnector,
|
||||
async_address_reachability_diagnostics,
|
||||
async_clear_advertisement_history,
|
||||
async_request_active_scan,
|
||||
async_scanner_by_source,
|
||||
@@ -112,6 +114,57 @@ async def test_async_scanner_devices_by_address_connectable(
|
||||
cancel()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_bluetooth")
|
||||
async def test_async_address_reachability_diagnostics(hass: HomeAssistant) -> None:
|
||||
"""Test the address reachability diagnostics passthrough."""
|
||||
# An address that was never seen reports as unknown.
|
||||
assert "unknown" in async_address_reachability_diagnostics(
|
||||
hass, "44:44:33:11:23:99", BluetoothReachabilityIntent.CONNECTION
|
||||
)
|
||||
|
||||
manager = _get_manager()
|
||||
|
||||
class FakeInjectableScanner(BaseHaRemoteScanner):
|
||||
def inject_advertisement(
|
||||
self, device: BLEDevice, advertisement_data: AdvertisementData
|
||||
) -> None:
|
||||
"""Inject an advertisement."""
|
||||
self._async_on_advertisement(
|
||||
device.address,
|
||||
advertisement_data.rssi,
|
||||
device.name,
|
||||
advertisement_data.service_uuids,
|
||||
advertisement_data.service_data,
|
||||
advertisement_data.manufacturer_data,
|
||||
advertisement_data.tx_power,
|
||||
{"scanner_specific_data": "test"},
|
||||
MONOTONIC_TIME(),
|
||||
)
|
||||
|
||||
connector = HaBluetoothConnector(MockBleakClient, "esp32", lambda: True)
|
||||
scanner = FakeInjectableScanner("esp32", "esp32", connector, True)
|
||||
unsetup = scanner.async_setup()
|
||||
cancel = manager.async_register_scanner(scanner)
|
||||
switchbot_device = generate_ble_device("44:44:33:11:23:45", "wohand", {})
|
||||
switchbot_device_adv = generate_advertisement_data(local_name="wohand", rssi=-80)
|
||||
scanner.inject_advertisement(switchbot_device, switchbot_device_adv)
|
||||
|
||||
connection_diag = async_address_reachability_diagnostics(
|
||||
hass, "44:44:33:11:23:45", BluetoothReachabilityIntent.CONNECTION
|
||||
)
|
||||
assert "in connectable history" in connection_diag
|
||||
assert "esp32" in connection_diag
|
||||
|
||||
# An advertisement intent does not report connectable paths or slots.
|
||||
advertisement_diag = async_address_reachability_diagnostics(
|
||||
hass, "44:44:33:11:23:45", BluetoothReachabilityIntent.PASSIVE_ADVERTISEMENT
|
||||
)
|
||||
assert "advertising" in advertisement_diag
|
||||
|
||||
unsetup()
|
||||
cancel()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_bluetooth")
|
||||
async def test_async_scanner_devices_by_address_non_connectable(
|
||||
hass: HomeAssistant,
|
||||
|
||||
Reference in New Issue
Block a user