All field notes
publishedField note 001Home Assistant / Thread / Zigbee

From myQ to Thread.

A 2022 garage-door complaint led to Homebridge, Home Assistant on an Odroid M1, Zigbee2MQTT, Apple Thread credentials, and a 2024 ESP32-S3/H2 Ethernet build that eventually left my network.

The first project was a garage door. I wanted Siri to open it without making me hunt for a phone app from the driver’s seat.

Quick summary

Time invested: a two-year trail from the first Homebridge install to the 2024 Thread build.

Current status: Home Assistant and the Zigbee stack are still in use; the ESP32 border-router experiment is not.

Would I build the exact same thing again? Probably not. I would keep the separation between the systems and make fewer assumptions about what “gateway” means.

Current investigation

The build is finished as a learning record, but the useful question keeps moving: which parts of the stack are worth maintaining, and which were only useful long enough to teach me something?

In 2022, the house had a Chamberlain/LiftMaster myQ garage-door opener. The opener worked. The app worked. The workflow still felt wrong in CarPlay, where opening the door meant reaching for a phone instead of using the assistant already on the dashboard. Someone in the household asked for Siri control.

I had no Homebridge experience, no Home Assistant experience, and no embedded-systems background. I searched for a path that worked with the hardware already installed.

Less than an hour later, Homebridge was running and Siri could open the garage door.

That was the start. I didn’t have a plan for a smart-home lab. I had one annoying workflow and enough curiosity to keep pulling the thread.

Timeline from the myQ garage door through Homebridge, Home Assistant, Zigbee2MQTT, and Matter over Thread
How the project grew. One annoying garage-door workflow became a Home Assistant and networking lab. Original Sudo-Dev illustration.
2022The garage door

One bad CarPlay workflow and a request for Siri control.

NextHomebridge

Siri worked in under an hour. The rabbit hole opened.

LaterHome Assistant

The host, radios, and protocols became a system worth understanding.

2024Ethernet Thread build

Two chips, a daughterboard, several failures, and a board that eventually worked.

NowThe stack that stayed

Odroid M1, Zigbee radios, Thread services, and fewer unnecessary moving parts.

Homebridge solved the first request

Homebridge translated one device into something Siri could see. That was enough for the garage door, but Apple Home stayed in charge of the model. Home Assistant changed the question from “How do I make Siri understand this?” to “What should happen, and which system should control it?”

The host changed more than once: a laptop, a mini PC, then an Odroid M1. Each move bought more room for add-ons and radio services. Zigbee2MQTT gave the house a Zigbee mesh without putting a manufacturer hub between the coordinator and Home Assistant, and that part is still running.

Thread and Matter added another network layer

Matter describes the device and its commands. Thread carries those packets over a low-power IPv6 mesh. A Thread border router connects that mesh to the home IP network; it doesn’t decide how a light or lock behaves.

That distinction matters when several border routers share a home. My setup included Home Assistant’s OpenThread border router, Apple TV and HomePod border routers, and a separate board I built for about a year and a half. Seeing a border router on the network did not prove that it had the credentials for the same Thread network.

The 2024 Ethernet build

Planning started on November 3, 2024. I wrote: “I need to know exactly what list of dev boards I need to build the esp open thread border router with Ethernet. It should just be two boards right?” The question was accurate. The answer depended on which half of the board I meant to flash.

From the notebook · November 3, 2024

“I need to know exactly what list of dev boards I need to build the esp open thread border router with Ethernet. It should just be two boards right?”

Espressif’s ESP Thread Border Router/Zigbee Gateway board combines an ESP32-S3 host with an ESP32-H2 radio co-processor. I paired it with the W5500 Sub-Ethernet daughterboard so the host could use a wired link instead of Wi-Fi.

Labeled illustration of the ESP Thread Border Router board with ESP32-S3 and ESP32-H2 chips connected to its W5500 Sub-Ethernet daughterboard
The 2024 build. ESP32-S3 host, ESP32-H2 radio co-processor, and the W5500-based Sub-Ethernet daughterboard. Original illustration based on Espressif's published hardware documentation; not to scale.

The first ESP-IDF and VS Code setup attempt was November 12. The project layout, Dev Container prompt, and versioned toolchain added another layer to the build. The board was not the only thing being assembled.

By November 22, I had the W5500 configured in menuconfig: SPI host 2; SCLK GPIO 21; MOSI GPIO 45; MISO GPIO 38; CS GPIO 41; 36 MHz clock; interrupt GPIO 39; PHY reset GPIO 40; PHY address 1; Ethernet on; Wi-Fi off; IPv6 address acquisition on. Those values describe my build, not a universal pinout.

The product name combines “Thread Border Router” and “Zigbee Gateway,” so I expected one firmware image to provide both roles. It didn’t. The Thread and Zigbee examples come from separate SDKs. I completed the Thread side; Zigbee2MQTT remained the separate coordinator.

What didn’t work (and why)

  • A build-time compile failure in December 2024: implicit declaration of function 'esp_openthread_set_compatibility_error_callback', on ESP-IDF 5.3.1, reproduced identically on both an M2 Mac Mini and a Debian Bookworm box. That ruled out a macOS-only install problem.
  • Missing build artifacts and stale submodules, including an absent components/heap/tlsf/include path that forced a clean ESP-IDF reinstall.
  • Two separate USB serial devices for one board. The H2 and S3 halves are flashed independently. macOS exposed them as /dev/cu.usbmodem...; the guide I was following used Linux-style /dev/ttyACM... paths, which cost real debugging time before I noticed the mismatch.
  • A RadioSpinelIncompatible boot loop on the S3 after flashing the H2 in April 2025. The host reported that the radio co-processor lacked capabilities it expected.
Build evidence · observed failures
implicit declaration of function 'esp_openthread_set_compatibility_error_callback'

RadioSpinelIncompatible

The first line is the compiler failure from the December build. The second is the boot-loop condition recorded after the April flash. These are failure labels, not a reconstructed transcript.

The December compiler error has a documented cause. I filed esp-thread-br issue #111; Espressif engineer chshu explained that the project had moved ahead of the stable ESP-IDF 5.3.1 release. The choices were to use ESP-IDF master or roll back the project commit. The issue closed two days later after the documentation changed.

I wanted this to have one clean “and then I fixed it” paragraph. It doesn’t. The board eventually worked after matching the two halves and rebuilding cleanly, but I can’t honestly point to one magic command. My brain would love a tidy ending; the evidence gets the final vote.

The April 2025 boot loop was different. Issue #96 describes an older radio co-processor paired with a newer host. The documented remedy is to build both halves with the same ESP-IDF version and flash the H2 directly. My board eventually worked, but I can’t point to one recorded command as the final fix.

The useful evidence came later: the board appeared on the network as a reachable Thread border router beside Home Assistant’s OTBR and Apple’s border routers. The finish was a sequence of clean builds and matching versions, not a single command I can quote.

Apple Thread credentials live behind the ecosystem

Multiple border routers do not prove that the routers share one Thread network. A Thread operational dataset contains the credentials needed to join. Apple-managed Thread credentials are stored and mediated through Apple’s ecosystem; finding an Apple border router and receiving permission to extend its network are separate operations.

At the time, the handoff ran through the Home Assistant Companion app on iPhone and the Thread integration. iOS could provide Apple’s credentials to Home Assistant, giving the integration an authorized dataset instead of only a discovered border router.

The hardware I still use

I don’t own the ESP32-S3/H2 board or its Sub-Ethernet daughterboard anymore. That experiment ended when the hardware left my network.

The current stack is smaller and more concrete: Home Assistant OS on an Odroid M1; Zigbee2MQTT with a SMLIGHT SLZB-07P7 and a separate SONOFF ZBDongle-E; a GL.iNet GL-S200 in the Thread setup; and a Home Assistant Voice Preview Edition that I bought and rarely use.

Illustration of an ODROID-M1, SMLIGHT SLZB-07P7, and SONOFF ZBDongle-E
The hardware that stayed. The ODROID-M1 and two distinct Zigbee adapters: SMLIGHT's CC2652P7-based SLZB-07P7 and SONOFF's EFR32MG21-based ZBDongle-E. Original Sudo-Dev illustration; not to scale.

I still use the system, but maintenance has changed how I think about new devices. Each added ecosystem brings another update path, credential store, radio, and failure mode.

The board worked, then became one more thing to maintain. It is gone now. The Odroid, Zigbee radios, and Thread services are the part of the project that stayed.

What I learned

  • Matter is not Thread. One describes the device layer; the other carries the network traffic.
  • More border routers are not automatically better. Discovery is not proof that the routers share credentials or a common operational dataset.
  • A product label can hide multiple projects. The “Thread Border Router/Zigbee Gateway” board still meant separate firmware paths and separate debugging.
  • The boring stack won. The Odroid, the radios, and the services I could actually maintain outlasted the clever board experiment.

If I started over today

I would start with the system I wanted to keep: Home Assistant on the Odroid, a deliberate Zigbee coordinator, and one Thread path that I could explain six months later. I would treat the ESP32 board as a contained experiment instead of quietly letting it become part of the house.

I would also write down the board versions, SDK commit, flash target, and serial device names before the first build. That would have saved me from rediscovering the same facts while tired. A surprisingly large part of embedded work is just leaving yourself a note before your future self becomes the bug.

This is a personal field note built from my own archived conversations and hardware notes, cross-checked against primary sources where a technical claim needed verification:

$ echo "build it. break it better."_

Back to all field notes