Flashing the SonOff USB Zigbee dongle

A while ago I purchased a SONOFF ZigBee 3.0 USB Dongle Plus on aliexpress. Finally I am coming around to using it for domotica around the house via Home Assistant.

Last week I had an interesting call with a friend of mine. He switched from ZHA to Zigbee to MQTT and he boasted about it having better device support. Since I had some issues with my smart radiator valves, I thought I’d give zigbee2mqtt a try.

Looking at the adapter list of zigbee2mqtt I was in luck to find my Zigbee USB dongle in there. Since I was moving away from ZHA, I decided to update (firmware upgrade) my USB dongle as well. The documentation references a DOCX and is quite Windows centric. Time for a Linux writeup.

boot mode

To update the firmware you need to put the USB dongle into boot mode (e.g. make it writeable), which can apparently be done with hardware switches (you will need to screw open the device for that, which I did not try). But there is also the possibility of using software to put the dongle into boot mode. This is done with uartLog.py, which did not work on Linux. After a tiny modification it worked (I’m calling it uartLog_linux.py). Note: after each read or write (e.g. modification) the boot mode will be disabled and you will need to enable it again (if needed).

user@host:~/$ python uartLog_linux.py
This is a debug log
This is an info log
This is critical
An error occurred

/dev/ttyUSB0 - Sonoff Zigbee 3.0 USB Dongle Plus
选择串口(输入串口序号即可):0
>>>>>>>>>>>>>>>> /dev/ttyUSB0 is opened.....
<queue.Queue object at 0x7f70c8649930>
<queue.Queue object at 0x7f70c86499f0>
Write  processing...
Write  processing...
Read processing...
Log Print processing...
>>>>>>>>>>>>>>>> end

reading and writing data

Decided to use cc2538-bsl to modify the firmware, which worked like a charm. First I tried to make a backup of the current data, just in case something went wrong. In the end I did not use this backup file, so I am unsure if it even would have been useable or not. The ERROR at the end seemed quite common and as such I ignored it.

user@host:~/git/cc2538-bsl master$ ./cc2538-bsl.py -p /dev/ttyUSB0 -b 115200 -r 20220508.bin
Opening port /dev/ttyUSB0, baud 115200
Connecting to target...
CC1350 PG2.0 (7x7mm): 352KB Flash, 20KB SRAM, CCFG.BL_CONFIG at 0x00057FD8
Primary IEEE Address: 00:12:4B:00:24:C1:66:F8
Reading 524288 bytes starting at address 0x0
ERROR: Timeout waiting for ACK/NACK after 'Mem Read (0x2A)'

Then I continued with flashing the new firmware (after putting the stick into boot mode again):

user@host:~/git/cc2538-bsl master$ ./cc2538-bsl.py -p /dev/ttyUSB0 -b 115200 -evw ~/Downloads/CC1352P2_CC2652P_launchpad_coordinator_20220219.hex
Opening port /dev/ttyUSB0, baud 115200
Reading data from /home/user/Downloads/CC1352P2_CC2652P_launchpad_coordinator_20220219.hex
Firmware file: Intel Hex
Connecting to target...
CC1350 PG2.0 (7x7mm): 352KB Flash, 20KB SRAM, CCFG.BL_CONFIG at 0x00057FD8
Primary IEEE Address: 00:12:4B:00:24:CB:DC:23
    Performing mass erase
Erasing all main bank flash sectors
    Erase done
Writing 360448 bytes starting at address 0x00000000
Write 104 bytes at 0x00057F988
    Write done
Verifying by comparing CRC32 calculations.
    Verified (match: 0xddfc152d)

It seems to have worked like a charm (the stick still works).

A big thank you to all the people to made the software, the firmware and the instructions possible.

closing thoughts

My thoughts on Zigbee2MQTT (compared to ZHA) are:

  • Zigbee2MQTT enabled me to do more and better debugging
  • it has better device support (my radiator valves have more options and properties to use)
  • and provides Over The Air (OTA) updates (which only worked for my smart power plugs, the radiator valves are a corner case apparently, for now)
  • it also integrates excellently with HomeAssistant
  • ZHA is dead to me (but still a big thank you to everyone, the creators, the maintainers and the contributors)