NR to MQTT combine payloads

Hi,

I am using Node-Red to translate my Hubitat sensor to MQTT for use in Domoticz.

The sensor I'm using is an Aqara temperature/humidity/baro(pressure) Zigbee sensor.
This sensor outputs 3 values which I want to combine to 1 single string for use in MQTT.

I've put in the JOIN node. The problem I face is the order of the three payloads. In the JOIN node there is no fixed order, i.e. I don't know how to force the payloads in the right order.

For MQTT the following order is necessary: {"command":"udevice", "idx":1234, "svalue":"tm;hu;lv;ba;pr"}

I've tried to put delay options for humidity and pressure before the JOIN node but this trick does work a few times and later the payloads are again out of order.

Can someone give me some guidance? Thanks.

You could manually put the string together. Keep the 3 values in separate variables and then assemble them in the right order once you have all 3. You would need to keep track of the count of readings.

2 Likes

That's how I would do it. Probably easier/other ways to do it, but I stick to what I know.

3 Likes

Thanks for your help, it's working.

@jonjon - Glad you got it working but I am confused about the join? As far as I know there IS a fixed order but you need to make sure you've declared your "parts" properties correctly.

I did this as a quick test and everything always comes out in the order I set in "parts" regardless of what inject node I click on.. Tried various join types - object, array and string.

Note: You need to set the "index" value for each node you are joining to set the order, in this case 0-2 with index 0 being "dev1:timestamp" and so on. The "count" is the total # of nodes you are joining - in this example it's 3. "id" stays the same for all nodes and "key" needs to be unique - I used msg.topic.

Am I missing something obvious? (would not be the first time..)

2 Likes

@ertrek - I've copied your solution. The 3 change nodes consist of the following code. The JOIN node is programmed as follows. When pressing the individual inject nodes the output is still out of order. When I inject the three nodes at once the output message is in the order I want. The problem is that once in a while the input from my temperature, humidity, pressure sensor is missing certain inputs and the string to MQTT is not composed as it should be.

{
"id": "test",
"index": 0,
"count": 3,
"type": "string",
"ch" :",",
"key": topic1,
"len":""
}

{
"id": "test",
"index": 1,
"count": 3,
"type": "string",
"ch" :",",
"key": topic2,
"len":""
}

{
"id": "test",
"index": 2,
"count": 3,
"type": "string",
"ch" :",",
"key": topic3,
"len":""
}

Maybe I've misinterpretated your post. Probably it's a small change somewhere. But I cannot find it.

That seems odd... here is the sequence from the example above if you want to check it out..

Join Example

[{"id":"0ba57b7075405281","type":"inject","z":"e6807da71ee5477b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev1","payload":"","payloadType":"date","x":1380,"y":740,"wires":[["4068d0348bfe7c76"]]},{"id":"cbf7c8cc89b993f3","type":"inject","z":"e6807da71ee5477b","name":"dev2: $random()","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev2","payload":"$random()","payloadType":"jsonata","x":1380,"y":780,"wires":[["b7dd96c3f49e70ee"]]},{"id":"3306b9bafc057473","type":"inject","z":"e6807da71ee5477b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev3","payload":"TestOutput123123","payloadType":"str","x":1400,"y":820,"wires":[["1ca19f68548e68da"]]},{"id":"534c5a3f8847837d","type":"join","z":"e6807da71ee5477b","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1910,"y":780,"wires":[["0a4b66071a2ee01e"]]},{"id":"0a4b66071a2ee01e","type":"debug","z":"e6807da71ee5477b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2090,"y":780,"wires":[]},{"id":"4068d0348bfe7c76","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 0,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":740,"wires":[["534c5a3f8847837d"]]},{"id":"b7dd96c3f49e70ee","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 1,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":780,"wires":[["534c5a3f8847837d"]]},{"id":"1ca19f68548e68da","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 2,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":820,"wires":[["534c5a3f8847837d"]]}]

edit: the only thing strange is your key definition. You are using JSONATA not JSON right? "topic" refers directly to msg.topic so either put a unique string in there for each or use topic (note: no quotes!) if the message topic coming off each event is unique to those events.

The Join example is from another sequence. Buttons with button-taps.

Maybe you can post the Join example you mentioned. I'll check your programming against mine to find the problem. It's working for you so I must be able to find the culprit.

yeah sorry hang on a sec.. export didn't work for some reason. My copy/paste foo is weak..

Join Example

[{"id":"0ba57b7075405281","type":"inject","z":"e6807da71ee5477b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev1","payload":"","payloadType":"date","x":1380,"y":740,"wires":[["4068d0348bfe7c76"]]},{"id":"cbf7c8cc89b993f3","type":"inject","z":"e6807da71ee5477b","name":"dev2: $random()","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev2","payload":"$random()","payloadType":"jsonata","x":1380,"y":780,"wires":[["b7dd96c3f49e70ee"]]},{"id":"3306b9bafc057473","type":"inject","z":"e6807da71ee5477b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dev3","payload":"TestOutput123123","payloadType":"str","x":1400,"y":820,"wires":[["1ca19f68548e68da"]]},{"id":"534c5a3f8847837d","type":"join","z":"e6807da71ee5477b","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1910,"y":780,"wires":[["0a4b66071a2ee01e"]]},{"id":"0a4b66071a2ee01e","type":"debug","z":"e6807da71ee5477b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2090,"y":780,"wires":[]},{"id":"4068d0348bfe7c76","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 0,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":740,"wires":[["534c5a3f8847837d"]]},{"id":"b7dd96c3f49e70ee","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 1,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":780,"wires":[["534c5a3f8847837d"]]},{"id":"1ca19f68548e68da","type":"change","z":"e6807da71ee5477b","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": \"test\",\t   \"index\": 2,\t   \"count\": 3,\t   \"type\":\"string\",\t   \"ch\":\",\",\t   \"key\": topic,\t   \"len\":\"\"\t}\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1660,"y":820,"wires":[["534c5a3f8847837d"]]}]

Still fixated on that pony, perhaps?

You bet!!!! :heart: :heart_eyes: :rofl:

Ok found it, this is the solution. You've pointed out the JSONATA in the change node. I have used the description to put in the code. That's a failure. I see you are using the set/to the value J:

Many thanks for your help. Now my Zigbee device connected through the Hubitat can talk via Node-Red to my Domoticz server (which I still like for the moment for the easy graphs).

2 Likes

Awesome!

_plancomestogether2