Node-Red - V1.2.9 Post to New Topic Keep same payload

Hi I receive a mqtt message from a tasmota zigbee device, the payload is fine but the format of the topic is restrictive and i need to change it. I would like to on receipt of an original message, post with a New topic (same payload) this is based on two conditions a name from the topic and a value from the json, I will give two examples:
I have tried examples with the function at the heart and using inject and debug, most of it is hardcoded and not expandable as i have other sensors "outside_temp" for example

any pointers, examples, will be most appreciated

  1. original message received -
    home/sensor/tele/zb_bridge/Apricot/ZbReceived = {"0xA114":{"Device":"0xA114","Name":"Apricot","Temperature":7.18,"Endpoint":1,"LinkQuality":29}}
    Transposed to
    home/sensor/tele/Apricot_Temp = {"0xA114":{"Device":"0xA114","Name":"Apricot","Temperature":7.18,"Endpoint":1,"LinkQuality":29}}

  2. original message received -
    home/sensor/tele/zb_bridge/Apricot/ZbReceived = {"0xA114":{"Device":"0xA114","Name":"Apricot","Humidity":84.59,"Endpoint":1,"LinkQuality":31}}
    Transposed to
    home/sensor/tele/Apricot_Hum = {"0xA114":{"Device":"0xA114","Name":"Apricot","Humidity":84.59,"Endpoint":1,"LinkQuality":31}}

As the topic is the same for both you can simply subscribe to that topic & use a switch to test msg.payload having key Humidity or having key Temperature. Then direct the 2 outputs of the switch to 2 change nodes that set the topic to what you want.

A switch with a couple of change nodes. Not tested but this should work.

[{"id":"1cfc7fcf.2436b","type":"mqtt in","z":"1d254cc8.5925b3","name":"RX","topic":"home/sensor/tele/zb_bridge/Apricot/ZbReceived","qos":"2","datatype":"auto","broker":"4c991b46.bd4ce4","x":100,"y":260,"wires":[["744dbea5.57659"]]},{"id":"31c9629f.328f8e","type":"change","z":"1d254cc8.5925b3","name":"Apricot_Temp","rules":[{"t":"set","p":"topic","pt":"msg","to":"home/sensor/tele/Apricot_Temp","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":240,"wires":[["2baffbcf.d49354"]]},{"id":"2baffbcf.d49354","type":"mqtt out","z":"1d254cc8.5925b3","name":"TX","topic":"","qos":"2","retain":"false","broker":"4c991b46.bd4ce4","x":590,"y":260,"wires":[]},{"id":"744dbea5.57659","type":"switch","z":"1d254cc8.5925b3","name":"","property":"payload.Apricot","propertyType":"msg","rules":[{"t":"eq","v":"Temperature","vt":"str"},{"t":"eq","v":"Humidity","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":240,"y":260,"wires":[["31c9629f.328f8e"],["c1ec619e.adb1"]]},{"id":"c1ec619e.adb1","type":"change","z":"1d254cc8.5925b3","name":"Apricot_Hum","rules":[{"t":"set","p":"topic","pt":"msg","to":"home/sensor/tele/Apricot_Hum","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":280,"wires":[["2baffbcf.d49354"]]},{"id":"4c991b46.bd4ce4","type":"mqtt-broker","z":"","name":"mqtt","broker":"mqtt","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"tele/node-red/LWT","birthQos":"0","birthRetain":"true","birthPayload":"Online","closeTopic":"tele/node-red/LWT","closeQos":"0","closeRetain":"true","closePayload":"Offline","willTopic":"tele/node-red/LWT","willQos":"0","willRetain":"true","willPayload":"Offline"}]

Thankyou both for the quick reply, I have deployed the suggestion above, the sensors report every 1hr or so, will report back, i do have other sensors eg
home/sensor/tele/zb_bridge/wine_cellar/ZbReceived = {"0x2F7E":{"Device":"0x2F7E","Name":"wine_cellar","Temperature":10.53,"Endpoint":1,"LinkQuality":81}}

Capture1

Hi this function should do the same and it will not matter which sensor sends the payload. So if sensor 0xA114 or 0x2F7E sends it will adjust the topic

[{"id":"a63116a.b2f7ae8","type":"inject","z":"9b3f9f31.c45298","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"home/sensor/tele/zb_bridge/Apricot/ZbReceived","payload":"{\"0xA114\":{\"Device\":\"0xA114\",\"Name\":\"Apricot\",\"Humidity\":84.59,\"Endpoint\":1,\"LinkQuality\":31}}","payloadType":"json","x":170,"y":1140,"wires":[["4a33f2f3.dc3e94"]]},{"id":"4a33f2f3.dc3e94","type":"function","z":"9b3f9f31.c45298","name":"","func":"const lookingfor = {\"Temperature\": \"Temp\",\"Humidity\": \"Hum\"};\nlet topic = msg.topic.split(\"/\");\nfor(const keyL in lookingfor){\n    for(const keyP in msg.payload){\n        if(msg.payload[keyP].hasOwnProperty(keyL)){\n            msg.topic=`${topic[0]}/${topic[1]}/${topic[2]}/${topic[4]}_${lookingfor[keyL]}`;\n            return msg;\n        }\n    }\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":350,"y":1120,"wires":[["4775edd3.971bc4"]]},{"id":"1f57d850.6b377","type":"inject","z":"9b3f9f31.c45298","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"home/sensor/tele/zb_bridge/Apricot/ZbReceived","payload":"{\"0xA114\":{\"Device\":\"0xA114\",\"Name\":\"Apricot\",\"Temperature\":7.18,\"Endpoint\":1,\"LinkQuality\":29}}","payloadType":"json","x":170,"y":1080,"wires":[["4a33f2f3.dc3e94"]]},{"id":"4775edd3.971bc4","type":"debug","z":"9b3f9f31.c45298","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":680,"y":1060,"wires":[]}]

[edit added creating topic with device name e.g. apricot or wine celler]

Just re-looking at your payload and you will have to use the mag.payload "has key" test in the switch instead of the "==" test.

ok thankyou noted, i will have a play later cheers

You would have to also set the property to payload["0xA114"] as the key you are looking for is not in msg.payload.
If you wanted the switch node to accept any sensor, then you could set the property to JSONata expression payload.*

Thanks for this i have set this up as follows, assume i use the function in this way ?
The inject works fine but i cant seem to read an output from the function, when the mqtt message is received

Your mqtt node is not set to output an object, it is outputting a json string. In the mqtt node select a parse json object from the dropdown list.

brilliant its working - i can adapt for other sensors, i'll post the code later

To add other sensors just add an entry for the value you want i.e. "BatteryPercentage": "Batt_per" to the looking for object.

Great got it, its working reliably, i have added an additional topic "Temperature": "Temp/SENSOR" a bit crude bit it works

[{"id":"cb10aeed.05f76","type":"tab","label":"2nd post from forum E1cid","disabled":false,"info":""},{"id":"a63116a.b2f7ae8","type":"inject","z":"cb10aeed.05f76","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"home/sensor/tele/zb_bridge/Apricot/ZbReceived","payload":"{\"0xA114\":{\"Device\":\"0xA114\",\"Name\":\"Apricot\",\"Humidity\":84.59,\"Endpoint\":1,\"LinkQuality\":31}}","payloadType":"json","x":570,"y":220,"wires":[["4a33f2f3.dc3e94"]]},{"id":"4a33f2f3.dc3e94","type":"function","z":"cb10aeed.05f76","name":"","func":"const lookingfor = {\"Temperature\": \"Temp/SENSOR\",\"Humidity\": \"Hum/SENSOR\"};\nlet topic = msg.topic.split(\"/\");\nfor(const keyL in lookingfor){\n    for(const keyP in msg.payload){\n        if(msg.payload[keyP].hasOwnProperty(keyL)){\n            msg.topic=`${topic[0]}/${topic[1]}/${topic[2]}/${topic[4]}_${lookingfor[keyL]}`;\n            return msg;\n        }\n    }\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":840,"y":180,"wires":[["4775edd3.971bc4","4efc8065.06ab6"]]},{"id":"1f57d850.6b377","type":"inject","z":"cb10aeed.05f76","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"home/sensor/tele/zb_bridge/Apricot/ZbReceived","payload":"{\"0xA114\":{\"Device\":\"0xA114\",\"Name\":\"Apricot\",\"Humidity\":88.61,\"Endpoint\":1,\"LinkQuality\":18}}","payloadType":"json","x":570,"y":160,"wires":[["4a33f2f3.dc3e94"]]},{"id":"4775edd3.971bc4","type":"debug","z":"cb10aeed.05f76","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":300,"wires":[]},{"id":"7226a5a8.ccb0cc","type":"mqtt in","z":"cb10aeed.05f76","name":"","topic":"home/sensor/tele/zb_bridge/#","qos":"2","datatype":"json","broker":"4b0d18d9.f511b8","x":600,"y":60,"wires":[["4a33f2f3.dc3e94","7c410c4e.56d5f4"]]},{"id":"7c410c4e.56d5f4","type":"debug","z":"cb10aeed.05f76","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":880,"y":60,"wires":[]},{"id":"4efc8065.06ab6","type":"mqtt out","z":"cb10aeed.05f76","name":"","topic":"","qos":"","retain":"","broker":"4b0d18d9.f511b8","x":1110,"y":180,"wires":[]},{"id":"4b0d18d9.f511b8","type":"mqtt-broker","name":"MQTT Broker","broker":"172.16.1.199","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.