BT proxy (btproxy) suddenly stops discovering - debugging

Without further ado, I’ve 3 btproxy devices that scan some Airthings (10x), Nuki locks (2x) and an Oral-B toothbrush. About once a day, all my bluetooth devices go offline (all entities Unavailable).

Trying to debug that I have enabled bluetooth logging in HA:

logger:
  logs:
    homeassistant.components.bluetooth: debug

Which at some point starts giving me messages like:

2025-01-20 07:37:57.538 INFO (MainThread) [habluetooth.base_scanner] btproxy-c25b74 (E8:31:CD:C2:5B:74): Bluetooth scanner has gone quiet for 90s, check logs on the scanner device for more information
2025-01-20 07:37:58.648 INFO (MainThread) [habluetooth.base_scanner] btproxy-c257a8 (E8:31:CD:C2:57:A8): Bluetooth scanner has gone quiet for 90s, check logs on the scanner device for more information
2025-01-20 07:37:58.648 INFO (MainThread) [habluetooth.base_scanner] btproxy-c25bac (E8:31:CD:C2:5B:AC): Bluetooth scanner has gone quiet for 90s, check logs on the scanner device for more information

and eventually:

Error fetching airthings_ble data: Unable to fetch data: 80:6F:B0:D7:34:D1 - 80:6F:B0:D7:34:D1: Failed to connect after 9 attempt(s): No backend with an available connection slot that can reach address 80:6F:B0:D7:34:D1 was found: The proxy/adapter is out of connection slots or the device is no longer reachable; Add additional proxies (https://esphome.github.io/bluetooth-proxies/) near this device

…for all my Airthings devices - which given how proxies are distributed (some within 1-3 meters from Airthings device) can not be caused by bluetooth range.

There were no logs at the esphome device itself (beside my “uptime” sensor updates), but the error messages inspired me to add a couple sensors:

globals:
  - id: ble_scans
    type: int
    restore_value: no
    initial_value: '0'
esp32_ble_tracker:
  # < skipping scan_params as irrelevant for this snippet about sensors >
  # < see full config later in the post >
  on_scan_end:
    - then:
      - sensor.template.publish:
          id: ble_scans_finished
          state: !lambda 'return ++id(ble_scans);'

sensor:
  - platform: template
    name: "btproxy connections free"
    lambda: 'return id(btproxy).get_bluetooth_connections_free();'
    update_interval: 60s
    state_class: "measurement"
    accuracy_decimals: 0
    entity_category: diagnostic
    icon: "mdi:bluetooth-settings"

  - platform: template
    name: "BLE scans finished"
    id: ble_scans_finished
    state_class: "total_increasing"
    accuracy_decimals: 0
    entity_category: diagnostic
    icon: "mdi:bluetooth-settings"

Which gave me some picture - looks like at some point in time, connections are exhausted (theres 0 or 1 slot remaining) and at the same time, bluetooth scanning stops (until I restart esphomes):

My question is, for the lack of further debug information, where would I need to dig next to see what causes my blutooth proxies misbehave like that?

P.S. esphome config, manually expanded from !include’d packages - these are Olimex devices connected and powered over ethernet:

esp32:
  board: esp32-poe
  framework:
    type: esp-idf

esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms
    active: true

bluetooth_proxy:
  id: btproxy
  active: true

# The following is likely irrelevant but included for posterity:

api:
  encryption:
    key: !secret api_encryption_key

status_led:
  pin: GPIO2

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO17_OUT
  phy_addr: 0
  power_pin: GPIO12
  domain: ""

text_sensor:
- platform: ethernet_info
  ip_address:
    name: "Device IP (Ethernet)"
  mac_address:
    name: "Device MAC (Ethernet)"

logger:

sensor:
- platform: uptime
  name: "Uptime"

button:
- platform: restart
  name: "ESP chip restart"
  entity_category: diagnostic

ota:
  - platform: esphome
    password: !secret ota_password

A little bit more info if it helps:

  • the btproxies do not go offline all at the same time. In this instance, one did at 9:40PM, another 10:37PM and the last one 10:41PM.

  • the messages about “scanner has gone quiet for 90s” in HA logs are coming 90s (as expected) after the latest message for that proxy, which is nothing special, just a usual discovery log something like “… [connectable] …”. For example (yes, in addition I also have a couple Ruuvi sensors - almost forgot about those. It’s not always Ruuvi that is last message though):

    btproxy-c25bac (E8:31:CD:C2:5B:AC) [connectable]:
    <BluetoothServiceInfoBleak name=Ruuvi DF2E
     address=CE:43:F8:76:DF:2E rssi=-73
     manufacturer_data={1177: b'\x05\x00\x00s\xed\xb4o\x00$\x004\x03\xf0\x976\t\xad\xc5\xceC\xf8v\xdf.'}
     service_data={} service_uuids=['6e400001-b5a3-f393-e0a9-e50e24dcca9e']
     source=E8:31:CD:C2:5B:AC
     connectable=True time=458935.833431193
     tx_power=None> match: set()
    

Perhaps there’s a way to tell where the connections are gone, i.e. what integration occupied the remaining connections from btproxy?

Added syslog to esp-idf and discovered that there are more logs in esp32 before Bluetooth is out of service. Apparently the issue is similar to ESPhome Bluetooth BLE proxy stops working - #14 by Mikrofarad

Posted as BLE client "DISCONNECTING" state is terminal and leaks btproxy connections · Issue #6701 · esphome/issues · GitHub

To whoever wonders, my solution is to reboot the device if the latest scan was more than a few minutes ago:

button:
  - platform: restart
    id: restart_button

script:
  - id: restart_after_delay
    mode: restart  # abort previous restart sequence on script.execute
    then:
      - delay: 10min
      - button.press: restart_button

esp32_ble_tracker:
  # ...
  on_scan_end:
    - then:
      - script.execute: restart_after_delay
1 Like

Just wanted to say thanks for posting this.

I recently updated my wESP32 POE board running as a bluetooth-proxy to 2024.12.4 and it has become totally unreliable.

I’m going to try your automated-reboot workaround and hope a future update fixes this.

Out of curiosity, how do you “add syslog to esp-idf”? (I’ve been wondering if there’s a way to send ESPHome log messages to a central log server using remote syslog.)

Thanks again for following up with a solution (and for upcoming the issue with the ESPHome project)!

Glad it helps! I tried to upgrade syslog component from TheStaticTurtle, but it’s bound very strongly to Arduino, and so is the underlying library. Since it’s the spirit of esphome to have fewer dependencies, and syslog protocol is trivial (sans myriad of standards), I ended up with a custom implementation which works for Arduino (for my esp8266) and IDF.

I’m going to let it run for few weeks more and try to submit a PR to esphome. In the meantime, feel free to pick it up from here:

Something like this should work:

external_components:
  - source:
      type: git
      url: https://github.com/dotdoom/esphome
      ref: main
    components: [ syslog ]

syslog:
  ip_address: 3.4.3.2
1 Like

First, thanks for the syslog info — it will definitely be nice to see this (hopefully) merged. I will give it a try as an external_component.

Second, interestingly enough, once I added the additional sensors (based on your earlier example config) to my bluetooth-proxy config, it ended up becoming a bit more reliable: it will now go for a couple days (and now, get automatically restarted) instead of dying after several hours. I’m happy to have your “automated recovery” — thanks again!

1 Like

Great! If you end up trying, let me know how it’s going with syslog. My fleetzoo includes a variety of esp32 with WiFi and PoE, and a handful of esp8266, but I’m looking for feedback to have wider coverage.

Besides, HA has added more versatile Bluetooth UI in 2025.2 which you may find useful to e.g. see if a particular integration consumes all the slots: 2025.2: Iterating on backups - Home Assistant