Extend Your Thread Network Coverage with an Affordable ESP32-C6!
This ESPHome configuration turns an ESP32-C6 board into a Thread FTD (Full Thread Device) router that seamlessly integrates with Home Assistant to expand your Thread mesh network and improve connectivity for your Thread devices.
| Requirement | Description |
|---|---|
| 🔧 Hardware | ESP32-C6 board (tested with Seeed Studio XIAO ESP32C6) |
| 🌐 Network | Thread Border Router in network (e.g., Home Assistant with Thread integration) |
| 💻 Software | ESPHome installed |
| 🔌 Cable | USB cable for initial flashing |
| 📦 Optional | 3D-printed case - XIAO ESP32-C6 Case |
💡 Important: The TLV contains ALL network parameters - you don't need to generate or enter anything manually!
✅ Recommended method - via SSH/Terminal:
Step 1: SSH to your Server
Step 2: Retrieve TLV data:
docker exec otbr ot-ctl dataset active -xStep 3: Copy the hex string (e.g., 0e080000000000010000...)
Step 4: Add to secrets.yaml:
thread_tlv: "YOUR_TLV_HEX_HERE"🎉 That's it! The TLV contains:
| ✅ Channel | ✅ Network Name | ✅ PAN ID & Extended PAN ID |
| ✅ Network Key (encrypted) | ✅ PSKc (encrypted) | ✅ Mesh-Local Prefix |
In secrets.yaml you need:
| Key | Description | Required |
|---|---|---|
| thread_tlv | Your Thread network commissioning data | ✅ Required |
Edit secrets.yaml with your Thread TLV:
thread_tlv: "YOUR_TLV_HEX_HERE"That's all you need - no WiFi credentials required!
Connect your ESP32-C6 via USB and flash the firmware using local ESPHome:
esphome run esp32c6-thread-router.yaml --device=/dev/ttyACM0💡 Note: Replace
/dev/ttyACM0with your device path (see troubleshooting below)
📚 Important Notes & Troubleshooting
| OS | Typical Paths |
|---|---|
| 🐧 Linux | /dev/ttyUSB0, /dev/ttyACM0, /dev/ttyUSB1 |
| 🍎 macOS | /dev/cu.usbserial-*, /dev/cu.wchusbserial* |
| 🪟 Windows | COM3, COM4, etc. |
Check available ports:
- Linux/macOS:
ls /dev/tty* - Windows: Device Manager
Standard Linux - Add user to dialout group:
sudo usermod -a -G dialout $USER
# Then log out and back inFedora Atomic/Bazzite with rootless Docker/Podman:
The dialout group doesn't work reliably on immutable systems. You need to fix permissions before each flash:
# Check permissions
ls -la /dev/ttyACM0
# Output: crw-rw----. 1 root dialout 166, 0 ...
# Fix temporarily (resets on USB reconnect)
sudo chmod 666 /dev/ttyACM0
# If using Docker/Podman, restart the container
docker-compose restart
⚠️ Note: You need to runsudo chmod 666each time you reconnect the USB device.
🐳 Alternative: Using Docker/Podman
⚠️ Important: When using Docker/Podman (rootless), you need to fix USB permissions before flashing.
# 1. Start container
docker-compose up -d
# 2. Flash the firmware
docker-compose exec esphome esphome run /config/Thread/esp32c6-thread-router.yaml --device=/dev/ttyACM0📌 Note: The docker-compose.yml mounts the parent
config/directory to/configin the container. That's why you need/config/Thread/in the path above. This is necessary so ESPHome can find the build files in.esphome/.
🌐 Alternative: Web Dashboard (GUI)
Choose between local or hosted dashboard:
Docker Dashboard:
# Start container if not already running
docker-compose up -d
# Start the dashboard
docker-compose exec esphome esphome dashboard /configThen open http://localhost:6052 in your browser and navigate to the Thread folder.
Local Dashboard (requires local ESPHome):
esphome dashboard .Then open http://localhost:6052 in your browser and use the web interface.
Hosted Dashboard (no installation needed):
🎉 No installation needed! Flash directly from your browser.
- Visit https://web.esphome.io/
- Click "Connect" and select your ESP32-C6 device
- Upload your
esp32c6-thread-router.yamlconfiguration file - Click "Install" to compile and flash
Perfect for: Users who prefer GUI over command line, or quick flashing without local ESPHome installation.
🎉 Good news: You can view logs over-the-air even with WiFi disabled!
Logging Options:
🔌 Option A: Serial Connection (USB)
- Always available - Connect via USB cable
📡 Option B: Over Thread Network (OTA)
- Works without WiFi! The device uses its Thread IPv6 address to connect.
esphome logs esp32c6-thread-router.yamlChoose "Over The Air" option when prompted. You should see:
- IPv6 address like
fd3d:8f96:a13d:1:...(Thread mesh-local address) [openthread:xxx] Device Type: FTD- No continuous error messages
# List all Thread devices in network
podman exec otbr ot-ctl router table
# Your ESP32-C6 should appear with Extended MAC and good Link Quality
# Show network state
podman exec otbr ot-ctl state- Go to Settings → Devices & Services
- The ESP32-C6 should appear as a discovered device
- Add it to Home Assistant (use
esp32c6-thread-router.localor IPv6 address) - Check device status - should show "Online"
To flash multiple ESP32-C6 devices and use them as separate routers in the same Thread network:
For each additional device, create a new YAML file (e.g., esp32c6-thread-router-2.yaml):
esphome:
name: esp32c6-thread-router-2 # Must be unique!
friendly_name: ESP32-C6 Thread Router 2 # Optional but helpful
openthread:
device_type: FTD
tlv: !secret thread_tlv # Same TLV = same Thread networkEach device will join the same Thread network and act as an independent router, extending your mesh coverage.
.
├── esp32c6-thread-router.yaml # Main ESPHome configuration
├── esp32c6-thread-router-2.yaml # Optional: Second router
├── esp32c6-thread-router-3.yaml # Optional: Third router
├── secrets.yaml # Shared credentials (not in git)
├── .gitignore # Excludes secrets and build artifacts
└── README.md # This file
| Resource | Description |
|---|---|
| 📖 ESPHome OpenThread Documentation | Official ESPHome Thread component docs |
| 🔗 OpenThread Primer | Learn the basics of Thread networking |
| 🏠 Home Assistant Thread Integration | How Thread works in Home Assistant |
Made by the open source community
⭐ Star us on GitHub • 🐛 Report a Bug • 💡 Request a Feature