Zigbee2mqtt to Domoticz flow help

This is a flow which changes the state of a zigbee2mqtt group (of bulbs) with an vritual on/off switch in domoticz. The idx=183 is the domoticz object

[{"id":"56035fe2.21c4e8","type":"tab","label":"Keuken_Licht_Group","disabled":false,"info":""},{"id":"17b6b703.ebe381","type":"mqtt in","z":"56035fe2.21c4e8","name":"","topic":"domoticz/out","qos":"2","datatype":"auto","broker":"b90f182d.2e6838","x":134.50003051757812,"y":210,"wires":[["452631d0.ef45a8"]]},{"id":"52d623f.852d35c","type":"comment","z":"56035fe2.21c4e8","name":"Domoticz Switch for Kitchen Light Group","info":"","x":224.00003051757812,"y":157,"wires":[]},{"id":"452631d0.ef45a8","type":"json","z":"56035fe2.21c4e8","name":"","property":"payload","action":"","pretty":false,"x":288.50006103515625,"y":210,"wires":[["96dc8119.c7418"]]},{"id":"96dc8119.c7418","type":"function","z":"56035fe2.21c4e8","name":"Turn On/Off Z2M Group","func":"if(msg.payload.idx == '183') {\n//if(msg.payload.idx == '268') {\nif(msg.payload.nvalue == '0') {\n    msg.payload.state = 'OFF'\n}\nif(msg.payload.nvalue == '1') {\n    msg.payload.state = 'ON',\n    msg.payload.brightness = 120,\n    msg.payload.color_temp = 350\n}\nreturn msg;\n}","outputs":1,"noerr":0,"x":489.7713928222656,"y":210.00000381469727,"wires":[["5eba5b0b.72b304","25b6c7eb.71f88"]]},{"id":"5eba5b0b.72b304","type":"mqtt out","z":"56035fe2.21c4e8","name":"","topic":"zigbee2mqtt/Keuken_Spots/set","qos":"","retain":"","broker":"1ec43ef1.2b0269","x":762.8785705566406,"y":210.37855529785156,"wires":[]},{"id":"25b6c7eb.71f88","type":"debug","z":"56035fe2.21c4e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":716.2666320800781,"y":323.4499816894531,"wires":[]},{"id":"b90f182d.2e6838","type":"mqtt-broker","z":"","name":"Domoticz","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1ec43ef1.2b0269","type":"mqtt-broker","z":"","name":"Zigbee2mqtt","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"domoticz/bridge/state","birthQos":"0","birthPayload":"online","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Perhaps you are missing something.

The flow I posted above had a comment "ignore emulation only"
You have changed the inject node topic, while the mqtt node topic was already set. The point of those inject nodes was to emulate your output: {"state": "ON", "brightness": 200, "color_temp": 350} (or OFF)

when a zigbee2mqtt/Keuken_Spot1/get/state is published, zigbee2mqtt/Keuken_Spot1 will get the output.

And is that correct ? I would suspect something like: a set and a get (and indeed the documentation describes this as well). If you subscribe to a topic-layer above, you will get everything, be specific and get specific output, or generalize and filter.

On your initial flow I added a debug node after the "set flow.light_state" change node, i got no output. After changing the mqtt topic to zigbee2mqtt/Keuken_Spots or zigbee2mqtt/Keuken_Spot1 i did get an output after running emulation injection node set to zigbee2mqtt/Keuken_Spot1/get/state or without state

"set flow.light_state" change node, i got no output.

Because there is no output, it sets a flow variable, ie: to keep track. (there is output, but that is not relevant)
The point was to click the toggle which emulates your physical remote (and yes it requires an initial state)

To see the flow variables:

And this variable should be ON or OFF?
(Not at home to check)

  • Import the flow
  • Click the "Spot state ON" inject button (this is to set the initial state)
  • check the context data (you may need to click refresh button for the flow context) - context = ON
  • click the toggle inject button, result: OFF

converting this to real life:

  • Remove the "ignore" part.
  • switch your light once manually (check the context data while doing that)
  • replace the toggle inject with an mqtt node, set topic to: zigbee2mqtt/Remote_E1524-E1810

your remote should work.

This is the context data I see:

I told you it is not ON or OFF!
It doesn't matter if the topic is set to:

zigbee2mqtt/Keuken_Spot1/get/state
zigbee2mqtt/Keuken_Spot1/get

Both topics return {"state": "ON", "brightness":200, "color_temp": 350}

So the JSON string needs to be split up first....how do I do that?

if you mean how do you get the 'state' from the flow variable it will depend on if you are using a change node or function node. In a change node you would select 'flow' then use 'light_stats.state. In a function` node you would use something like

var x = flow.get("light_stats.state");

Read the post above where i link to the documentation.

So if I get it right then the

zigbee2mqtt/Keuken_Spot1/get/state

Returns {"state": "ON", "brightness":200, "color_temp": 350} to the change node "set flow.light_state"

the variable $flowContext("light_state.state") will return "ON"? (or OFF of course)
In a Function node var x = flow.get("light_state.state"); will also return "ON"?

and $flowContext("light_state.brightness") would return "200"?
also var x = flow.get("light_state.brightness"); would return "200"?

and $flowContext("light_state.color_temp") would return "350"?
also var x = flow.get("light_state.color_temp"); would return "350"?

If you are looking directly at the msg coming in from MQTT, then no, that is not right bcause it is not in the flow context. You could access the values with msg.payload.state and msg.payload.brightness etc.

What does the flow context node "set flow.light_state" expect to get (or extract) from the mqtt topic: zigbee2mqtt/Keuken_Spot1/get/state then?
It does not only get the state, as the topic name does suggest.

There is no valid topic in zigbee2mqtt to get only the state of a device (maybe the zigbee2mqtt topic and message structure documentation is misleading here?).

zigbee2mqtt/Keuken_Spot1/get/state or zigbee2mqtt/Keuken_Spot1/get
produce the same incoming message from mqtt:{"state": "ON", "brightness":200, "color_temp": 350}

What does work is set a state zigbee2mqtt/Keuken_Spot1/set/state with payload ON or OFF

Or zigbee2mqtt/Keuken_Spot1/set with a JSON payload {"state": "ON", "brightness":200, "color_temp": 350}

I am trying to understand here

In the mqtt-in node, you specify a topic you want to subscribe to. That is all the topic is used for.

The device that publishes using that topic, will (hopefully) be sending data. How that data comes in is controled by the device that publishes the data using that topic. (Note, a device could publish different formats of data using different topics but hopefully the data published using a certian topic will remain the same format.)

In your case it is sending a json object which ends up in msg.payload. If you put a debug node (set to display the 'Complete msg object') on the output of the mqtt-in node, you will be able to see this.

From there on, it is just a matter of accessing the various items in the json object.

That's what I thought too...The idea of this thread was this:

  1. I already have a flow running which sets a zigbee2mqtt Group of bulbs in a certain state when a Domoticz virtual switch is set to ON or OFF....this flow:
[{"id":"56035fe2.21c4e8","type":"tab","label":"Keuken_Licht","disabled":false,"info":""},{"id":"17b6b703.ebe381","type":"mqtt in","z":"56035fe2.21c4e8","name":"","topic":"domoticz/out","qos":"2","datatype":"auto","broker":"b90f182d.2e6838","x":413.5,"y":215,"wires":[["452631d0.ef45a8"]]},{"id":"52d623f.852d35c","type":"comment","z":"56035fe2.21c4e8","name":"Domoticz Switch for Kitchen Light Group","info":"","x":165,"y":215,"wires":[]},{"id":"452631d0.ef45a8","type":"json","z":"56035fe2.21c4e8","name":"","property":"payload","action":"","pretty":false,"x":567.5000305175781,"y":215,"wires":[["96dc8119.c7418"]]},{"id":"96dc8119.c7418","type":"function","z":"56035fe2.21c4e8","name":"Turn On/Off Z2M Group","func":"if(msg.payload.idx == '183') {\nif(msg.payload.nvalue == '0') {\n    msg.payload.state = 'OFF'\n}\nif(msg.payload.nvalue == '1') {\n    msg.payload.state = 'ON',\n    msg.payload.brightness = 200,\n    msg.payload.color_temp = 350\n}\nreturn msg;\n}","outputs":1,"noerr":0,"x":768.7713623046875,"y":215.00000381469727,"wires":[["5eba5b0b.72b304"]]},{"id":"5eba5b0b.72b304","type":"mqtt out","z":"56035fe2.21c4e8","name":"zigbee2mqtt/in","topic":"zigbee2mqtt/Keuken_Spots/set","qos":"","retain":"","broker":"1ec43ef1.2b0269","x":1010.8785247802734,"y":216.3785514831543,"wires":[]},{"id":"b90f182d.2e6838","type":"mqtt-broker","z":"","name":"Domoticz","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1ec43ef1.2b0269","type":"mqtt-broker","z":"","name":"Zigbee2mqtt","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"domoticz/bridge/state","birthQos":"0","birthPayload":"online","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

  1. The zigbee2mqtt Group is also controlled with a dimmer Remote (IKEA E1524/E1810) which is bound to the zigbee2mqtt Group. But since this remote is a "toggle" ON/OFF device, it is not possible to get the ON/OFF state of this device. see JSON: {"linkquality":42,"battery":47,"action":"toggle"}

  2. When the toggle button of the Remote is used to change the state of the Group to ON/OFF, the Domoticz virtual switch does not know that the zigbee2mqtt Group is set to OFF or ON.

  3. So I was looking for a flow example which sets the Domoticz virtual switch in "ON/OFF" sync with the state of the zigbee2mqtt Group.

  4. The topic & message structure of zigbee2mqtt (https://www.zigbee2mqtt.io/information/mqtt_topics_and_message_structure.html) does not allow to get the state of a group, but it does allow to get the state of devices. Therefor I wanted to create the following flow:

  • If the physical remote toggle button is used
  • Then get the state of one of the devices in the group with
    zigbee2mqtt/Keuken_Spot1/get/state or zigbee2mqtt/Keuken_Spot1/get which both return the same JSON string {"state": "ON", "brightness":200, "color_temp": 350}
  • If "state": "ON" Then set Domoticz virtual switch to ON (if not already)
  • If "state": "OFF" Then set Domoticz virtual switch to OFF (if not already)

Not having eithor a Zigbee or Domoticz I'm forced to bow out here. Maybe someone else will be able to help you.

Well maybe you could help me with small function?

When the remote toggle button is used it sends a message: {"linkquality":26,"battery":21,"action":"toggle"}

Now only when this message is received I want to publish zigbee2mqtt/Keuken_Spot1/get, to get the state of the Bulb....something like:

if (msg.payload.action == "toggle"){

activate a publish to zigbee2mqtt/Keuken_Spot1/get

return msg;
}

How is that done in this function node? or should I use a different method to achieve this?

Use a switch node for the if, a change node to set the payload as you need it and then an mqtt node to publish it

2 Likes