Skip to content

Commit b3acb88

Browse files
authored
feat: rename _async_on_raw_advertisement to _async_on_raw_advertisements (#184)
1 parent 5352e45 commit b3acb88

File tree

4 files changed

+95
-6
lines changed

4 files changed

+95
-6
lines changed

src/habluetooth/base_scanner.pxd

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ cdef class BaseHaRemoteScanner(BaseHaScanner):
5656
info=BluetoothServiceInfoBleak,
5757
prev_info=BluetoothServiceInfoBleak
5858
)
59+
cdef void _async_on_advertisement_internal(
60+
self,
61+
str address,
62+
int rssi,
63+
str local_name,
64+
list service_uuids,
65+
dict service_data,
66+
dict manufacturer_data,
67+
object tx_power,
68+
dict details,
69+
double advertisement_monotonic_time
70+
)
71+
5972
cpdef void _async_on_advertisement(
6073
self,
6174
str address,
@@ -70,7 +83,7 @@ cdef class BaseHaRemoteScanner(BaseHaScanner):
7083
)
7184

7285
@cython.locals(parsed=tuple, address_rssi_raw_details=tuple, now=double)
73-
cpdef void _async_on_raw_advertisement(self, list advertisements)
86+
cpdef void _async_on_raw_advertisements(self, list advertisements)
7487

7588
@cython.locals(now=double, timestamp=double, info=BluetoothServiceInfoBleak)
7689
cpdef void _async_expire_devices(self)

src/habluetooth/base_scanner.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def get_discovered_device_advertisement_data(
408408
return info.device, info.advertisement
409409
return None
410410

411-
def _async_on_raw_advertisement(
411+
def _async_on_raw_advertisements(
412412
self, advertisements: list[AdvertisementTupleType]
413413
) -> None:
414414
"""
@@ -422,7 +422,7 @@ def _async_on_raw_advertisement(
422422
now = _MONOTONIC_NOW()
423423
for address_rssi_raw_details in advertisements:
424424
parsed = parse_advertisement_data_tuple(address_rssi_raw_details[2])
425-
self._async_on_advertisement(
425+
self._async_on_advertisement_internal(
426426
address_rssi_raw_details[0],
427427
address_rssi_raw_details[1],
428428
parsed[0],
@@ -446,7 +446,36 @@ def _async_on_advertisement(
446446
details: dict[Any, Any],
447447
advertisement_monotonic_time: _float,
448448
) -> None:
449-
"""Call the registered callback."""
449+
"""Call on new advertisement data."""
450+
self._async_on_advertisement_internal(
451+
address,
452+
rssi,
453+
local_name,
454+
service_uuids,
455+
service_data,
456+
manufacturer_data,
457+
tx_power,
458+
details,
459+
advertisement_monotonic_time,
460+
)
461+
462+
def _async_on_advertisement_internal(
463+
self,
464+
address: _str,
465+
rssi: _int,
466+
local_name: _str | None,
467+
service_uuids: list[str],
468+
service_data: dict[str, bytes],
469+
manufacturer_data: dict[int, bytes],
470+
tx_power: _int | None,
471+
details: dict[Any, Any],
472+
advertisement_monotonic_time: _float,
473+
) -> None:
474+
"""
475+
Internal implementation of _async_on_advertisement.
476+
477+
This method is unstable and not part of the public API.
478+
"""
450479
self.scanning = not self._connecting
451480
self._last_detection = advertisement_monotonic_time
452481
info = BluetoothServiceInfoBleak.__new__(BluetoothServiceInfoBleak)

tests/test_base_scanner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def inject_raw_advertisement(
6363
self, address: str, data: tuple[bytes, ...], details: dict[Any, Any], rssi: int
6464
) -> None:
6565
"""Inject a raw advertisement."""
66-
self._async_on_raw_advertisement([(address, rssi, data, details)])
66+
self._async_on_raw_advertisements([(address, rssi, data, details)])
6767

6868

6969
@pytest.mark.parametrize("name_2", [None, "w"])

tests/test_benchmark_base_scanner.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
from __future__ import annotations
44

5+
import base64
6+
57
import pytest
68
from bleak.backends.scanner import AdvertisementData
79
from bluetooth_data_tools import monotonic_time_coarse
810
from pytest_codspeed import BenchmarkFixture
911

10-
from habluetooth import BaseHaRemoteScanner, HaBluetoothConnector, get_manager
12+
from habluetooth import (
13+
AdvertisementTupleType,
14+
BaseHaRemoteScanner,
15+
HaBluetoothConnector,
16+
get_manager,
17+
)
1118

1219
from . import (
1320
MockBleakClient,
@@ -73,6 +80,46 @@ def run():
7380
unsetup()
7481

7582

83+
@pytest.mark.usefixtures("enable_bluetooth")
84+
@pytest.mark.asyncio
85+
async def test_inject_100_simple_raw_advertisements(
86+
benchmark: BenchmarkFixture,
87+
) -> None:
88+
"""Test injecting 100 simple raw advertisements."""
89+
manager = get_manager()
90+
91+
switchbot_device = generate_ble_device(
92+
"44:44:33:11:23:45",
93+
"wohand",
94+
{},
95+
rssi=-100,
96+
)
97+
connector = HaBluetoothConnector(
98+
MockBleakClient, "mock_bleak_client", lambda: False
99+
)
100+
101+
class SubclassedBaseHaRemoteScanner(BaseHaRemoteScanner):
102+
"""Subclassed BaseHaRemoteScanner to expose _async_on_raw_advertisements."""
103+
104+
scanner = SubclassedBaseHaRemoteScanner("esp32", "esp32", connector, True)
105+
unsetup = scanner.async_setup()
106+
cancel = manager.async_register_scanner(scanner)
107+
_address = switchbot_device.address
108+
_rssi = switchbot_device.rssi
109+
adv_bytes = (base64.b64decode("AgEaAgoFCv9MABAFChx3+Vs="),)
110+
advs: list[AdvertisementTupleType] = [
111+
(_address, _rssi, adv_bytes, {}) for _ in range(100)
112+
]
113+
114+
def run():
115+
scanner._async_on_raw_advertisements(advs)
116+
117+
benchmark(run)
118+
119+
cancel()
120+
unsetup()
121+
122+
76123
@pytest.mark.usefixtures("enable_bluetooth")
77124
@pytest.mark.asyncio
78125
async def test_inject_100_complex_advertisements(benchmark: BenchmarkFixture) -> None:

0 commit comments

Comments
 (0)