Nodered MQTT (sparkplug) flow

Hi,
I just wanted to share a fully working sparkplug flow for those of you considering using nodered as an Ignition interface.

Here you can test inputs, outputs, DBirth, DDeath, rebirth and probably more…

Screenshot:

I suggest using NPM and installing sparkplug client first like this:

npm install --unsafe-perm sparkplug-client
npm install --unsafe-perm node-red-contrib-sparkplug

I am not completely sure, but my assumption is that you get the latest sparkplug-client this way. contrib-sparkplug is a bit outdated…

Flow: (import flow > paste from clipboard):

[{"id":"67ff7c1a.40a404","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"a81c4e59.6a453","type":"function","z":"67ff7c1a.40a404","name":"Birth message for this device","func":"var msg={\"topic\":\"myMultiSensor01/DBIRTH\",\n\"payload\":{\n    \"timestamp\": Date.now(),\n    \"metrics\":[{\n        \"name\":\"Temperature01\",\n        \"value\":1337,\n        \"type\":\"float\",\n        \"properties\":{\n            \"engUnit\":{\"value\":\"C\",\"type\":\"string\"},\n            \"engHigh\":{\"value\":100,\"type\":\"double\"},\n            \"engLow\":{\"value\":0,\"type\":\"double\"}\n            }\n        },\n        {\n        \"name\":\"Temperature02\",\n        \"value\":1338,\n        \"type\":\"float\",\n        \"properties\":{\n            \"engUnit\":{\"value\":\"C\",\"type\":\"string\"},\n            \"engHigh\":{\"value\":100,\"type\":\"double\"},\n            \"engLow\":{\"value\":0,\"type\":\"double\"}\n            }\n        },\n        {\n        \"name\":\"Output01\",\n        \"value\":false,\n        \"type\":\"boolean\",\n        }]\n    }\n    \n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":940,"y":200,"wires":[["3abcfd2d.b8c002","afc60000.92d74"]]},{"id":"4d95b97.6f42b48","type":"inject","z":"67ff7c1a.40a404","name":"First scan","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":620,"y":200,"wires":[["a81c4e59.6a453"]]},{"id":"3abcfd2d.b8c002","type":"debug","z":"67ff7c1a.40a404","name":"Birth message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1260,"y":200,"wires":[]},{"id":"b7f3b713.742968","type":"function","z":"67ff7c1a.40a404","name":"Metric value for measurement 1","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Temperature01\",\n    \"value\":msg.payload,\n    \"type\":\"float\"}]},\n\"topic\":\"myMultiSensor01/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":930,"y":320,"wires":[["fa0e50aa.109fd","afc60000.92d74"]]},{"id":"18f8e72c.56de49","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1338","payloadType":"num","x":610,"y":320,"wires":[["b7f3b713.742968"]]},{"id":"fa0e50aa.109fd","type":"debug","z":"67ff7c1a.40a404","name":"metric 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1260,"y":320,"wires":[]},{"id":"5d3a0180.3c557","type":"function","z":"67ff7c1a.40a404","name":"Metric value for measurement 2","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Temperature02\",\n    \"value\":msg.payload,\n    \"type\":\"float\"}]},\n\"topic\":\"myMultiSensor01/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":930,"y":380,"wires":[["b3074479.430578","afc60000.92d74"]]},{"id":"d24604eb.11c758","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1338","payloadType":"num","x":610,"y":380,"wires":[["5d3a0180.3c557"]]},{"id":"b3074479.430578","type":"debug","z":"67ff7c1a.40a404","name":"metric 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1260,"y":380,"wires":[]},{"id":"8e01dfde.f35da","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor (output feedback)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":560,"y":440,"wires":[["46e856f8.96bf88"]]},{"id":"46e856f8.96bf88","type":"function","z":"67ff7c1a.40a404","name":"Metric value for output","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Output01\",\n    \"value\":msg.payload,\n    \"type\":\"boolean\"}]},\n\"topic\":\"myMultiSensor01/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":960,"y":440,"wires":[["afc60000.92d74"]]},{"id":"9b5408a7.e077c8","type":"function","z":"67ff7c1a.40a404","name":"Output (from ignition)","func":"if (msg.topic==\"myMultiSensor01\"){\n    if (msg.payload.metrics[0].name==\"Output01\"){\n        newMsg={};\n        newMsg.payload=msg.payload.metrics[0].value;\n        return newMsg;\n    }\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1780,"y":280,"wires":[["398adbd.45a1724"]]},{"id":"398adbd.45a1724","type":"debug","z":"67ff7c1a.40a404","name":"value to sensor","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2000,"y":280,"wires":[]},{"id":"36701b5e.437424","type":"inject","z":"67ff7c1a.40a404","name":"trigger rebirth","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":610,"y":160,"wires":[["a81c4e59.6a453"]]},{"id":"965067a.11efb98","type":"function","z":"67ff7c1a.40a404","name":"DDEATH","func":"let EquipmentName = \"myMultiSensor01\"\n\nreturn { \"topic\" : EquipmentName+\"/DDEATH\",'payload': {\"timestamp\" : Date.now()} };\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1000,"y":120,"wires":[["afc60000.92d74"]]},{"id":"b911110c.4f163","type":"inject","z":"67ff7c1a.40a404","name":"trigger Death","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":610,"y":100,"wires":[["965067a.11efb98"]]},{"id":"deb5ccdd.a451a","type":"debug","z":"67ff7c1a.40a404","name":"Sparkplug Diag","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1760,"y":380,"wires":[]},{"id":"836db305.a26ba","type":"sparkplug","z":"67ff7c1a.40a404","name":"","broker":"tcp://192.168.0.99","port":"1883","clientid":"NodeREDSimpleEdgeNode","groupid":"Sparkplug Devices","edgenode":"Node-RED Edge Node","version":"spBv1.0","enablecache":"false","publishdeath":"true","user":"myUser","password":"__PWRD__","x":1480,"y":500,"wires":[["9b5408a7.e077c8","deb5ccdd.a451a","d4f8fb29.30ee18","7e8c8c04.8b0314"]]},{"id":"d4f8fb29.30ee18","type":"function","z":"67ff7c1a.40a404","name":"external rebirth of all devices from this node","func":"if (msg.topic==\"rebirth\"){\n    return msg\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1850,"y":460,"wires":[["4d1cdf3e.850b4"]]},{"id":"4d1cdf3e.850b4","type":"link out","z":"67ff7c1a.40a404","name":"","links":["8f8845ad.a6ab38","e31740a6.3a29e"],"x":2095,"y":460,"wires":[]},{"id":"8f8845ad.a6ab38","type":"link in","z":"67ff7c1a.40a404","name":"","links":["4d1cdf3e.850b4"],"x":755,"y":260,"wires":[["a81c4e59.6a453"]]},{"id":"90061fa9.fab9","type":"function","z":"67ff7c1a.40a404","name":"Birth message for this device","func":"var msg={\"topic\":\"myMultiSensor02/DBIRTH\",\n\"payload\":{\n    \"timestamp\": Date.now(),\n    \"metrics\":[{\n        \"name\":\"Temperature01\",\n        \"value\":1337,\n        \"type\":\"float\",\n        \"properties\":{\n            \"engUnit\":{\"value\":\"C\",\"type\":\"string\"},\n            \"engHigh\":{\"value\":100,\"type\":\"double\"},\n            \"engLow\":{\"value\":0,\"type\":\"double\"}\n            }\n        },\n        {\n        \"name\":\"Temperature02\",\n        \"value\":1338,\n        \"type\":\"float\",\n        \"properties\":{\n            \"engUnit\":{\"value\":\"C\",\"type\":\"string\"},\n            \"engHigh\":{\"value\":100,\"type\":\"double\"},\n            \"engLow\":{\"value\":0,\"type\":\"double\"}\n            }\n        },\n        {\n        \"name\":\"Output01\",\n        \"value\":false,\n        \"type\":\"boolean\",\n        }]\n    }\n    \n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":960,"y":700,"wires":[["938bc35d.9c5ff","9fafc8a4.923c08"]]},{"id":"ad1a3789.3c0128","type":"inject","z":"67ff7c1a.40a404","name":"First scan","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":640,"y":700,"wires":[["90061fa9.fab9"]]},{"id":"938bc35d.9c5ff","type":"debug","z":"67ff7c1a.40a404","name":"Birth message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1260,"y":700,"wires":[]},{"id":"dad285c8.ac0a58","type":"function","z":"67ff7c1a.40a404","name":"Metric value for measurement 1","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Temperature01\",\n    \"value\":msg.payload,\n    \"type\":\"float\"}]},\n\"topic\":\"myMultiSensor02/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":950,"y":820,"wires":[["b94758a0.8dbee8","9fafc8a4.923c08"]]},{"id":"33b62af6.aadbc6","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1338","payloadType":"num","x":630,"y":820,"wires":[["dad285c8.ac0a58"]]},{"id":"b94758a0.8dbee8","type":"debug","z":"67ff7c1a.40a404","name":"metric 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1240,"y":820,"wires":[]},{"id":"7d2171b.3e6e19","type":"function","z":"67ff7c1a.40a404","name":"Metric value for measurement 2","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Temperature02\",\n    \"value\":msg.payload,\n    \"type\":\"float\"}]},\n\"topic\":\"myMultiSensor02/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":950,"y":880,"wires":[["e73c59cb.404988","9fafc8a4.923c08"]]},{"id":"57d8d78.cbbd728","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1338","payloadType":"num","x":630,"y":880,"wires":[["7d2171b.3e6e19"]]},{"id":"e73c59cb.404988","type":"debug","z":"67ff7c1a.40a404","name":"metric 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1240,"y":880,"wires":[]},{"id":"aa2e5891.35cc08","type":"inject","z":"67ff7c1a.40a404","name":"Value from sensor (output feedback)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":580,"y":940,"wires":[["d6a62d37.916f6"]]},{"id":"d6a62d37.916f6","type":"function","z":"67ff7c1a.40a404","name":"Metric value for output","func":"var msg={\"payload\":\n{\"timestamp\": Date.now(),\n\"metrics\":[{\n    \"name\":\"Output01\",\n    \"value\":msg.payload,\n    \"type\":\"boolean\"}]},\n\"topic\":\"myMultiSensor02/DDATA\"}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":980,"y":940,"wires":[["9fafc8a4.923c08"]]},{"id":"7e8c8c04.8b0314","type":"function","z":"67ff7c1a.40a404","name":"Output (from ignition)","func":"if (msg.topic==\"myMultiSensor02\"){\n    if (msg.payload.metrics[0].name==\"Output01\"){\n        newMsg={};\n        newMsg.payload=msg.payload.metrics[0].value;\n        return newMsg;\n    }\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1800,"y":660,"wires":[["4d2fe7ca.bcf5f8"]]},{"id":"4d2fe7ca.bcf5f8","type":"debug","z":"67ff7c1a.40a404","name":"value to sensor","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2040,"y":660,"wires":[]},{"id":"233c2e41.6edff2","type":"inject","z":"67ff7c1a.40a404","name":"trigger rebirth","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":630,"y":660,"wires":[["90061fa9.fab9"]]},{"id":"8baf8d54.c730d","type":"function","z":"67ff7c1a.40a404","name":"DDEATH","func":"let EquipmentName = \"myMultiSensor02\"\n\nreturn { \"topic\" : EquipmentName+\"/DDEATH\",'payload': {\"timestamp\" : Date.now()} };\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1020,"y":620,"wires":[["9fafc8a4.923c08"]]},{"id":"2972a704.992e48","type":"inject","z":"67ff7c1a.40a404","name":"trigger Death","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1337","payloadType":"num","x":630,"y":600,"wires":[["8baf8d54.c730d"]]},{"id":"e31740a6.3a29e","type":"link in","z":"67ff7c1a.40a404","name":"","links":["1f7d5357.830b6d","4d1cdf3e.850b4"],"x":775,"y":760,"wires":[["90061fa9.fab9"]]},{"id":"8a06951f.dc4278","type":"link in","z":"67ff7c1a.40a404","name":"","links":["9fafc8a4.923c08","afc60000.92d74"],"x":1305,"y":500,"wires":[["836db305.a26ba"]]},{"id":"9fafc8a4.923c08","type":"link out","z":"67ff7c1a.40a404","name":"","links":["8a06951f.dc4278"],"x":1195,"y":780,"wires":[]},{"id":"afc60000.92d74","type":"link out","z":"67ff7c1a.40a404","name":"","links":["8a06951f.dc4278"],"x":1215,"y":280,"wires":[]}]
5 Likes