Intro
If you run Home Assistant in Docker (not HAOS or Supervised), setting up a Thread border router is significantly less documented than the add-on based approach. I figured these steps out via a lot of trial and error, so I hope this helps someone!
I got a SONOFF Zigbee Dongle Plus MG24 with the intent to use it as my thread router and keep my ZBT-1 for zigbee. In the end, I migrated my zigbee network over to the SONOFF dongle and converted the ZBT-1 to thread, so this guide will be specific to the ZBT-1.
Step 0: Migrate Zigbee network
Before setting up my ZBT-1 as my thread router, I had to migrate my ZHA network over to my SONOFF dongle. There are plenty of good official guides on how to do that, just bears noting. It's important that the HA docker container no longer claims the ZBT-1 device, so it can be used by our thread router container.
Step 1: Flash SkyConnect to OpenThread RCP firmware
The SkyConnect ships with Zigbee firmware. You need to reflash it to OpenThread RCP. The easiest way is the NabuCasa web flasher (The addon/in HA options will not work for HA Container). Plug the SkyConnect directly into a computer with a Chrome-based browser and visit:
https://skyconnect.home-assistant.io/firmware-update
Select the Thread / OpenThread RCP option and flash.
Step 2: Identify your device paths
With your ZBT-1 plugged in, find it's device path:
ls -la /dev/serial/by-id/
The SkyConnect shows up as a Silicon_Labs_CP2102N device (not with a NabuCasa name).
Something like:
usb-Silicon_Labs_CP2102N_xxxx-if00-port0
Also identify your host's primary network interface:
ip link show
You'll need the interface name, probably something like: eth0, enp60s0 or eno1
Step 3: Add your user to the dialout group
Required for serial port access:
sudo usermod -a -G dialout $USER
Log out and back in for it to take effect.
Step 4: Docker Compose configuration
Add this neat container that runs the HA Open Thread Border Router (OTBR) addon as a standalone docker container (I never got the official OTBR container to work):
otbr:
image: denniswitt/homeassistant-otbr:latest
container_name: otbr
restart: unless-stopped
privileged: true
network_mode: host
environment:
- DEVICE=/dev/ttyUSB0
- BAUDRATE=460800 # OpenThread RCP firmware uses 460800
- BACKBONE_IF=eth0 # Replace with your actual interface name
- FLOW_CONTROL=1 # Required for SkyConnect
devices:
- /dev/serial/by-id/usb-Silicon_Labs_CP2102N_xxxx-if00-port0:/dev/ttyUSB0
volumes:
- /var/lib/thread:/var/lib/thread # Persist Thread network data across restarts
Important notes:
BAUDRATE=460800— the NabuCasa web flasher installs firmware at this baud rate, not 115200FLOW_CONTROL=1— the SkyConnect requires hardware flow controlBACKBONE_IFmust match your actual host interface name, noteth0- The
AUTOFLASH_FIRMWAREvariable shown in some documentation does not exist in this image despite appearing on Docker Hub — flash the firmware manually as described in Step 1 - Port 8081 must be free on your host — this is what the OTBR agent binds to internally regardless of
OTBR_REST_PORT. If something else is using 8081, move it - The migration script that runs on container startup will always show a
TimeoutError— this is harmless and can be ignored. The agent starts successfully afterward
Step 5: Add integrations in HA
Once the container is running, in HA go to Settings → Devices & Services → Add Integration:
- If the Thread integration shows up automatically, ignore it for now
- Add OpenThread Border Router first, pointing at
http://localhost:8081
Step 6: Android — sync Thread credentials
This step was a tricky one. On Android, Matter commissioning routes Thread credentials through Google Play Services. Your phone needs to know about your Thread network before it can commission Thread devices.
After setting up the OTBR and Thread integrations, open the HA companion app and go to:
Settings → Companion App → TroubleShooting → Sync Thread Credentials
Sync the credentials to your phone. You can verify it worked by going to your phone's
Settings → Search 'thread' → Thread Networks
Your network should appear without a crossed-out key icon.
On iOS this step is not required as the HA app handles credential sharing differently.
Step 7: Commission your Thread devices
With credentials synced, go to Settings → Devices & Services → Add Integration → Matter in the HA companion app and scan your device's QR code. BLE must be enabled on your phone and you should be within ~1 metre of the device during commissioning.
Troubleshooting
- Container crashes with "No such device" for eth0 → your
BACKBONE_IFis wrong, checkip link show - Migration script TimeoutError on every start → harmless, ignore it
- "Your device requires a Thread border router" on Android → you haven't synced credentials to your phone yet (Step 6)
- "Unavailable" with crossed-out key in Android Thread settings → same as above
- Port 8081 conflict → something else on your host is using 8081, move it