Pencil sketch: a brand-new USB Zigbee coordinator covered in cobwebs beside an hourglass with red sand
|

My brand-new SLZB-07 Zigbee coordinator shipped too old: fixing “EZSP protocol version 12 is not supported by host”

After a clone coordinator that shipped with no usable firmware and no working bootloader turned into a fiasco, I bought the community-recommended SMLIGHT SLZB-07. I plugged it into ubuntu1 (my Ubuntu home server) and Zigbee2MQTT printed one line and quit:

Error: Adapter EZSP protocol version (12) is not supported by Host [13-18].

The radio’s firmware ships speaking EZSP 12. Current Zigbee2MQTT (through zigbee-herdsman) wants EZSP 13 through 18, so there is no overlap and it refuses to start. The fix is a roughly 15-minute flash with universal-silabs-flasher; the notes below cover that flash plus picking a Zigbee channel while you are at it.

Enumeration

Plugged in, read the USB descriptor:

  • Manufacturer SMLIGHT, product SLZB-07, real serial number.
  • USB-to-serial bridge is a Silicon Labs CP210x (10c4:ea60).
  • Stable path /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-07_*-if00-port0. I use the by-id symlink because /dev/ttyUSB0 can shuffle across reboots.

The old config carried over from the prequel specified adapter zstack (Texas Instruments’ stack). Wrong family. The SLZB-07 base model is a Silicon Labs EFR32MG21, so the Zigbee2MQTT adapter is ember, not zstack. Fixed that first. With ember, the serial framing connected and the EZSP handshake completed, then the version mismatch above.

The version math: coordinator firmware vs zigbee-herdsman

The radio shipped with EmberZNet 7.3.0.0 build 131, which speaks EZSP 12. Zigbee2MQTT 2.12.0 with zigbee-herdsman 10.4.0 wants EZSP 13 through 18. No overlap.

Decision: this was a fresh install with the Zigbee database still zero bytes, so nothing to preserve. Pinning an old Zigbee2MQTT that still accepts EZSP 12 would freeze me on the deprecated ezsp driver with no security patches, so I flashed the radio forward instead.

Flashing the SLZB-07 firmware with universal-silabs-flasher

Safe sequence: stop z2m, probe, dump-gbl-metadata, flash, probe.

The tool is universal-silabs-flasher 1.1.0. There’s no working prebuilt image at ghcr.io/nabucasa, so I ran it via pip in a throwaway container:

docker run --rm -it --privileged -v /dev:/dev python:3.12 bash
pip install universal-silabs-flasher

--privileged plus the /dev bind give the container the USB serial device; --rm throws it away on exit.

Probe first, to confirm the bootloader reset works and read the current version:

universal-silabs-flasher \
  --device /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-07_*-if00-port0 \
  --bootloader-reset slzb07 probe

--bootloader-reset slzb07 drives the SLZB-07’s CP210x GPIO pins 4 and 5 into the bootloader, not generic DTR/RTS toggling. Printed EmberZNet 7.3.0.0 build 131.

Check the candidate image before writing a byte:

universal-silabs-flasher dump-gbl-metadata skyconnect_zigbee_ncp_7.5.1.0.gbl

It should show fw_type: ZIGBEE_NCP. This catches the two brick cases: a wrong-chip image (an MG24 image on an MG21), or a bootloader/combined image instead of an application image.

Firmware sourcing wrinkle: SMLIGHT serves its SLZB-07 firmware through a dynamic single-page web app, not a plain URL. The USB model runs stock EmberZNet NCP (Network CoProcessor) firmware with no vendor customization, so a same-chip (EFR32MG21) NCP image from NabuCasa’s silabs-firmware-builder is equivalent. I used skyconnect_zigbee_ncp_7.5.1.0.gbl; the metadata check confirms it.

Flash, then probe again:

universal-silabs-flasher \
  --device /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-07_*-if00-port0 \
  --bootloader-reset slzb07 flash \
  --firmware skyconnect_zigbee_ncp_7.5.1.0.gbl

The post-flash probe reported EmberZNet 7.5.1.0 (EZSP 13).

Result: Zigbee2MQTT forms the network

Started Zigbee2MQTT and watched the logs: [INIT FORM] New network formed!, coordinator backup written, MQTT bridge online, auto-registered in Home Assistant. From the error to a live coordinator, about an hour.

Tested with: Zigbee2MQTT 2.12.0, zigbee-herdsman 10.4.0, universal-silabs-flasher 1.1.0, EmberZNet 7.5.1.0.

Picking the best Zigbee channel (scan the wifi first)

Zigbee shares 2.4 GHz with wifi, and changing the channel later means re-pairing every device, so I measured before forming the network. Zigbee channels 11 through 26 span 2.405 to 2.480 GHz; the wifi-safe zigbee channels (15, 20, 25) sit in the gaps between wifi 1, 6, and 11.

My RTL-SDR software-defined radio is no help here (it tops out around 1.7 GHz). The right tool is a wifi radio:

system_profiler SPAirPortDataType

On Linux, nmcli dev wifi list does the same. Closer to zero dBm = louder:

  • Wifi channel 1: three APs, around -74 dBm
  • Wifi channel 6: two APs, -48 dBm
  • Wifi channel 11: three APs, including -28 dBm

Wifi 6 and 11 are both loud. Zigbee 20 would be squeezed between them; 25 sits right above the loudest one. Channel 15 sits between wifi 1 and wifi 6, clear of the -28 dBm signal on wifi 11. Formed the network on channel 15.

Notes

  • USB product string disambiguates variants: bare SLZB-07 = EFR32MG21 = ember; SLZB-07p7 = TI CC2652P7 = zstack. Read the string, don’t guess from the radio family.
  • Wrong adapter family (zstack vs ember) throws a different, more confusing error before you ever reach the EZSP mismatch.
  • No working prebuilt flasher Docker image; pip install universal-silabs-flasher in a throwaway python:3.12 container with --privileged -v /dev:/dev.
  • --bootloader-reset slzb07 drives the CP210x GPIO pins 4 and 5. The Sonoff Dongle-E uses rts_dtr instead.
  • Run dump-gbl-metadata before every flash to catch a wrong-chip image or a non-application image.

This same SLZB-07 coordinator later carried a stranger payload: a $15 Zigbee probe I taped to a GPU and used as a load side channel.


Frequently Asked Questions

How do I update my EZSP firmware?

Stop Zigbee2MQTT first. Use universal-silabs-flasher with probe to confirm bootloader access and read your current version. Run dump-gbl-metadata on the target firmware file to verify chip compatibility and image type (must show ZIGBEE_NCP, not bootloader or combined). Flash with the --bootloader-reset flag set to your device type (slzb07 for the SLZB-07). Probe again to confirm the new version.

What is universal-silabs-flasher?

A Python CLI tool from NabuCasa for flashing Silicon Labs EFR32 Zigbee and Thread radios over serial. It handles bootloader entry via device-specific GPIO resets, firmware validation, and writing. Install from PyPI (pip install universal-silabs-flasher). There’s no working prebuilt Docker image at the expected GitHub Container Registry path.

How do I pick the best Zigbee channel to avoid wifi interference?

Scan your 2.4 GHz environment with a wifi radio (macOS: system_profiler SPAirPortDataType; Linux: nmcli dev wifi list). Note which wifi channels (1, 6, 11) are loudest. Zigbee channels 15, 20, and 25 sit in the gaps between those wifi channels. Pick the gap furthest from your strongest wifi signals. Changing the Zigbee channel later means re-pairing every device, so measure before you commit.

How do I update my SLZB-07 firmware?

The SLZB-07 USB model runs standard EmberZNet NCP firmware with no vendor customization. Use universal-silabs-flasher with --bootloader-reset slzb07 (drives the CP210x GPIO pins 4 and 5 to enter the bootloader). A compatible image is the NabuCasa SkyConnect MG21 NCP build (skyconnect_zigbee_ncp_7.5.1.0.gbl), same EFR32MG21 chip. Verify with dump-gbl-metadata before flashing.

Do I need to re-pair devices after a coordinator firmware update?

No. Flashing the coordinator firmware doesn’t erase the Zigbee network or device pairings. Paired devices reconnect after the coordinator restarts with the updated firmware. Back up your Zigbee2MQTT data directory before flashing as a precaution. If you change the Zigbee channel, that does require re-pairing everything.

How do I update the firmware on an SLZB-06 or Sonoff Dongle-E?

Both use the same Silicon Labs EFR32MG21 chip as the SLZB-07, so the same universal-silabs-flasher method applies. The difference is the --bootloader-reset flag: the SLZB-07 uses slzb07, while the Sonoff Dongle-E uses rts_dtr. SLZB-06 variants may differ, so check the flasher’s documentation for your specific model. I tested this procedure on the SLZB-07 specifically, but the underlying flash protocol is identical across EFR32MG21 devices.

How do I update my Zigbee dongle firmware?

It depends on the chip. Silicon Labs radios (EFR32 family, used in the SLZB-07, Sonoff Dongle-E, and SkyConnect) flash with universal-silabs-flasher. Texas Instruments radios (CC2652 family, used in the Sonoff Dongle-P/Plus and older coordinators) use a different tool, typically cc2538-bsl or TI’s own flasher. Check your dongle’s USB product string or vendor documentation to identify the chip before choosing a tool.

How a CEO uses Claude Code and Hermes to do the knowledge work

A blank or generic config file means every session re-explains your workflow. These are the files I run daily as CEO of a cybersecurity company managing autonomous agents, cron jobs, and publishing pipelines.

  • CLAUDE.md template with session lifecycle, subagent strategy, and cost controls
  • 8 slash commands from my actual workflow (flush, project, morning, eod, and more)
  • Token cost calculator: find out what each session is actually costing you

One email when the pack ships. Occasional posts after that. Unsubscribe anytime.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *