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>
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

1 participant