LN882H Bluetooth Low Energy Tracker Hub
The ln882h_ble_tracker component creates a global hub so that you can track Bluetooth Low Energy
devices using your LN882H node (LibreTiny ln882x platform, such as the WL2H-U and
LN-CB3S V1.0 modules).
This component provides the BLE scanner and the listener interface used by ESPHome’s advertisement-based BLE sensor platforms — for example BLE RSSI, BLE Presence, BLE Scanner and Xiaomi BLE — which attach to this tracker automatically.
NOTE
The tracker is scan-only and cannot open GATT connections, so
ble_client is not available on this platform.
bluetooth_proxy works in advertisement-only mode — see
Platform Support.
NOTE
The tracker builds on the LN882H BLE controller component and
loads it automatically — the BLE stack (CFG_SUPPORT_BLE) is enabled in the build with no
manual platformio_options flag.
NOTE
The LN882H is a single-core SoC — WiFi and BLE share the same ARM CPU core.
The scan window / interval ratio decides how that core is split between BLE and WiFi.
See Use on a single-core chip below.
# Example configuration entryln882h_ble_tracker:Configuration variables
Section titled “Configuration variables”-
scan_parameters (Optional): Advanced parameters for configuring the scan behaviour. See also this guide by Texas Instruments for background reading.
-
interval (Optional, Time): The interval between each consecutive scan window. The scanner cycles through the three BLE advertising channels at this rate. Defaults to
100ms— the LN882H SDK’s recommendedSCAN_INTERVAL_DEF(0xA0), which together with the defaultwindowgives a 50 % duty cycle (the value the chip is designed to scan at). A larger interval lowers the duty cycle and frees more CPU time for WiFi on the single-core SoC, at the cost of catching fewer advertisements. -
window (Optional, Time): The time the receiver is actively listening for packets on a channel during each scan interval. Must be ≤
interval. Defaults to50ms— the LN882H SDK’s recommendedSCAN_WINDOW_DEF(0x50). -
duration (Optional, Time): The length of each complete scan session. When
continuousistruethe scanner restarts immediately after each session ends. Defaults to5min. -
active (Optional, boolean): When
truethe scanner sends scan-request packets to request additional advertisement data (scan response). Defaults totrue, matching ESP32 BLE Tracker.NOTE
As on ESP32 (where ESP-IDF performs the merge), an advertisement and its scan response are combined into a single result, so automations and sensor platforms receive one merged frame containing both payloads — this is where device names come from. The merge is best-effort: a scannable advertisement is held briefly (up to 300 ms) waiting for its scan response, and a device that does not answer the scan request is delivered unmerged (without a name) after that timeout.
-
continuous (Optional, boolean): When
truethe scanner restarts automatically after eachdurationperiod. Whenfalsea scan runs once fordurationafterln882h_ble_tracker.start_scan; nothing scans on boot unless an automation starts it. Defaults totrue.
-
-
id (Optional, ID): Manually specify the ID used to reference this component in lambdas.
Automations:
- on_ble_advertise (Optional, Automation): An automation to perform
when a BLE advertising packet is received. Optionally filtered to a list of
mac_addresses. Seeon_ble_advertiseTrigger. - on_ble_manufacturer_data_advertise (Optional, Automation): An automation
to perform when a BLE advertising packet with matching manufacturer data is received.
See
on_ble_manufacturer_data_advertiseTrigger. - on_ble_service_data_advertise (Optional, Automation): An automation to
perform when a BLE advertising packet with service data for
service_uuidis received. Seeon_ble_service_data_advertiseTrigger. - on_scan_end (Optional, Automation): An automation to perform when a scan
session ends (its
durationelapsed, orstop_scanwas called). Fires on every cycle whencontinuousistrue. Seeon_scan_endTrigger.
LN882H BLE Tracker Automation
Section titled “LN882H BLE Tracker Automation”on_ble_advertise Trigger
Section titled “on_ble_advertise Trigger”This automation will be triggered when a BLE advertising packet is received. A variable x of
type API Reference: ble_device_base::ESPBTDevice is
passed to the automation for use in lambdas.
ln882h_ble_tracker: on_ble_advertise: # Optional multi-device filter; omit mac_address to fire on every advertisement. - mac_address: - XX:XX:XX:XX:XX:XX - XX:XX:XX:XX:XX:XX then: - lambda: |- ESP_LOGD("ble_adv", "Advertisement from %s (RSSI %d), name '%s'", x.address_str().c_str(), x.get_rssi(), x.get_name().c_str());Add an optional mac_address filter (a list) to restrict the automation to specific devices, and
use the device accessors — x.get_service_uuids(), x.get_service_datas(),
x.get_manufacturer_datas() — to inspect the advertisement payload.
Configuration variables
Section titled “Configuration variables”- mac_address (Optional, list of MAC Address): The MAC address to filter for this automation.
- See Automation.
on_ble_manufacturer_data_advertise Trigger
Section titled “on_ble_manufacturer_data_advertise Trigger”This automation will be triggered when a BLE advertising packet with manufacturer-specific data
is received. A variable x of type std::vector<uint8_t> is passed to the automation for use
in lambdas.
ln882h_ble_tracker: on_ble_manufacturer_data_advertise: - mac_address: XX:XX:XX:XX:XX:XX manufacturer_id: 0590 then: - lambda: |- ESP_LOGD("ble_man_data", "Manufacturer data of length %i", x.size());Configuration variables
Section titled “Configuration variables”- mac_address (Optional, MAC Address): The MAC address to filter for this automation.
- manufacturer_id (Required, string): 16-bit, 32-bit, or 128-bit BLE manufacturer ID in hex.
- See Automation.
on_ble_service_data_advertise Trigger
Section titled “on_ble_service_data_advertise Trigger”This automation will be triggered when a BLE advertising packet with service data is received. A
variable x of type std::vector<uint8_t> is passed to the automation for use in lambdas.
ln882h_ble_tracker: on_ble_service_data_advertise: - mac_address: XX:XX:XX:XX:XX:XX service_uuid: FCD2 then: - lambda: |- ESP_LOGD("ble_svc_data", "Service data of length %i", x.size());Configuration variables
Section titled “Configuration variables”- mac_address (Optional, MAC Address): The MAC address to filter for this automation.
- service_uuid (Required, string): 16-bit, 32-bit, or 128-bit BLE service UUID in hex
(e.g.
FCD2for BTHome v2,181Afor Environmental Sensing). - See Automation.
on_scan_end Trigger
Section titled “on_scan_end Trigger”This automation will be triggered when a Bluetooth scan session has completed. When continuous
is true this fires at the end of every scan cycle.
ln882h_ble_tracker: on_scan_end: - then: - lambda: |- ESP_LOGD("ble_auto", "The scan has ended!");Configuration variables
Section titled “Configuration variables”- None.
- See Automation.
ln882h_ble_tracker.start_scan Action
Section titled “ln882h_ble_tracker.start_scan Action”Start a Bluetooth scan. The optional templatable
continuous overrides the scan mode until the next start_scan or stop_scan (the
YAML-configured value itself is untouched); without it the mode configured under
scan_parameters is restored (a previous stop_scan does not stick as “one-shot”). This
differs from esp32_ble_tracker.start_scan, where an omitted continuous always forces a
one-shot scan. Invoked while a scan is already running, a mode switch re-anchors the running
scan’s duration window instead of restarting the radio; a same-mode call is a no-op.
ln882h_ble_tracker: scan_parameters: continuous: false
on_...: - ln882h_ble_tracker.start_scan: continuous: trueConfiguration variables
Section titled “Configuration variables”- continuous (Optional, templatable, boolean):
Override the scan mode until the next
start_scanorstop_scan(the YAML-configured value itself is untouched). When omitted, the mode configured underscan_parametersis restored — a previousstop_scandoes not stick as “one-shot”.
ln882h_ble_tracker.stop_scan Action
Section titled “ln882h_ble_tracker.stop_scan Action”Stop the running Bluetooth scan; also cancels a start latched before setup (an on_boot
start_scan). Accepts the bare-id shorthand (ln882h_ble_tracker.stop_scan: my_tracker). It
can be restarted with ln882h_ble_tracker.start_scan.
on_...: - ln882h_ble_tracker.stop_scan:With BLE sensors
Section titled “With BLE sensors”Sensor platforms attach to the tracker automatically (identical to ESP32):
ln882h_ble_tracker:
sensor: - platform: xiaomi_lywsd03mmc mac_address: XX:XX:XX:XX:XX:XX bindkey: "00112233445566778899aabbccddeeff" temperature: name: "Temperature" humidity: name: "Humidity" - platform: ble_rssi mac_address: XX:XX:XX:XX:XX:XX name: "BLE Beacon RSSI"Use on a single-core chip
Section titled “Use on a single-core chip”Unlike the ESP32 which runs BLE on a dedicated core, the LN882H runs both WiFi and BLE on the same ARM CPU core at 160 MHz. Continuous scanning during the ESPHome Native API TCP handshake can prevent WiFi from completing the connection; the scan actions exist to time-share instead — scan only while Home Assistant is connected:
ln882h_ble_tracker: scan_parameters: continuous: false # do not start on boot
api: on_client_connected: - ln882h_ble_tracker.start_scan: continuous: true on_client_disconnected: # fires for EVERY departing client (log viewer, CLI) — state_subscription_only # ignores logger-only clients, so scanning stops only when Home Assistant is gone - if: condition: not: api.connected: state_subscription_only: true then: - ln882h_ble_tracker.stop_scan:The scan window / interval ratio decides how the core is split between BLE scanning and
WiFi while a scan runs. Keep window: 50ms and choose the interval:
interval: 100ms→ 50 / 50 BLE / WiFi — the LN882H SDK’s recommended defaultinterval: 200ms→ 25 / 75 BLE / WiFi — catches fewer advertisements, but leaves more of the core for WiFi
Setting active: false is a second lever: the scanner no longer sends scan requests to request
more data after receiving an advertising packet, keeping the radio cost of each window minimal.
BTHome/ATC-style sensors that broadcast all their data in the advertisement don’t need active
scanning.