Skip to content

fix(ble_scanner): register FMDN callback as connectable=False so proxy-relayed advertisements aren't dropped - #220

Open
heman22union wants to merge 1 commit into
BSkando:mainfrom
heman22union:fix/ble-proxy-connectable-matcher
Open

fix(ble_scanner): register FMDN callback as connectable=False so proxy-relayed advertisements aren't dropped#220
heman22union wants to merge 1 commit into
BSkando:mainfrom
heman22union:fix/ble-proxy-connectable-matcher

Conversation

@heman22union

Copy link
Copy Markdown

Problem

The FMDN BLE listener (fmdn_finder/ble_scanner.py) registers its async_register_callback with matcher=None, intending "receive every advertisement." In current Home Assistant, a falsy matcher is not "match everything" — BluetoothManager treats it as {"connectable": True} (homeassistant/components/bluetooth/manager.py):

if not matcher:
    callback_matcher[CONNECTABLE] = True

ESPHome and Shelly Bluetooth proxies register their scanners as non-connectable. So any advertisement relayed through a proxy is silently filtered out before this integration's callback ever runs — only advertisements picked up by a connectable local adapter got through. In practice this means GoogleFindMyBLEBatterySensor (and any other consumer of this listener) can never populate for a tracker that's only ever in range of a Bluetooth proxy, which is a very common home setup (proxy coverage instead of, or in addition to, the HA host's own onboard radio).

Fix

Pass {"connectable": False} as the matcher instead of None. Per HA's matching logic in match.py:

if matcher.get(CONNECTABLE, True) and not service_info.connectable:
    return False

connectable=False short-circuits that check regardless of the advertisement's own connectable status, so both local-radio and proxy-relayed advertisements reach the callback.

Verification

Reproduced and fixed against a live install with a Shelly BLE proxy ~10ft from several trackers:

  • Before: instrumented the callback with a call counter. Zero invocations over a 5+ minute window post-restart, despite HA's own Bluetooth manager diagnostics (/api/diagnostics/config_entry/...) confirming the proxy's scanner was scanning: true and actively holding multiple 0xFEAA-tagged advertisements from known trackers in its live pool (sub-second freshness).
  • After: same restart, same proxy, same trackers — the callback started firing immediately, resolved multiple trackers via resolve_eid(), and GoogleFindMyBLEBatterySensor entities appeared within minutes for trackers that had never had a battery sensor before (proxy-only coverage, never in range of the HA host's own radio).

Scope

Single-line behavioral change (plus an explanatory comment) in fmdn_finder/ble_scanner.py. No other files touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KXsckk4TPxReBfo44LAgQt

A falsy matcher (None) passed to HA's async_register_callback is not
"match everything" -- HA's BluetoothManager treats it as
{"connectable": True} (homeassistant/components/bluetooth/manager.py),
which silently drops every advertisement relayed through a
non-connectable source. ESPHome and Shelly Bluetooth proxies register
as non-connectable scanners, so the FMDN BLE listener never fired for
any proxy-heard tracker -- only advertisements picked up by a
connectable local adapter got through. This meant BLE battery sensors
(GoogleFindMyBLEBatterySensor) could never populate for trackers only
in range of a Bluetooth proxy, which is the common case for a home
with proxy coverage instead of (or in addition to) the HA host's own
onboard radio.

Verified with targeted instrumentation on a live install: with the
matcher as None, zero callback invocations occurred over a 5+ minute
window despite HA's own Bluetooth manager diagnostics confirming a
Shelly BLE proxy was actively holding matching FEAA-tagged
advertisements. Changing the matcher to {"connectable": False}
(which HA's matching logic treats as "don't require connectable",
not "require non-connectable") made the callback fire immediately,
resolved multiple trackers, and produced working BLE battery sensors
within minutes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RsSisxZGmU4TyrqhhN46ZL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant