Beginning of investigation of why Bluetooth integration dies

I’m hoping to get some ideas on how to investigate why my Bluetooth adapter no longer works after a few days.

I’m running Debian 11,

cat /etc/debian_version
11.5

on an older i7 desktop (16g core) to run many things including HA in Docker. I’ve tried 2 different Bluetooth chipsets, 5.0 and 5.1 versions.

It starts with this in system logs:

Bluetooth: hci0: command 0x2042 tx timeout
Bluetooth: hci0: failed to disable LE scan: status 0x1f
Bluetooth: hci0: command 0x2042 tx timeout

HA reports this:

2022-11-19 11:38:04.036 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/scanner.py", line 372, in _async_scanner_watchdog
    await self._async_reset_adapter()
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/scanner.py", line 389, in _async_reset_adapter
    result = await async_reset_adapter(self.adapter)
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/util.py", line 112, in async_reset_adapter
    return await recover_adapter(adapter_id)
  File "/usr/local/lib/python3.10/site-packages/bluetooth_auto_recovery/recover.py", line 251, in recover_adapter
    async with MGMTBluetoothCtl(hci, MGMT_PROTOCOL_TIMEOUT) as adapter:
  File "/usr/local/lib/python3.10/site-packages/bluetooth_auto_recovery/recover.py", line 116, in __aenter__
    await self._setup()
  File "/usr/local/lib/python3.10/site-packages/bluetooth_auto_recovery/recover.py", line 137, in _setup
    self.sock = btmgmt_socket.open()
  File "/usr/local/lib/python3.10/site-packages/btsocket/btmgmt_socket.py", line 58, in open
    raise BluetoothSocketError("Unable to open PF_BLUETOOTH socket")
btsocket.btmgmt_socket.BluetoothSocketError: Unable to open PF_BLUETOOTH socket

Current firmware:

Bluetooth: hci0: RTL: loading rtl_bt/rtl8761b_config.bin

I can “unplug and then plug it back in” and it seems to recover briefly. But ultimately, I have to “turn off then turn back on” the machine to get it to work for a few more days.

Firmware problem?
USB hardware problem?

Any ideas?

Thanks - Joel

Bluetooth continues to be a fragile and confusing interface on Linux. I think I’ve been down many of the rabbit holes you have been. Based on my experience, I would carefully look for some software running (or something you are doing by accident) that is accessing the Bluetooth adapter in addition to Home Assistant. Regardless of what will be offered, I just do not think it is reliable let more than one application access a give bluetooth adapter. Yes, some things do work successfully, however some code does not. Especially when doing BLE advertising scanning in my experience. Which is kind of core to a lot of the bluetooth HA stuff that is currently being done.

I went down the firmware update path, made no difference.

Bluetooth 5.x vs. 4.x adapters, 5 seems less stable to me due to requiring the newer BlueZ and D-Bus to work as well as the older legacy APIs. Not that the old API’s seemed that stable prior to the new stuff.

BlueZ versions, another whole ‘hole’…

IMHO doing nothing Bluetooth on your HA server and abstracting all bluetooth communication using proxy devices via remote ESPHome or MQTT for C2 seems to be the best path.

Hope you find an answer! Good hunting! It is a PIA…

2 Likes

Yes, this all makes sense. Especially multiple things using the bluetooth service. Thank you. I’ll keep digging and share if there’s anything I find.

Did you find something?
My TP-Link UB500 (not the best choice) stopped working. I presume itś related to at least one of the updates. It could be the Debian or the HA upgrade of last week.

I’m running HA supervised on a Debian VM in Proxmox.

Debian host: 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2 (2022-10-21) x86_64 GNU/Linux
HA: Home Assistant 2022.11.4 Supervisor 2022.11.2 Frontend 20221108.0 - latest

Debian host and HA showing the same dmesg messgage:

$ dmesg | grep -i blue
[    8.216472] Bluetooth: Core ver 2.22
[    8.216562] Bluetooth: HCI device and connection manager initialized
[    8.216568] Bluetooth: HCI socket layer initialized
[    8.216572] Bluetooth: L2CAP socket layer initialized
[    8.216579] Bluetooth: SCO socket layer initialized
[   12.053743] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[   12.053749] Bluetooth: BNEP filters: protocol multicast
[   12.053757] Bluetooth: BNEP socket layer initialized
[   50.671661] Bluetooth: RFCOMM TTY layer initialized
[   50.671672] Bluetooth: RFCOMM socket layer initialized
[   50.671683] Bluetooth: RFCOMM ver 1.11
[ 1154.423907] Bluetooth: hci0: failed to disable LE scan: status 0x1f
/config # hcitool scan
Scanning ...
/config # 

Interesting observation when clicking on the bluetooth device in HA it shows:

Firmware: hass-os
Hardware: usb:v1D6Bp0246d0537 

No progress. I still see the same failures; however, a reboot still recovers for me.

I can only report that I got past a week this time without the failure.

When I get a chance, I’ll check if there is a firmware update for my chipset.

Some progress: I started seeing the errors only after a couple days. I was able to recover without a reboot:

  1. Shutdown HA (in my case docker stop home-assistant).
  2. sudo hciconfig hci0 down
  3. sudo rmmod btusb
  4. sudo modprobe btusb
  5. sudo hciconfig hci0 up
  6. Restart HA and I then can see readings from my Govee BT sensor.

UPDATE:
With the last recent failure, I was able to recover with a Reload on the Bluetooth device integration. This avoids having to restart HA.

So, something like this:

#!/bin/sh

hatoken=<your API token>
state=`curl --silent -X GET -H "authorization: Bearer ${hatoken}" "https://<your HA ip>/api/states/sensor.govee_temperature" | jq -r .state`
echo $state
if [ ! "$state" = 'unavailable' ]
then
    exit 0
fi

/usr/bin/hciconfig hci0 down
/sbin/rmmod btusb
/sbin/modprobe btusb
/usr/bin/hciconfig hci0 up

curl -X POST -H "authorization: Bearer ${hatoken}" "https://<your HA ip>/api/config/config_entries/entry/bb024fc5d7e816ed8bc5e32159b76b11/reload"
  • Run this as root.
  • Create a long-lived API token and use that.
  • I can’t find documentation for the reload call at the bottom. I don’t know what that GUID is. I debug’d the UI to get it (hacked).
  • This is a works-well-enough solution, for now (i.e. hack).

Just sayin’ my Home Assistant server with NO bluetooth direct stuff runs one year plus without touching. My remote raspberry pi 3B also runs one year plus, no touch, delivering BLE sensor broadcasts to HA server via MQTT. “Bob’s your uncle”, pick ur battles. :microphone::droplet:…good hunting!

Yes, I’m getting to that point. I’ve been meaning to investigate having my RPIs handle BLE and send to HA via MQTT. I’ve had success with other sensors (e.g. rtl_433) using MQTT – just works.

I was ending upgrading my debian kernel to 6.0. With it my Bluetooth dongle is working.

Hope you find a solid solution for your config. As I said, I am very happy with my BLE sensor, especially the temperature, humidity, CO2 and AQI devices. I started early, so used a RPI for the collector, but it really looks the ESP32 based devices are the way to go now. Good hunting!

1 Like

Will close this thread out as I moved off the HA Bluetooth Integration and switched to an RPI3+ and MQTT (paho) client to read and publish advertisements from my BLE sensors. Thanks for the tip!

I was able to create a simple Python MQTT client leveraging the great work of the contributors of the sensor.goveetemp_bt_hci and https://github.com/TheCellule/python-bleson projects. The gist is from bleson import get_provider and from govee_advertisement import GoveeAdvertisement.

I’m back to my very minimal HA Integration list :slight_smile:

1 Like

I know this was solved, but this works for me on debian w/usb realtek usb adapter, little overcomplicated, but keeps bt responding, add a crontab job to run it every few minutes.

#!/bin/bash

# Set lock file path
LOCK_FILE=~/usbresetBT/resetusb.lock

LOG_FILE=~/usbresetBT/resetusb.log


# Check if log file exists and create if it doesn't
if [ ! -e "$LOG_FILE" ]; then
    touch "$LOG_FILE"
fi

# Check if lock file exists
if [ -e "$LOCK_FILE" ]; then
    # Check if lock file is older than 20 minutes
    if find "$LOCK_FILE" -mmin +20 | grep -q .; then
        echo "$(date +"%b %d %T") Lock file is older than 20 minutes, removing lock file" >> ~/usbresetBT/resetusb.log
        rm "$LOCK_FILE"
    else
        echo "$(date +"%b %d %T") Script is already running, exiting" >> ~/usbresetBT/resetusb.log
        exit 1
    fi
fi

# Create lock file
touch "$LOCK_FILE"

# Set maximum log file size (in bytes)
MAX_LOG_SIZE=20000

# Get the output of bluetoothctl devices command
devices_output=$(bluetoothctl devices)

# Get the number of devices found
num_devices=$(echo "$devices_output" | grep -c "Device")

# Check if the number of devices found is less than 3 (change to your preference).
if [ "$num_devices" -lt 3 ]; then
  echo "$(date +"%b %d %T") TOO FEW DEVICES FOUND: Restarting BT SERVICE!" >> ~/usbresetBT/resetusb.log
  echo "$(date +"%b %d %T") Devices information before restarting:" >> ~/usbresetBT/resetusb.log
  echo "$devices_output" >> ~/usbresetBT/resetusb.log
  echo -n "1-1.3" > sudo /sys/bus/usb/drivers/btusb/unbind
  sleep 1
  echo -n "1-1.3" > sudo /sys/bus/usb/drivers/btusb/bind
  sleep 1
  sudo systemctl restart bluetooth
  if [ $? -eq 0 ]; then
      echo "$(date +"%b %d %T") Bluetooth service restarted successfully" >> ~/usbresetBT/resetusb.log
      sleep 50
      echo "$(date +"%b %d %T") Devices information after restarting:" >> ~/usbresetBT/resetusb.log
      echo "$(bluetoothctl devices)" >> ~/usbresetBT/resetusb.log
  else
      echo "$(date +"%b %d %T") Failed to restart Bluetooth service" >> ~/usbresetBT/resetusb.log
  fi
else
  echo "$(date +"%b %d %T") Devices Responding Normally" #>> ~/usbresetBT/resetusb.log
fi

# Check log file size and rotate if necessary
file_size=$(stat -c%s ~/usbresetBT/resetusb.log)
if [ $file_size -ge $MAX_LOG_SIZE ]; then
    mv ~/usbresetBT/resetusb.log ~/usbresetBT/resetusb.log.old
fi


rm "$LOCK_FILE"

output (removed full mac’s):

Can remove the comment from echo “$(date +”%b %d %T") Devices Responding Normally" #>> ~/usbresetBT/resetusb.log if you want to log when devices are responding normally.

Apr 04 19:51:01 TOO FEW DEVICES FOUND: Restarting BT SERVICE!
Apr 04 19:51:01 Devices information before restarting:

Apr 04 19:51:03 Bluetooth service restarted successfully
Apr 04 19:51:53 Devices information after restarting:
Device 7D:B5:C9
Device CD:E9:44
Device A4:C1:38
Device A4:C1:38
Device D9:B9:C4
Device F6:54:F5
Device A4:C1:38
Device 6E:F7:F1
Device A4:C1:38
Device A4:C1:38
Device CB:C3:CA
Device 2F:DE:0F
Device 4A:DA:80
Device C4:2E:25
Device 0B:78:4B
Device A4:C1:38
Device 54:48:E6
Device 7D:33:BC
Device 38:56:3D
Device C8:8C:1C
Device 11:70:E1
1 Like