You can make your own Zigbee devices! DIY Zigbee How To

You can make your own Zigbee devices! DIY Zigbee How To

Thanks to these little boards, you can make your own Zigbee devices! Scrap ESPHome and WiFi, these boards let you use the Zigbee network to make smart devices! But wait, why would you want to? Well the Zigbee network has a bunch of benefits – and yes a couple of drawbacks – over the much easier solution, that being WiFi and something like ESPHome. Zigbee is a low power mesh network, which means it’s much better for battery powered devices, and for signal strength thanks to mains powered devices acting as repeaters – hence the mesh in the name. As an example my Philips Hue light bulbs act as repeaters, meaning devices that are too far from the coordinator – the main router/access point if we’re talking in WiFi terms – can still connect just fine, via the bulbs. The other major advantage is that these devices are not, and cannot, connect to the internet. You need a hub of sorts, and as it turns out running your own hub with Home Assistant and a Zigbee dongle is ridiculously easy and means you don’t need to rely on Chinese servers to make your lights work. The downside to Zigbee really is only speed and complexity. If you need to transfer lots of data – like a video doorbell for example – then WiFi is a much better choice, and on the complexity side, up until now it has been nigh on impossible to make your own devices that connect to the Zigbee network, but thanks to companies like Espressif and Silicon Labs it’s now possible.

So, how do you make a Zigbee device? Well you’ll need to start with a little board like this. This is an ESP32 C6 from Seeed Studio, the XIAO ESP32C6 specifically. You can use an ESP32 H2 as well – basically the H2 is the Zigbee/Thread/BLE only version, whereas the C6 is the “big brother” as such and supports WiFi 6 as well. You can also use a Silicon Labs board like this one, although my testing and coding has all been done on the ESP boards so your mileage may vary on that one. Zigbee uses the 802.15.4 standard for low power 2.4GHz networking, but unlike Thread and Matter which at least the former also uses that standard, Zigbee is a full stack protocol, meaning Zigbee handles both the application layer – what is said between devices – and the communications layer – how things are said between devices. Matter is just the application layer, and requires a communications protocol like Thread or WiFi to actually do anything. Zigbee is also much easier to work with on an individual basis, as devices you create connect as if they were any other professional device, whereas Thread and Matter devices need certification to create the QR code needed to commission devices. This means you can make a Zigbee device, and then just start using it as if you’d bought it, and that’s perfect.

As for the actual how, that’s where we start to get into the nerdy weeds – so I’ll understand if that isn’t for you – but let’s start looking at some code. Let’s look at what options for devices we have based on the examples. In no particular order, we can make: a CO2 sensor; a colour dimmable light; a colour dimmer switch; a dimmable light; an occupancy sensor; a basic on off light; an on off light switch; a pressure and flow sensor; a device to scan available networks; a sleepy temperature and humidity sensor; a basic temperature sensor; and a thermostat. To be clear this isn’t every type of Zigbee device possible – here’s that list, as you can see there’s a fair few more options – but this is all that the Espressif Zigbee library owners have written for us. 

Let’s look at the on off light example as that’s the simplest option. The Arduino file is remarkably simple. You initialise the light, create a function to be called when the light state is changed – in this case that just toggles the built in LED, but this is where you’d write any code you want for controlling external LEDs or even a relay that then supplies power to the LEDs themselves. You’ll probably want to set the manufacturer and model, assign that setLED function, then add the endpoint and wait to connect to the network. Once connected it drops into the loop, it then just checks if the onboard boot button has been pressed. If so, and it’s held for 3 seconds, it’ll factory reset the board. If not, it toggles the light state. Flashing this to the board – with the Zigbee mode set to “end device” and the partition scheme set to “Zigbee 4MB with spiffs” – we see it connects to Home Assistant just fine, and once connected you can toggle the light from both HASS and the button onboard – and if you do toggle it from the button you can see it’s state being updated in Home Assistant basically instantly. That’s really cool!

I want to also look at the sleepy temperature and humidity sensor, as that’s key for battery powered devices. Looking at that INO file it’s pretty similar to the light for the most part. You initialise the temp sensor, you’ve got a function for what to do to get the new data, but there are a few tweaks. At the end of that measure and sleep function there’s a call to make the ESP drop into deep sleep, and in the setup there’s a call to enable the wake timer with a 55 second sleep time (leaving 5 seconds to be awake and send the data). You’ll also want to set the power source to battery and set the percentage – this can be updated with the setBatteryPercentage command at any time – and finally you’ll need a custom Zigbee End Device configuration to change the keep-alive timer to 10 seconds so it doesn’t break when trying to send data. So, this measures the temperature and humidity – well it would if you’ve actually hooked up a sensor like a BME280 or something like that – reports it, then sleeps for 55 seconds. You can adjust the value at the top to have it sleep for longer or shorter depending on the battery life you want – which at least for this Seeed board I measured at around 63mAh for the three seconds per minute it’s on. By my maths that’s an average of 3.15mAh at most. That’s a very rough measurement though and nowhere near truly accurate – and I suspect the H2 is even more power efficient, so if that’s a concern and you don’t need WiFi that’s likely a better choice. 

The most in-depth part of this little exploration is this – I wrote a backend and example for a light sensor. It took me a couple days to wrap my head around the code, and being able to ape the existing code helps an awful lot, but let me do my best to explain something I have a very tentative grasp of myself. 

Check the video for this bit, there’s a lot!

That backend code is likely pretty imperfect, but it does work, and the ability to create new options is really cool. A lot of the customisation is likely in the “get the data” part of the Arduino file, rather than this sort of backend stuff, but I figured since I was working on it I’d share a little of what I’ve been learning. I would submit a pull request to add this into the official repos, but I can’t work out where to submit all the changes – the esp_zigbee_ha_standard.h file needs updating to support that default config for the light sensor that’s missing, but the version of that file in the official esp zigbee sdk is practically empty, meaning the version from the arduino library must come from somewhere else, and I have no idea where that is. If you have any idea, please do let me know so I can push these new examples, and the couple of bug fixes I’ve found… Anyway, that’s DIY Zigbee as it stands today. I’m sure as these boards get more popular and available more people will do more impressive stuff than this, but I know I’m gonna be tinkering with some Zigbee devices and who knows maybe I’ll make some available at some point too.