Skip to content

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 entry
ln882h_ble_tracker:
  • 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 recommended SCAN_INTERVAL_DEF (0xA0), which together with the default window gives 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 to 50ms — the LN882H SDK’s recommended SCAN_WINDOW_DEF (0x50).

    • duration (Optional, Time): The length of each complete scan session. When continuous is true the scanner restarts immediately after each session ends. Defaults to 5min.

    • active (Optional, boolean): When true the scanner sends scan-request packets to request additional advertisement data (scan response). Defaults to true, 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 true the scanner restarts automatically after each duration period. When false a scan runs once for duration after ln882h_ble_tracker.start_scan; nothing scans on boot unless an automation starts it. Defaults to true.

  • id (Optional, ID): Manually specify the ID used to reference this component in lambdas.

Automations:

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.

  • 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());
  • 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.

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());
  • 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. FCD2 for BTHome v2, 181A for Environmental Sensing).
  • See Automation.

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!");

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: true
  • continuous (Optional, templatable, boolean): Override the scan mode until the next start_scan or stop_scan (the YAML-configured value itself is untouched). When omitted, the mode configured under scan_parameters is restored — a previous stop_scan does not stick as “one-shot”.

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:

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"

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: 100ms50 / 50 BLE / WiFi — the LN882H SDK’s recommended default
  • interval: 200ms25 / 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.