A tiny peek into the world of ZigBee.


I have a bunch of hue lights and some hue dimmers at home. Because I was cheap and didn’t want to buy too many dimmers, I decided to make each 4-button dimmer into 4 one-button dimmers, with the functions press for toggle and hold for dim up and then turn to dim down when max has been reached. This I achieved by automations in home assistant.

This has been serving me well for as long as my home assistant has been up, but things happens and the working light switches is kind of important.

I recently switched to using Zigbee2MQTT with the Deconz Conbee II I have, largely because everyone seems to recommend it and it supposedly has much better device support than the software deconz provides themselves. Last, but not least, I like to play and wanted to see why people liked this.

Zigbee2Mqtt will handle all devices you connect to it, and it will translate it all to MQTT. I originally thought I would have to do a lot of stuff in Home Assistant to translate MQTT messages and create devices from it, but it seems I was wrong: Zigbee2Mqtt handles all that for you, as soon as it knows about a device, it will inform and have homeassistant create the device. Neat!

I ran with the same setup for a while, with dimmer functionality in custom home assistant automations, and it worked as well as before. That is, it worked as long as home assistant was up…but a while back, I read up on the magic which makes it all so much more reliable.

The magic I found, was direct binding. I still configure it all through configuration in zigbee2mqtt. But with direct binding, I can basically tell a dimmer «hey, you’re supposed to manage this light!». With this setup, my home assistant box, including zigbee2mqtt, can actually go down/stop working, and the basic dimmer functionality will still work. That should give a tiny bit more WAF…

Before this, I have had a period of unstability in my Kubernetes-platform. Even that seems quite a bit better now, but the last time everything went south and no Hue-dimmers worked was a time I was away from home, but my SO was still at home. If there’s one thing every nerd out there should know, it is that you need to keep tab on what, in your nerdiness, that affects them most, and non-working lights is way up there!

So, I’ll give you a little intro to the tiny bit of Zigbee that I have learnt, and how it should make my light-setup much more stable and my SO happy.

Endpoints

An endpoints is sort of a virtual device. For example a Hue Motion Sensor I have lying around has two endpoints, one endpoint for the core motion sensor functionality, another endpoint for some sensors that it also has: temperature and light.

Clusters

Clusters is sort of the API specification in ZigBee, a light will have an genOnOff-cluster (turn on/off the lights), a genLeveControl cluster (dimming), and perhaps lightingColorControl if it’s a multicolor bulb. There’s also others, but this was an example.

Devices

A device will typically have one or more endpoints, which imlements several clusters. All clusters come in a server flavor and a client flavor. These endpoints and clusters will again have to talk to other devices and clusters. In a naive setup, like I was running until now, everything was set up to talk to my controller, which pretty much implements all clusters I need.

The Zigbee2MQTT documentation has a pretty good description how all of this fits together.

The functionality of Zigbee2MQTT

Zigbee2MQTT (or z2m, for short) listens to messages that are sent to it over the Zigbee network. When you pair a device to z2m, you basically pair all its endpoints and clusters to z2m itself. z2m will then take all these z2m messages, and depending on the configuration of z2m, it will send them to a MQTT broker as events.

MQTT is a standard made for internet-of-things, it is meant for passing messages from and to devices. It has quite a bit of overlap with zigbee, so ZigBee2MQTT just translates zigbee messages to MQTT messages – and vice versa.

MQTT is based upon the concept that a client can subscribe to topics, which is kind of standardized message names. So in the case of home assistant, it will connect to MQTT and subscribe to the topics z2m passes along, leading to the creation of devices in home assistant. It will also notice state changes in those devices, and can in turn manage those devices (i.e. turn off lights) by sending specific MQTT messages the other way, which z2m again translates to ZigBee.

This way, you can have home assistant turn off the light when the off-press of a switch is pressed, and it doesn’t really matter what type of switches or lights it is.

But all of this makes the role of the mqtt broker, zigbee2mqtt and home assistant pretty crucial. If either goes down, a zigbee dimmer/switch won’t work, there’s noone to pass on the command.

Direct binding

And this is where direct binding comes in, which can make this a ton more reliable. A dimmer implements sending on/off events, while a light listens to on/off events. With direct binding, zigbee2mqtt just acts as a true coordinator – it delegates the responsibility! It basically tells the dimmer/switch to send the on/off command directly to a specific light – or even a group of lights. Zigbee has support for grouping devices together, so that you can for example have all the lights in a lamp with 3 bulbs act as one device.

This is done by connecting Zigbee2MQTT clusters on the device endpoints to clusters on other devices endpoints. The flexibility of this is quite device-dependent, some devices will happily let you bind the same cluster on the same endpoint to multiple devices, other devices again are less flexible and can only bind to a single device. Again, zigbee2mqtt device documentation has a pretty good description of this for the devices it supports, giving a pretty good starting idea on how to set up all this.

Practical example: Configuring a dimmer to do what I want.

The Philips Hue 4-button dimmer comes in two variants, the old one and the new one. ZigBee-wise, they work a bit differently. I originally had only old type dimmers, and only two of them in use, with custom home assistant code for what the buttons should do.

Zigbee-wise, the old dimmer and the new dimmers are quite different. They don’t have the same endpoints, and they don’t implement the same events behind the buttons. The old dimmer had a dedicated on-button and a dedicated off-button, and dedicated increase and decrease brightness buttons. The new one have a toggle button, the same brightness button, but the fourth button is a special «hue» button that toggles between two scenes in a dimmer-specific group ID. The new one also supports zigbee 3.0, and is, of course, more likely to get new features in firmware, so I decided to go with the new dimmers – after first having bought a single version two dimmer to verify that I was able to do what I wanted.

Because of usability, I decided to have the same dimmer everywhere, so my decision to go for the new one actually meant I had to get six new dimmers, while I can retire my old ones. Or who knows, maybe I can repurpose them for something else? With z2m and home assistant, I can pretty much have the buttons do anything I want….

After having bound the dimmers to zigbee2mqtt, it was time to play around with mqtt. It’s actually good to start with binding everything to the controller to gather information:

After this, you can put zigbee2mqtt in debug log mode, press some buttons of the dimmer, and watch what really happens. In particular, I am interested in what the hue button does:

[2025-10-16 17:05:30] ESC[34mdebugESC[39m:      z2m:mqtt: Received MQTT message on 'homeassistant/scene/1221051039810110150109113116116_28441/scene_0/config' with
data '{"availability":[{"topic":"zigbee2mqtt/bridge/state","value_template":"{{ value_json.state }}"}],"command_topic":"zigbee2mqtt/Gangdimmergruppe/set","defaul
t_entity_id":"scene.gangdimmergruppe_0_av","device":{"identifiers":["zigbee2mqtt_1221051039810110150109113116116_28441"],"manufacturer":"Zigbee2MQTT","model":"Gro
up","name":"Gangdimmergruppe","sw_version":"Zigbee2MQTT 2.6.2","via_device":"zigbee2mqtt_bridge_0x00212effff06dc53"},"name":"Av","object_id":"gangdimmergruppe_0_a
v","origin":{"name":"Zigbee2MQTT","sw":"2.6.2","url":"https://www.zigbee2mqtt.io"},"payload_on":"{ \"scene_recall\": 0 }","unique_id":"28441_scene_0_zigbee2mqtt"}
'
[2025-10-16 17:05:30] ESC[34mdebugESC[39m: z2m:mqtt: Received MQTT message on 'homeassistant/scene/1221051039810110150109113116116_28441/scene_1/config' with
data '{"availability":[{"topic":"zigbee2mqtt/bridge/state","value_template":"{{ value_json.state }}"}],"command_topic":"zigbee2mqtt/Gangdimmergruppe/set","defaul
t_entity_id":"scene.gangdimmergruppe_1_p<C3><A5>","device":{"identifiers":["zigbee2mqtt_1221051039810110150109113116116_28441"],"manufacturer":"Zigbee2MQTT","mode
l":"Group","name":"Gangdimmergruppe","sw_version":"Zigbee2MQTT 2.6.2","via_device":"zigbee2mqtt_bridge_0x00212effff06dc53"},"name":"P<C3><A5>","object_id":"gangdi
mmergruppe_1_p<C3><A5>","origin":{"name":"Zigbee2MQTT","sw":"2.6.2","url":"https://www.zigbee2mqtt.io"},"payload_on":"{ \"scene_recall\": 1 }","unique_id":"28441_
scene_1_zigbee2mqtt"}'

Now, this is from after I have configured things, but you should be able to glance some messages that states pretty clearly what the group is. I need that button for configuring the Hue button functionality.

Now, I am ready to bind specific endpoints. I can leave the coordinator binding as it is.

For on/off/dimming, I need to bind genlevelControl and genOnOff on endpoint on the dimmer to endpoint 11 on the Mellomgangen light, which is the name of the light I want the dimmer to primarily control.

Zigbee2MQTT actually knows about all these, you’ll be able to see the endpoints and clusters that a device supports, but the Zigbee2MQTT documentation is also quite good for a lot of the devices.

With this binding in place, you can turn on/off and dim up and down the Mellomgangen light with the Gangdimmer, and if you really want to test it, unplug the coordinator device so that it’s not reachable anymore, and everything should still work! How cool is that?

The Hue button

In the debug log, we fished out the group ID for the two scenes it toggles between. This can’t be changed, you’re stuck with this group ID, so you’ll have to create a group in Zigbee2mqtt with that group id, containing the lights you want to control with it. After having created that group, you’ll need to add the lights that the group should control, and finally create two scenes with scene id 0 and 1 which contains the lights I want that this scene could control.

You can pretty much do anything in such a scene, but in my case I wanted it to be a toggle button for all the lights in the hallway. So I just added all the lights in the hallway to the group, and stored all off in scene id 0 and all on in scene id 1. I called the group «Gangdimmergroup», to signify that it’s actally the specific group that gangdimmer controls.

Then, I need to do the binding:

Now, the scene controls (recall_0 and recall_1, they are called), will toggle between all lights on and all lights off. And this is also independent from the rest of my automation system!

In the living room, I wanted to do a trick. I have some spot lights above the coach that is basically only used if someone is reading in the evening. I don’t want it to be turned on when I turn on all the lights in the living room, but I want to turn them off if I turn all off. This can be done, but we need to do a trick.

The scene state is actually stored in the lights at the time that the scene is created. If you later add more lights to the group, the new lights will not get any state set for the previously created scene.

So, what I did was creating the group containing all lights I wanted to turn on first, and then I created the «all lights on»-scene. Then, I added the spot lights I want to turn off (but not on) with the hue button, and create the «all lights»-off scene.

I have 6 dimmers in my house, all of them controls their own light (or group of lights, I treat the spots as one light, dimmer-wise). This means I have 6 dimmer-specific groups, that can be set to control the same or different sets of lights. For example I wanted the spot-dimmers hue-button to also turn on the spots, of course, in addition to all the rest of the spots in the living room. For doing this, I just need to repeat this process for all of my hue dimmers! puh!

All of this, I can of course make as flexible and different as I want, I could have the hue-buttons do completely different things, scene-wise. It’s also possible to alter stuff in zigbee2mqtt by sending mqtt-messages to it, so it’d actually be possible to get home assistant to i.e. have a night version and a day version of the scenes, and then alter the scenes at a specific time of the day! Of course all of that logic won’t work if home assistant or zigbee2mqtt is down, but at least I’ll have basic controls of things working, even with nothing else but the lights and the dimmers themselves running!

Cool, huh? But don’t go overboard if you have a SO, you always need to consider the WAF (wife-acceptance-factor) of what you are doing with things as important as the lights!

, ,

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.