How to make a Sonoff Zigbee 3.0 USB Dongle Plus E become a router on Linux

:zero: Introduction

I bought some Sonoff Zigbee 3.0 USB Dongle Plus E and wanted to use one as coordinator and all others as routers. However they come all configured by default as coordinators. As it took me a long time to find out how do do it on Linux, I share below how I did it so that you can do it quicker than me.

Here are the steps to follow.

:one: Download the latest firmware

You get the latest firmware from GitHub:

$ git clone https://github.https://github.com/itead/Sonoff_Zigbee_Dongle_Firmware.git

In folder Dongle-E you find 2 sub-folders called NCP (for the coordinator firmware) and Router. They contain the firmware file: in Dongle-E/Router, you can find the latest firmware as router. At the date of this article (21-Jan-2024), the firmware file name is Z3RouterUSBDonlge_EZNet6.10.3_V1.0.0.gbl.

:two: Open the Dongle, plug it to the PC and get its device path

  1. Remove the 2 screws on the antenna side and get the dongle out of its casing. It is easier to do the following steps when the antenna is in a longitudinal position or not plugged.
  2. Plug the dongle to the PC.
  3. Get the device path: get the latest line returned by dmesg containing tty:
$ dmesg|grep tty|tail -1
[ 7307.785188] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

The device path is in this case /dev/ttyACM0. Remember it for the next steps.

:three: Connect to the dongle with Putty

Install Putty with your package manager. For example, on Fedora, you can do:

$ sudo dnf install putty

Run Putty and start a serial connection with your device:

  1. Select Category Session, Serial as Connection type and input your device path (/dev/ttyACM0) in Serial line and 115200 in Speed.
  2. Select Category Connection/Serial and type in:
  1. Click on Open. You should get a black window like this:

:four: Launch the bootloader and upload the firmware

You then need to launch the bootloader on the device. This is the tricky part! It is done physically on the device itself. You can see 2 small round black buttons next to each others. To launch the bootloader, you use your index thumbnail to click with a rotating movement first on the reset button (RST) then on the boot button (BOOT). This will (i) click RST, (ii) click BOOT, (iii) release RST, (iv) release BOOT.

When this is done, the Putty terminal show the bootloader menu:

:five: Upload the Router firmware

  1. Open a terminal and go in the directory cloned from GitHub, subdirectory Dongle-E/Router.
    Check that you have the program sx with sx --version. If you do not have it, install package lrzsz with your package manager. For example on Fedora:
    $ sudo dnf install lrzsz
    Prepare the following command (replace the firmware file name and the device path by the ones you determined above in section 1. and 2.) and wait before pressing Enter:
    $ sx -vv Z3RouterUSBDonlge_EZNet6.10.3_V1.0.0.gbl < /dev/ttyACM0 > /dev/ttyACM0
  2. In the Putty terminal, press 1 (upload gbl). You will see begin upload followed by a line of C.
  3. Go back to the terminal where you prepared the sx command and press enter before the C line ends. The upload will start and you will see the progress:

    When the upload is complete, here is what you can see: Serial upload complete
  4. Finally, you can press 2 (run) in the Putty terminal to restart the Dongle as Router and you can start the usual addition of device to the Zigbee Home Automation integration.
1 Like

Very useful. Followed the instructions and was able to flash the firmware onto my dongle without trouble. Unfortunately, I never see it in HA. I’m assuming that it will show up as a Zigbee device and that I should use the normal “add device” process.

I’ve left it connected to the XModem terminal after flashing so I could see what if anything is happening. The first time I flashed it, It went through a long process of hunting for beacons and coming up empty. On attempt 16, things looked better, but then errors that are incomrehensible to me:

> appNwkJoinOrRejoinWhenPowerOn [291]:
 NWK attempt join EVENT, nwk_state = 0x00, appDevHadAttemptNwkJoinTimes = 16
NWK Steering: issuing scan on primary channels (mask 0x0318C800)
NWK Steering: Start: 0x00

> appNwkJoinOrRejoinWhenPowerOn [328]:
 start nwk join EVENT,sta = 0x00
NWK Steering scan complete. Beacons heard: 1
NWK Steering State: Scan Primary Channels and use Install Code
Error: install code setup failed. Is an install code flashed onto the device?
Error: NWK Steering could not setup security: 0xB7
Examining beacon on channel 25 with panId 0x3CF1
NWK Steering joining 0x3CF1 on channel 25
EMBER_JOIN_FAILED
NWK Steering stack status 0x94
NWK Steering trying next network.
No beacons left on current mask. Moving to next state
NWK Steering State: Scan Primary Channels and Use Distributed Key
Examining beacon on channel 25 with panId 0x3CF1
NWK Steering joining 0x3CF1 on channel 25

Later on attempt #28, things looked happier on the terminal:

> appNwkJoinOrRejoinWhenPowerOn [291]:
 NWK attempt join EVENT, nwk_state = 0x00, appDevHadAttemptNwkJoinTimes = 28
NWK Steering: issuing scan on primary channels (mask 0x0318C800)
NWK Steering: Start: 0x00

> appNwkJoinOrRejoinWhenPowerOn [328]:
 start nwk join EVENT,sta = 0x00
NWK Steering scan complete. Beacons heard: 1
NWK Steering State: Scan Primary Channels and use Install Code
Error: install code setup failed. Is an install code flashed onto the device?
Error: NWK Steering could not setup security: 0xB7
Examining beacon on channel 25 with panId 0x3CF1
NWK Steering joining 0x3CF1 on channel 25
EMBER_NETWORK_UP 0x9EED
NWK Steering stack status 0x90
NWK Steering network joined.
>>>> Joined chan = 25, PanId = 0x3CF1, nwkAddr = 0x9EED, txPower = 20
RX: ZDO, command 0x0013, status: 0x00
Device Announce: 0x9EED

> appNwkJoinOrRejoinWhenPowerOn [291]:
 NWK attempt join EVENT, nwk_state = 0x02, appDevHadAttemptNwkJoinTimes = 29

> appNwkJoinOrRejoinWhenPowerOn [360]:
 NWK join EVENT:EMBER_JOINED_NETWORK, app_dev_had_attempt_nwk_join_times = 30
Update TC Link Key: Starting update trust center link key process: 0x00
RX: ZDO, command 0x8002, status: 0x00
RX: Node Desc Resp, Matches: 0x0000
Update TC Link Key: New key established: 0x03
Partner: AD 5E F5 78 F1 AD 1B 00
NWK Steering: Trust center link key update status: 0x03
Update TC Link Key: New key established: 0x65
Partner: AD 5E F5 78 F1 AD 1B 00
NWK Steering: Trust center link key update status: 0x65
EMBER_NETWORK_OPENED: 180 sec
pJoin for 180 sec: 0x00
NWK Steering: Broadcasting permit join: 0x00
NWK Steering Stop.  Cleaning up.
Join network complete: 0x00

Unfortunately, I still couldn’t find it in Home Assistant.

I attempted a reflash, but it just seems to quickly sit in a quiet place and doesn’t do the same hunting again. I don’t know if this is a good sign or not:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[May 15 2022  22:44:15] EZNet_V6.10.3_20220515 chan = 11, PanId = 0xFFFF, nwkAddr = 0xFFFE
EMBER_NETWORK_UP 0x9EED
NWK Steering stack status 0x90
>>>> Joined chan = 25, PanId = 0x3CF1, nwkAddr = 0x9EED, txPower = 20

> appNwkJoinOrRejoinWhenPowerOn [291]:
 NWK attempt join EVENT, nwk_state = 0x02, appDevHadAttemptNwkJoinTimes = 0

> appNwkJoinOrRejoinWhenPowerOn [360]:
 NWK join EVENT:EMBER_JOINED_NETWORK, app_dev_had_attempt_nwk_join_times = 1

My main co-ordinator is superficially the same model, but with the default firmware it came with and about two years older. It reports Firmware: Z-Stack 20210708 in HA.