I recently purchased the XDO BT802 from Amazon. It’s on the list of “Known Working Adapters” on the Bluetooth Integration Page. I had some trouble getting this working on my Raspberry Pi 4 running Raspbian 11 / Bullseye with Home Assistant Core, so while I’m not an expert at either Linux or Bluetooth I thought I’d post how I got this working.
Posts below suggest the ZEXMTE Long Range Bluetooth Adapter has the same chipset, and the process below works for it as well.
You may also find my Xiaomi Mijia LYWSD03MMC Tutorial useful.
NB: if you want an easier option the Sena UD100-G03 is recommended by Home Assistant and I found it was picked up immediately by the Raspberry Pi with no issues at all.
Core Problem
The key problem is that Linux requires a “firmware” / aka Driver to get a piece of hardware working. The firmware for this device is not installed in Raspbian by default, so getting it installed is the key. The error message I was getting in the home assistant user interface was
Failed to start Bluetooth: adapter ‘hci0’ not found
The XSO BT802 appears to have a Realtek RTL8761BU chipset. To download the firmware / driver for this chipset ssh into your Raspberry Pi and run the following commands.
cd /lib/firmware/rtl_bt
sudo wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtl_bt/rtl8761bu_config.bin
sudo wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtl_bt/rtl8761bu_fw.bin
If you have a different model of Realtek chipset you may find it here or here. If they don’t have the “.bin” extension when you download them you’ll have to reload it.
Ensure Bluetooth is Enabled
sudo nano /boot/config.txt
Make sure the following line is NOT anywhere in the file.
dtoverlay=disable-bt
Finding Chipset / Firmware Required
If you’re not sure which driver you need run the command below and look for messages that contain something like the “not found” message below. This should tell you the chipset model and the file you need to find.
dmesg|egrep -i "blu|hci|bt"
[ 1280.353319] bluetooth hci0: Direct firmware load for rtl_bt/rtl8761bu_fw.bin failed with error -2
[ 1280.353343] Bluetooth: hci0: RTL: firmware file rtl_bt/rtl8761bu_fw.bin not found
Once you’ve copied the correct driver onto your Pi reboot the pi with the "sudo reboot"
command. Run the “dmesg” command from above to verify the firmware has been found and installed.
Install Packages
Installing these OS packages seemed to help reduce error messages in the HA logs.
sudo apt-get install libcap2 libpcap0.8-dev tcpdump
sudo apt-get install bluez*
Disable Built-In Raspberry Pi Bluetooth Adapter
See also the notes under “Disable Built-In Raspberry Pi Bluetooth Adapter 2022.09 and newer” below for an alternate and probably better way to disable bluetooth on startup
This page has a fairly simple method to disable the built in USB adapter.
Update 20221029: the old method didn’t seem to run on startup, I’ve added a new method below. I’m using the init.d method from this page.
First work out which adapter you want to disable. For me it was hci1. In short, you run ‘hciconfig -a’ do find the adapter to disable, then you run ‘hciconfig hci1 down’ to disable that adapter. The page goes on to tell you how to automate this with SystemD.
Steps:
hciconfig -a
Work out which of the bluetooth adapters to disable. In this case I want to disable hci1 which is on the UART bus, rather than hci0 on the USB bus.
hci1: Type: Primary Bus: UART
UP RUNNING
RX bytes:1616 acl:0 sco:0 events:93 errors:0
TX bytes:2916 acl:0 sco:0 commands:73 errors:0
Link policy: RSWITCH SNIFF
Name: 'XXX'
Class: 0x2c0000
Service Classes: Rendering, Capturing, Audio
Device Class: Miscellaneous,
HCI Version: 5.0 (0x9) Revision: 0x156
LMP Version: 5.0 (0x9) Subversion: 0x6119
Manufacturer: Cypress Semiconductor (305)
hci0: Type: Primary Bus: USB
UP RUNNING PSCAN
RX bytes:9516 acl:0 sco:0 events:385 errors:0
TX bytes:32162 acl:0 sco:0 commands:264 errors:0
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT
Name: 'USB'
Class: 0x2c0000
Service Classes: Rendering, Capturing, Audio
Device Class: Miscellaneous,
HCI Version: 5.1 (0xa) Revision: 0x9a9
LMP Version: 5.1 (0xa) Subversion: 0x8a6b
Manufacturer: Realtek Semiconductor Corporation (93)
sudo nano /etc/init.d/disable_builtin_bluetooth
- Paste the text below in
### BEGIN INIT INFO
# Provides: disable_builtin_bluetooth2
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable bluetooth on system startup - tw 20221029
# Description: Disable bluetooth on system startup - tw 20221029
### END INIT INFO
echo "Disabling hci1 bluetooth adapter"
/usr/bin/hciconfig hci1 down &
sudo chmod +x /etc/init.d/disable_builtin_bluetooth
-
sudo update-rc.d /etc/init.d/disable_builtin_bluetooth defaults
(or this might just becd /etc/init.d/ then sudo update-rc.d disable_builtin_bluetooth defaults
) - sudo reboot
hciconfig -a
At this point you should only see the bluetooth adapter that you want enabled - parts of the output have been removed for brevity
hciconfig -a
hci1: Type: Primary Bus: UART
DOWN
hci0: Type: Primary Bus: USB
UP RUNNING PSCAN
Disable Built-In Raspberry Pi Bluetooth Adapter 2022.09 and newer
As of HA 2022.09 you also seem to see your bluetooth adapters in the HA dashboard. You will need to go in and disable it in there. It was autodetected for me, then I disabled it.
I’m also using a different method to disable Bluetooth on startup on my R.Pi4.
sudo nano /etc/systemd/system/bluetooth-disable.service
Put this into the file
[Unit]
Description=Disable R.Pi4 built in bluetooth on startup
After=default.target
[Service]
ExecStart=/opt/bluetooth/disable_builtin_bluetooth.sh
[Install]
WantedBy=default.target
sudo nano /opt/bluetooth/disable_builtin_bluetooth.sh
Put this into the file - you will have to use hciconfig -a
to find which hci adapter to disable (the one with bus type UART)
#!/bin/bash
echo "Disabling hci1 built-in bluetooth adapter"
/usr/bin/hciconfig hci1 down &
Make both of the scripts executable (I think this is necessary)
chmod a+x /opt/bluetooth/disable_builtin_bluetooth.sh
chmod a+x /etc/systemd/system/bluetooth-disable.service
Finally run this command to run this script every time the server starts
sudo systemctl enable bluetooth-disable.service
USB Extension Cable
I don’t know if this helps at all, but I have put the USB adapter on a 2m extension cable, with the antenna up as high as I could easily get it. I read that some drives in the Pi can cause Bluetooth interference, and it’s also good to keep the adapter away from WiFi antennas. I’ll have a play with this and update at some point.
List USB Connected Devices
This command lists devices plugged into the Pi USB ports. This doesn’t mean the device is working or has a driver / firmware, just that it’s attached and the Pi can see it.
lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0bda:a725 Realtek Semiconductor Corp. Bluetooth 5.1 Radio
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
List Bluetooth Devices / Interfaces
This command lists the Bluetooth devices plugged into to the Pi.
hciconfig -a
When I run that command I get the following - with some information redacted / removed for brevity. Given I know my external bluetooth device has a Realtek chipset I can tell that hci0 is the device I need to tell Home Assistant to use. Once you’ve done the step to disable the built in bluetooth above it will look different.
hci1: Type: Primary Bus: UART
BD Address: E4:5F:... ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
Name: '...'
Service Classes: Rendering, Capturing, Audio
Manufacturer: Cypress Semiconductor (305)
hci0: Type: Primary Bus: USB
BD Address: 00:E0:... ACL MTU: 1021:6 SCO MTU: 255:12
UP RUNNING
Name: '... #1'
Manufacturer: Realtek Semiconductor Corporation (93)
List Bluetooth IDs
This seems to list the bluetooth adapter IDs.
hcitool dev
Devices:
hci1 E4:5F:01:xx:xx:xx
hci0 00:E0:42::xx:xx:xx
RFKill
I don’t really have any idea what this is, but if your output looks much different from mine maybe look into it.
rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth hci0 unblocked unblocked
1 bluetooth hci1 unblocked unblocked
Scan for Bluetooth Devices
This scans for bluetooth devices near you. Before I did this I plugged in a bluetooth receiver, enabled Bluetooth on my Android phone, and hit “add new device” to wake it up. The output is the IDs of the Bluetooth devices near you.
hcitool scan
If your built in bluetooth is enabled the range will be poor and likely nothing or only the closest bluetooth devices will be picked up.
Bluetooth Ping
Once you have device Bluetooth IDs you can ping the devices.
sudo l2ping -c 1 88:54:xx:xx:xx:xx
Ping: 88:54:xx:xx:xx:xx from E4:5F:xx:xx:xx:xx (data size 44) ...
44 bytes from 88:54:xx:xx:xx:xx id 0 time 7.31ms
1 sent, 1 received, 0% loss
You can also choose which Bluetooth device to ping from with the -i switch. I can ping my Android phone from either bluetooth adapter - see the third post in this thread.
l2ping -c 1 -i hci1 88:54:xx:xx:xx:xx
l2ping -c 1 -i hci0 88:54:xx:xx:xx:xx
Rename Bluetooth Broadcast ID
sudo hciconfig hci0 name ‘NewNameHere’
Python 3.10 Upgrade Error
If you get an error that looks anything like this
[custom_components.ble_monitor] HCIdump thread: Something wrong - interface hci0 not ready, and will be skipped for current scan period.
[custom_components.ble_monitor] HCIdump thread: Trying to power cycle Bluetooth adapter hci0 00:E0:42:8B:77:03, will try to use it next scan period
Try this - tweak it for your setup
sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/bin/python3.10
sudo systemctl restart home-assistant@homeassistant
This answer is documented in the BLE Monitor FAQ, and was originally found in this github question. Both have more detail and options.
Incidentally, to upgrade Python to 3.10 (and probably higher in future) there’s a good tutorial here.