Skip to content

fix: follow Bluetooth adapters that change their hci index - #1609

Open
dingausmwald wants to merge 1 commit into
custom-components:masterfrom
dingausmwald:fix/follow-adapter-hci-index
Open

dingausmwald wants to merge 1 commit into
custom-components:masterfrom
dingausmwald:fix/follow-adapter-hci-index

Conversation

@dingausmwald

Copy link
Copy Markdown

Fixes #830

Problem

When the kernel resets a Bluetooth dongle, the dongle can come back under a different hci index. This happens for example after a command tx timeout on a Realtek RTL8761BU. After that, BLE monitor keeps using the old index and never recovers until Home Assistant Core is restarted. Reloading the integration does not help.

The log from a Raspberry Pi 4 on 14.2.0, where the dongle 00:E0:42:A7:E9:03 moved from hci2 to hci0:

kernel: Bluetooth: hci2: command tx timeout
kernel: Bluetooth: hci2: Resetting usb device.
kernel: Bluetooth: hci0: RTL: fw version 0xdfc6d922
...
ERROR (Thread-3) [custom_components.ble_monitor] HCIdump thread: OS error (hci2): [Errno 19] error while attempting to bind on interface 2: No such device
ERROR (Thread-3) [custom_components.ble_monitor] HCIdump thread: Trying to power cycle Bluetooth adapter hci2 00:E0:42:A7:E9:03, will try to use it next scan period.
ERROR (Thread-3) [custom_components.ble_monitor.bt_helpers] hci2 seems not to exist (anymore), check BT interface mac address in your settings. Available adapters: {0: '00:E0:42:A7:E9:03', 1: 'E4:5F:01:74:E1:FF'}

The last three lines repeat every minute. In this case they ran for 8.5 hours until Core was restarted by hand.

Cause

The configured MAC address is resolved to an hci index only once, in async_setup_entry, and the lookup table it uses (BT_INTERFACES) is built once when the module is imported. After that, HCIdump and reset_bluetooth() only work with the stored index, even though the MAC address is known.

Fix

  • At the start of each scan period, HCIdump looks up the current index of each configured adapter by its MAC address and uses that index. When an index changes, a warning is logged. If an adapter is currently missing, it keeps its old index, so the existing power-cycle recovery behaves as before.
  • The power-cycle log message no longer uses BT_INTERFACES[iface]. That lookup raised a KeyError in the HCIdump thread when the new index was not present at import time.
  • bt_helpers.hci_get_all_mac() returns all available adapters. hci_get_mac() now uses it and behaves as before.

If hci_interface is configured in YAML and no MAC address is known for it, nothing changes.

Tests

  • New test/test_hcidump_interfaces.py covers a renumbered adapter, an unchanged adapter, a missing adapter, two adapters swapping indexes, disabled Bluetooth, an index without a known MAC address, and hci_get_mac/hci_get_all_mac.
  • The full test suite passes with pytest on Python 3.14, using requirements_test.txt.

🤖 Generated with Claude Code

A Bluetooth dongle that is reset by the kernel can come back under a
different hci index. HCIdump kept using the index resolved at setup and
did not recover until Home Assistant Core was restarted.

Look up the current hci index of the configured adapters by MAC address
at the start of each scan period. Also stop using BT_INTERFACES[iface]
in the power cycle log, which raised a KeyError for an index that was
not present at import time.

Fixes custom-components#830

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Mixed known and unknown YAML interfaces currently disable renumbering for all configured adapters.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Updates adapter tracking so BLE Monitor follows Bluetooth devices when their HCI indexes change.

Changes:

  • Adds runtime MAC-to-HCI resolution.
  • Prevents stale interface lookup errors.
  • Adds coverage for adapter renumbering and helper behavior.
File Description
custom_components/​ble_monitor/​__init__.py Tracks configured adapters across HCI changes.
custom_components/​ble_monitor/​bt_helpers.py Adds retrieval of all available adapters.
custom_components/​ble_monitor/​test/​test_hcidump_interfaces.py Tests renumbering and adapter lookup behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +540 to +544
if len(config[CONF_HCI_INTERFACE]) == len(config[CONF_BT_INTERFACE]):
self._hci_by_mac = {
bt_mac: hci
for hci, bt_mac in zip(config[CONF_HCI_INTERFACE], config[CONF_BT_INTERFACE])
if bt_mac != "disable"

This branch has not been deployed

No deployments
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.

Give bt Adapter a name

2 participants