Include the source in the bluetooth service info (#75112)

pull/75322/head^2
J. Nick Koston 2022-07-16 11:02:08 -05:00 committed by GitHub
parent 859189421b
commit ecc219fbc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 6 deletions

View File

@ -39,6 +39,8 @@ _LOGGER = logging.getLogger(__name__)
MAX_REMEMBER_ADDRESSES: Final = 2048
SOURCE_LOCAL: Final = "local"
class BluetoothCallbackMatcherOptional(TypedDict, total=False):
"""Matcher for the bluetooth integration for callback optional fields."""
@ -266,7 +268,7 @@ class BluetoothManager:
):
if service_info is None:
service_info = BluetoothServiceInfo.from_advertisement(
device, advertisement_data
device, advertisement_data, SOURCE_LOCAL
)
try:
callback(service_info, BluetoothChange.ADVERTISEMENT)
@ -277,7 +279,7 @@ class BluetoothManager:
return
if service_info is None:
service_info = BluetoothServiceInfo.from_advertisement(
device, advertisement_data
device, advertisement_data, SOURCE_LOCAL
)
for domain in matched_domains:
discovery_flow.async_create_flow(
@ -312,7 +314,9 @@ class BluetoothManager:
):
try:
callback(
BluetoothServiceInfo.from_advertisement(*device_adv_data),
BluetoothServiceInfo.from_advertisement(
*device_adv_data, SOURCE_LOCAL
),
BluetoothChange.ADVERTISEMENT,
)
except Exception: # pylint: disable=broad-except
@ -338,7 +342,9 @@ class BluetoothManager:
discovered = models.HA_BLEAK_SCANNER.discovered_devices
history = models.HA_BLEAK_SCANNER.history
return [
BluetoothServiceInfo.from_advertisement(*history[device.address])
BluetoothServiceInfo.from_advertisement(
*history[device.address], SOURCE_LOCAL
)
for device in discovered
if device.address in history
]

View File

@ -22,10 +22,11 @@ class BluetoothServiceInfo(BaseServiceInfo):
manufacturer_data: dict[int, bytes]
service_data: dict[str, bytes]
service_uuids: list[str]
source: str
@classmethod
def from_advertisement(
cls, device: BLEDevice, advertisement_data: AdvertisementData
cls, device: BLEDevice, advertisement_data: AdvertisementData, source: str
) -> BluetoothServiceInfo:
"""Create a BluetoothServiceInfo from an advertisement."""
return cls(
@ -35,6 +36,7 @@ class BluetoothServiceInfo(BaseServiceInfo):
manufacturer_data=advertisement_data.manufacturer_data,
service_data=advertisement_data.service_data,
service_uuids=advertisement_data.service_uuids,
source=source,
)
@cached_property

View File

@ -6,6 +6,7 @@ from bleak.backends.scanner import AdvertisementData, BLEDevice
from homeassistant.components import bluetooth
from homeassistant.components.bluetooth import (
SOURCE_LOCAL,
BluetoothChange,
BluetoothServiceInfo,
models,
@ -244,6 +245,7 @@ async def test_async_discovered_device_api(hass, mock_bleak_scanner_start):
assert len(service_infos) == 1
# wrong_name should not appear because bleak no longer sees it
assert service_infos[0].name == "wohand"
assert service_infos[0].source == SOURCE_LOCAL
assert bluetooth.async_address_present(hass, "44:44:33:11:23:42") is False
assert bluetooth.async_address_present(hass, "44:44:33:11:23:45") is True
@ -255,7 +257,8 @@ async def test_register_callbacks(hass, mock_bleak_scanner_start):
callbacks = []
def _fake_subscriber(
service_info: BluetoothServiceInfo, change: BluetoothChange
service_info: BluetoothServiceInfo,
change: BluetoothChange,
) -> None:
"""Fake subscriber for the BleakScanner."""
callbacks.append((service_info, change))
@ -312,16 +315,19 @@ async def test_register_callbacks(hass, mock_bleak_scanner_start):
service_info: BluetoothServiceInfo = callbacks[0][0]
assert service_info.name == "wohand"
assert service_info.source == SOURCE_LOCAL
assert service_info.manufacturer == "Nordic Semiconductor ASA"
assert service_info.manufacturer_id == 89
service_info: BluetoothServiceInfo = callbacks[1][0]
assert service_info.name == "empty"
assert service_info.source == SOURCE_LOCAL
assert service_info.manufacturer is None
assert service_info.manufacturer_id is None
service_info: BluetoothServiceInfo = callbacks[2][0]
assert service_info.name == "empty"
assert service_info.source == SOURCE_LOCAL
assert service_info.manufacturer is None
assert service_info.manufacturer_id is None