Fire bluetooth listener for all matching devices (#80440)

* Fire listener for all matching devices

* Add test case for seen device

* Avoid looping all data if we have address match

* Initialize to empty list
This commit is contained in:
Joakim Plate 2022-10-16 21:49:12 +02:00 committed by GitHub
parent e71bd2c20b
commit 9eb4faf037
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 10 deletions

View File

@ -483,15 +483,19 @@ class BluetoothManager:
# immediately with the last packet so the subscriber can see the # immediately with the last packet so the subscriber can see the
# device. # device.
all_history = self._get_history_by_type(connectable) all_history = self._get_history_by_type(connectable)
if ( service_infos: Iterable[BluetoothServiceInfoBleak] = []
(address := callback_matcher.get(ADDRESS)) if address := callback_matcher.get(ADDRESS):
and (service_info := all_history.get(address)) if service_info := all_history.get(address):
and ble_device_matches(callback_matcher, service_info) service_infos = [service_info]
): else:
try: service_infos = all_history.values()
callback(service_info, BluetoothChange.ADVERTISEMENT)
except Exception: # pylint: disable=broad-except for service_info in service_infos:
_LOGGER.exception("Error in bluetooth callback") if ble_device_matches(callback_matcher, service_info):
try:
callback(service_info, BluetoothChange.ADVERTISEMENT)
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Error in bluetooth callback")
return _async_remove_callback return _async_remove_callback

View File

@ -1089,6 +1089,16 @@ async def test_register_callbacks(hass, mock_bleak_scanner_start, enable_bluetoo
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done() await hass.async_block_till_done()
seen_switchbot_device = BLEDevice("44:44:33:11:23:46", "wohand")
seen_switchbot_adv = generate_advertisement_data(
local_name="wohand",
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
manufacturer_data={89: b"\xd8.\xad\xcd\r\x85"},
service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10c"},
)
inject_advertisement(hass, seen_switchbot_device, seen_switchbot_adv)
cancel = bluetooth.async_register_callback( cancel = bluetooth.async_register_callback(
hass, hass,
_fake_subscriber, _fake_subscriber,
@ -1125,7 +1135,7 @@ async def test_register_callbacks(hass, mock_bleak_scanner_start, enable_bluetoo
inject_advertisement(hass, empty_device, empty_adv) inject_advertisement(hass, empty_device, empty_adv)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(callbacks) == 1 assert len(callbacks) == 2
service_info: BluetoothServiceInfo = callbacks[0][0] service_info: BluetoothServiceInfo = callbacks[0][0]
assert service_info.name == "wohand" assert service_info.name == "wohand"