Home Assistant, Tasmota, and the Sonoff Zigbee Bridge

werner
12 min readOct 26, 2023

Customising this small, inexpensive Zigbee to (insert your network protocol here but I prefer ZHA) bridge to be part of your Home Assistant network.

Introduction

There are many ways to skin a cat, and so there are many ways to set up a smart home...

A crucial component in this process is setting up a bridge. This allows all of your Zigbee compatible devices — for example Ikea Tradfri, Lidl Livarno, and a whole galaxy of sensors and bulbs — that require reliable, efficient, low bandwidth communications to function, talk to your TCP/IP based network, which could also have additional WiFi based sensors and lightbulbs connected to it — as well as the odd Bluetooth device.

There are various hardware options available, the most popular being something like the Conbee 2 “do-it-all” stick and other devices based on the Texas Instruments CC2531 Chipset. However, in my opinion, this (USB-stick based) approach has various drawbacks:

  • Requires a host machine (like a PC or Raspberry Pi) to function — which can lead to interference on Zigbee frequencies, and tends to be stashed away in a cupboard or under a desk resulting in limited range, not to mention the tight coupling with the host operating system.
  • Initial pairing and adding a new device is cumbersome as you have to either move the lightbulb near the stick, or move the stick (and its host computer) to the lightbulb.
  • And (for me the most important) — because the stick is then tied to a host — you could loose your 100+ paired device network if something goes wrong and cannot power cycle your host independent of your Zigbee controller.

So when news broke of a new class of ESP based Zigbee to Wi-Fi bridges surfaced, I ended up getting the Sonoff Zigbee Bridge because:

  • It is standalone with a very low power draw (I can run it with a 10000mAh power bank for many moons)
  • Sonoff devices are built around the ESP8266/32 family of MCUs, so they are very hackable/customizable.
  • I can choose the optimal position to place it in my home by running it off a standard USB charger, and in some cases when I need to pair a new device, I can plug it into a power bank and go wherever needed.
  • Although it is still using an “old” ESP8266, I will keep an eye out for something ESP32-H2 based in the future — if required.

The Goal

My end goal for this project is to have a standalone, always on, reliable “fire and forget” Zigbee bridge which functions completely on my internal network and is bi-directionally integrated (i.e. no polling or other shenanigans) with Home Assistant with as little latency as possible.

This calls for:

  • Custom firmware — Sonoff stock firmware is a bit cludgy and could be partially workable by using cloud based triggers, which will require packets leaving my network in addition to introducing massive latency.
  • No MQTT — Although efficient, it requires a broker (another hop / point of failure) and can increase latency depending on configuration.
  • Easy, reliable and reproducible configuration and integration with Home Assistant.

The Process

So we need to flash some firmware and get the bridge set up on the internal network talking to Home Assistant, from where Zigbee devices can be paired, controlled and automated as required.

Bill of Materials (BOM)

  • Sonoff Zigbee Bridge
  • A computer with python installed (I’m using an ancient ~2013 Macbook Pro)
  • FTDI FT232-RL Flasher (A relatively cheap addition to any hardware hackers’ toolbox)
  • A breadboard
  • 5 or 10 x Male/Male or Maile/Female breadboard jumper leads

Step 1: Open it up

  • Remove the rubber pads on the bottom to reveal some screws.
Will peel off the plastic at the end. Yee!
  • Unscrew the four screws and open it up
Circuit board porn.
  • Pop out the circuit board and have a look at it:

As you can see (typical for Sonoff), an effort was made to clearly label significant headers / contacts on the board, making our lives a whole lot easier.

Although there is also a 5V contact, DO NOT USE THIS to flash the board. You will fry it and will have to buy a new one.

For interest, on the top of the board, you can clearly see the ESP board soldered on the bottom of the carrier board. There is also the Zigbee controller (to the top right of the ESP) and associated LED, power and USB interface components.

Step 2: The Flash

Now we need to flash our custom firmware, and the best candidate by far is Tasmota — a very popular open source firmware project for ESP based devices with good community support and lot’s of documentation.

Some of my favourite features for this use case:

  • Easy setup — A freshly flashed device creates a Wi-Fi hotspot to which you can connect and configure your actual Wi-Fi network and credentials for it to connect to.
  • OTA updates — Once flashed with Tasmota, you very rarely have to do it ever again as the firmware can then be updated Over-The-Air using the web interface.
  • Interactive (web based) console — Here you can see log output and issue commands directly to the device.

1 — Prepare the board

The first thing to do is prepare the board for flashing. For this I suggest using some “Sticky Tac” to temporarily fix the circuit board and FTDI to a breadboard as you will have to lightly “jam” the ends of the jumper cables into the points indicated previously and you could risk one jumping out mid flash if everything is not nice and stable.

You could also whip out your soldering iron and solder on some headers, but because we rarely need to re-flash, I consider it a waste of time not to mention the risk of damaging the board.

Note that it requires a bit of force to get the pin from the lead to stay in the connector hole on the Zigbee board, although once in, it’s fairly stable unless you bump too hard on a wire or there is unwanted tension on it.

You could also do it with less wiring (by plugging the FTDI straight into the breadboard), but I found this creates too much tension in the leads for my liking, so I followed a “loose” (or messy?!) approach.

Wire the leads up according to the following steps:

  • SET THE POWER JUMPER ON THE FTDI FLASHER TO 3V!!
  • Connect the TX of the FTDI to the ERX contact
  • Connect the RX of the FTDI to the TRX contact
  • Connect +ve of the FTDI to the 3v3 contact
  • Connect -ve (GND) of the FTDI to both the GND contact as well as the RST (IO0) contacts.

The reason we pull IO0 (RST) low (i.e. connect it to -ve / ground ) is to indicate to the ESP chip that it should enter flash mode on startup. This is standard practice for flashing any ESP based chip. If not done it will simply boot the current firmware (if any)

2 — Prepare the firmware

I go with a completely command line based approach here.

There are things like Tasmotizer that gives you a nice UI, but I prefer having full control over the process for various reasons.

a) Install esptool

$ pip install esptool

OR (if you prefer more control like me):

git clone git@github.com:espressif/esptool.git ~/.tools/esptool;
ln -s ~/.tools/esptool/esptool.py /usr/bin/esptool

b) Plug in the FTDI and identify the port on your computer it is bound to.

It’s alive!

There are various ways to get a pointer to the USB interface of the FTDI board depending on your operating system, but on MacOS I usually just run the following:

$ ls /dev | grep usb
tty.usbserial-00000000

Which in my case indicates that the FTDI is reachable through /dev/tty.usbserial-00000000 which I will refer to as <port> in the following commands.

c) Query the board

$ esptool -p <port> flash_id
esptool.py v3.3-dev
Serial port /dev/tty.usbserial-00000000
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 84:cc:a8:94:db:f5
Uploading stub...
Running stub...
Stub running...
Manufacturer: a1
Device: 4015
Detected flash size: 2MB
Hard resetting via RTS pin...

So we are dealing with an ESP8266EX MCU with WiFi and a 2MB flash size.

d) Backup the current (original) firmware

I always like to backup whatever firmware a device came with in case I ever have to restore it.

$ esptool -b 115200 --port <port> read_flash 0x000000 0x200000 ~/.backup/firmware/sonoff_zigbee_bridge_original_firmware_2M.binesptool.py v3.3-dev
Serial port /dev/tty.usbserial-00000000
Connecting...
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 84:cc:a8:94:db:f5
Stub is already running. No upload is necessary.
2097152 (100 %)
2097152 (100 %)
Read 2097152 bytes at 0x0 in 196.6 seconds (85.3 kbit/s)...
Hard resetting via RTS pin...

As you can see, I set the baud rate to 115200(fairly common for ESPs) with the command read_flash and the start / end addresses (note that the previous step reported a 2MB flash memory size, so here we indicate we want to read the entire flash memory), and then finally the filename to write it to.

e) Erase the current firmware

Next we erase the current firmware to give us a “clean” flash target for the Tasmota firmware.

$ esptool --port <port> erase_flashesptool.py v3.3-dev
Serial port /dev/tty.usbserial-00000000
Connecting...
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 84:cc:a8:94:db:f5
Stub is already running. No upload is necessary.
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.0s
Hard resetting via RTS pin...

f) Finally, time to flash the Tasmota firmware!

Note, we are not flashing the standard Tasmota firmware, instead we want the tasmota-zbbridge version. You can find the latest Tasmota firmware binaries listed here

  • Download tasmota-zbbridge.bin here
  • Then flash it to the Sonoff Zigbee Bridge
$ esptool --port <port> write_flash -fs 1MB -fm dout 0x0 ~/Downloads/tasmota-zbbridge.binesptool.py v3.3-dev
Serial port /dev/tty.usbserial-00000000
Connecting...
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 84:cc:a8:94:db:f5
Stub is already running. No upload is necessary.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x000a7fff...
Flash params set to 0x0320
Compressed 687824 bytes to 484618...
Wrote 687824 bytes (484618 compressed) at 0x00000000 in 43.2 seconds (effective 127.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...

And that’s it! After some flashing lights and hopefully no burny smells :), you can unplug the FTDI, then unplug all the jumper cables, and finally place the board back into its case.

At this stage I suggest to not screw the case back together until everything is set up and you are sure you won’t need to re-flash for some reason.

Step 3: The configuration

“Sticky Tack” attached and booted

First thing to do will be to power your newly flashed board over its micro USB port. Once powered up, it starts a web server and a Wi-Fi “hotspot” to which you can connect to configure it for the first time.

For the excitement of running around pairing your first Zigbee device I suggest using a power bank.

So, use a smartphone or computer and connect to a Wi-Fi network called tasmota_xxxxx (Where xxxxx will be some unique identifier).

Once connected, and in most cases, you will automatically get the typical Wi-Fi hotspot login popup you find in many public spaces, but if you don’t, browse to http://192.168.4.1 using a browser on the device.

Either way you should be presented with a screen like this:

I suggest you tick the show password box and ensure you enter it correctly

It is of UTMOST importance to get the SSID (Network Name) and Password correct here as you will have to re-flash the device if you get it wrong (i.e. the pairing button on the board does not reset Tasmota)

Once you hit save. The board will reboot, and will connect to your Wi-Fi on startup.

Notes

  • If you find the Sonoff disconnects randomly from your WiFi network — it can help to create a seperate “guest” network for it to use — which is probably not a bad idea anyway since having a dedicated IOT network isolated from the rest of your network is always a good idea. Most routers allow you to create additional or “guest” networks on your existing wifi.
  • I also suggest finding the Sonoff MAC address on your router and configuring a static IP (outside your DHCP range) for it — in my case that’s 192.168.1.210

Next, we need to configure a few things:

  1. Go to Configuration → Configure Module

2. Select module 75 (Sonoff ZbBridge)

3. Click save and wait for device to reboot. When you reload the tasmota web page, you will see

The bridge should now be using the ZbBridge module with the additional Zigbee related menu options (although this is not the state we want it in for ZHA)

Next download the (latest) ota file here in another tab, and come back here and click Firmware Upgrade (we need to upgrade the Zigbee chip interface now)

In the Upgrade by file upload choose the ota file you downloaded and start upgrade.

If you are following the console on another tab — you should see some activity:

When it’s done, we finally set the bridge to use Module 0 — so in the command input above paste:

Backlog Template {"NAME":"Sonoff ZHABridge","GPIO":[56,208,0,209,59,58,0,0,0,0,0,0,17],"FLAG":0,"BASE":18,"CMND":"Rule1 on system#boot do TCPStart 8888 endon"} ; Rule1 1; Module 0

This will reboot the bridge into Module 0 and when you reload, you should see a “reduced” menu:

And double checking the console output you should see that the TCP server has started on port 8888…

Success!

Step 4: Home Assistant Setup

Finally we get to integrating this into HA — which is fairly easy.

I like to keep the tasmota console open while I do this so you can see what’s happening (open web browser with your Tasmota IP address, and select Console)

Tasmota Console

In Home Assistant → Settings → Integration — Add New Integration…

and search for Zigbee Home Automation

Select Radio Type (EZSP)

For Serial Port select — Enter Manually

Then use the Sonoff IP address as socket address (Tasmota console should confirm port). I also like to set port speed to 115200 — because… and data flow to software

Next up — Keep radio settings (This is basically about the Zigbee network that may / may not yet be configured on Tasmota) and the devices in that address list become entities in Home Assistant.

Then wait…

Then (hopefully) great success!!

You can now start pairing Zigbee devices — read more @ https://www.home-assistant.io/integrations/zha/

I hope you had success in setting this up. Well worth it when everything works out.

Godspeed!

--

--