[bk72xx_ble] Support active scanning by packing the GAPM start command (#18169)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bdraco <663432+bdraco@users.noreply.github.com>
This commit is contained in:
J. Nick Koston
2026-08-10 14:02:37 -05:00
committed by GitHub
co-authored by copilot-swe-agent[bot] bdraco
parent 9e78a768a2
commit 207ae2e4cb
20 changed files with 754 additions and 180 deletions
@@ -15,6 +15,7 @@ bk72xx:
bk72xx_ble_tracker:
scan_parameters:
continuous: false
active: false
on_ble_advertise:
- mac_address:
- AC:37:43:77:5F:4C
@@ -48,6 +48,8 @@ def test_trigger_codegen(
# scan_parameters continuous: false reaches the YAML-mode setter, not the
# runtime override.
assert "->set_configured_continuous(false)" in main_cpp
# active: false (non-default) flows through to the setter.
assert "->set_scan_active(false)" in main_cpp
# Constructor call, not just the declaration: the parent argument is what
# registers the trigger as a listener.
assert re.search(
@@ -16,8 +16,8 @@ from esphome.components.ln882h_ble_tracker import (
from esphome.components.rp2_ble_tracker import SCAN_PARAMETERS_SCHEMA as RP2_SCHEMA
def _validate(**kwargs: str) -> dict:
"""Run a scan_parameters config through a passive tracker's real schema."""
def _validate(**kwargs: str | bool) -> dict:
"""Run a scan_parameters config through the bk72xx tracker's real schema."""
return BK72XX_SCHEMA(kwargs)
@@ -48,11 +48,12 @@ def test_to_ble_units_truncates() -> None:
def test_bk72xx_defaults_are_valid() -> None:
"""bk72xx pins the BK reference rate: 100 ms interval, shared 30 ms window."""
"""bk72xx pins the BK reference rate — 100 ms interval, shared 30 ms window —
and exposes active (default on, like every active-capable tracker)."""
config = _validate()
assert to_ble_units(config["interval"]) == 160
assert to_ble_units(config["window"]) == 48
assert "active" not in config
assert config["active"] is True
def test_esp32_defaults_are_valid() -> None:
@@ -86,10 +87,9 @@ def test_esp32_active_can_disable() -> None:
assert config["active"] is False
def test_passive_schema_rejects_active_key() -> None:
"""Trackers without active scan support must not silently accept the option."""
with pytest.raises(cv.Invalid):
_validate(active="true")
def test_bk72xx_active_can_disable() -> None:
config = _validate(active=False)
assert config["active"] is False
# --- accepted configurations ---
@@ -15,6 +15,7 @@ from esphome.const import (
KEY_CORE,
KEY_TARGET_FRAMEWORK,
KEY_TARGET_PLATFORM,
PLATFORM_BK72XX,
PLATFORM_ESP32,
PLATFORM_LN882X,
PLATFORM_RP2,
@@ -27,18 +28,20 @@ from ..types import SetCoreConfigCallable
# Advertisement-only hub platforms; rp2 runs the full proxy and has its own
# tests below.
HUB_PLATFORM_FRAMEWORKS = [
PlatformFramework.BK72XX_ARDUINO,
PlatformFramework.LN882X_ARDUINO,
]
HUB_TRACKERS = {
PLATFORM_BK72XX: "bk72xx_ble_tracker",
PLATFORM_LN882X: "ln882h_ble_tracker",
PLATFORM_RP2: "rp2_ble_tracker",
}
def test_hub_platform_list_covers_every_hub_platform() -> None:
# A platform added to _HUB_PLATFORMS (bk72xx is planned) would otherwise
# get no gate coverage at all; GATT platforms have their own tests.
# A platform added to _HUB_PLATFORMS would otherwise get no gate coverage
# at all; GATT platforms have their own tests.
advertisement_only = set(bluetooth_proxy._HUB_PLATFORMS) - set(
bluetooth_connection.HUB_MAX_CONNECTIONS
)