# Processing sensor data and structuring node-red-program

**URL:** https://discourse.nodered.org/t/processing-sensor-data-and-structuring-node-red-program/56152
**Category:** Share Your Projects
**Created:** [5 January 2022 14:01 UTC](https://discourse.nodered.org/t/processing-sensor-data-and-structuring-node-red-program/56152 "2022-01-05T14:01:48Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![juntiedt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/juntiedt/32/58357_2.png) [@juntiedt](https://discourse.nodered.org/u/juntiedt)
#### Post date: [5 January 2022 14:01 UTC](https://discourse.nodered.org/t/processing-sensor-data-and-structuring-node-red-program/56152/1 "2022-01-05T14:01:48Z")

</div>

for my floor heating system I had to manage quite a few sensors. I put all sensors in one flow and all my different rooms in seperate flows. I used a flow router (input) to bring the sensor data to the rooms.  
I actually used the same method for my outputs to actors. All outputs like http request, mqtt, websocket, telegram are in one flow with an output router. This turned out to be very effectiv if you had to add new sensors or outputs.  
Attached a basic example:

 ![sensor input](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/2/32e4b12bea8c1a4008fea017f597bdafd3e8bd61.jpeg)

[sensor.txt](https://discourse.nodered.org/uploads/short-url/nyPrg4SEBYwdzvc93txtBVX68OZ.txt) (16.7 KB)

As the flow was to big to post it here just download the txt file.

---

<div class="post-metadata">

### Author: ![juntiedt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/juntiedt/32/58357_2.png) [@juntiedt](https://discourse.nodered.org/u/juntiedt)
#### Post date: [20 March 2022 13:52 UTC](https://discourse.nodered.org/t/processing-sensor-data-and-structuring-node-red-program/56152/2 "2022-03-20T13:52:03Z")

</div>

updated version of sensor object and routing

```auto
[{"id":"eab1516f6ab665a5","type":"switch","z":"77a4781684365cf3","name":"flow router","property":"payload.send_to","propertyType":"msg","rules":[{"t":"eq","v":"flow1","vt":"str"},{"t":"eq","v":"flow2","vt":"str"},{"t":"eq","v":"flow3","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":1170,"y":300,"wires":[["5eae49bedbc1e910"],["082010b3df594541"],["c0f2cc238c3f9dc2"]]},{"id":"dfe81d783fd57341","type":"link in","z":"77a4781684365cf3","name":"flow_router_in","links":["b1fb0e92ce39e921","d7c9d7dbb2eeb0f2","7d0c6ad3b4eea62e","71983a5d4481ea31"],"x":1055,"y":300,"wires":[["eab1516f6ab665a5"]]},{"id":"5eae49bedbc1e910","type":"link out","z":"77a4781684365cf3","name":"router out","mode":"link","links":["33c29b5a726ed66c"],"x":1315,"y":260,"wires":[]},{"id":"082010b3df594541","type":"link out","z":"77a4781684365cf3","name":"","links":["30d05c4b5f80a0c2"],"x":1315,"y":300,"wires":[]},{"id":"8721ac1e9a0b8de7","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":110,"y":160,"wires":[["e87591bcd25842d7"]]},{"id":"e87591bcd25842d7","type":"change","z":"77a4781684365cf3","name":"init sensor offset","rules":[{"t":"set","p":"sensoroffset","pt":"flow","to":"0.5","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":160,"wires":[[]]},{"id":"ba8509f4a360bb5e","type":"mqtt in","z":"77a4781684365cf3","name":"Sensor 1 data","topic":"home/ug/Buero/unipi/1/temp/2892844D07000012","qos":"0","datatype":"auto","broker":"36a1d46c.15334c","nl":false,"rap":true,"rh":0,"inputs":0,"x":110,"y":360,"wires":[[]]},{"id":"7d0c6ad3b4eea62e","type":"link out","z":"77a4781684365cf3","name":"","links":["dfe81d783fd57341"],"x":955,"y":300,"wires":[]},{"id":"8b7b671ec9bc2cb7","type":"function","z":"77a4781684365cf3","name":"add routing information to object","func":"let sensordata = msg.payload;\nlet route = {'send_to':'flow3','type':'HZVL'};\nmsg.payload = Object.assign(sensordata, route);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":770,"y":300,"wires":[["7d0c6ad3b4eea62e"]]},{"id":"9731cf9db29a3c8d","type":"trigger","z":"77a4781684365cf3","name":"time - filter","op1":"","op2":"","op1type":"pay","op2type":"nul","duration":"10","extend":false,"overrideDelay":false,"units":"s","reset":"msg.reset","bytopic":"all","topic":"topic","outputs":1,"x":310,"y":340,"wires":[[]]},{"id":"ebed51f349a2b08b","type":"rbe","z":"77a4781684365cf3","name":"% - filter","func":"deadbandEq","gap":"5","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":300,"y":380,"wires":[[]]},{"id":"415aa050e48993b9","type":"inject","z":"77a4781684365cf3","name":"reset min max","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"reset","x":520,"y":260,"wires":[["ce87e1a8c4dbc99e"]]},{"id":"baf13327520f39ea","type":"switch","z":"77a4781684365cf3","name":"!= previous value","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"","vt":"prev"}],"checkall":"true","repair":false,"outputs":1,"x":330,"y":420,"wires":[[]]},{"id":"42fb581468a416e1","type":"function","z":"77a4781684365cf3","name":"no filter","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":300,"wires":[["ce87e1a8c4dbc99e"]]},{"id":"ce87e1a8c4dbc99e","type":"function","z":"77a4781684365cf3","name":"sensorobject","func":"if (msg.topic === 'reset'){\n context.set('min',0.0);\n context.set('max',0.0);\n return null;\n}\n\n//-------------------------------------------\n\nlet time = Date.now();\nlet sensoroffset = flow.get('sensoroffset');\n// the next 3 lines to be edited per sensor\nlet sensortype = \"one-wire\";\nlet sensorname = \"HZVL\";\nlet sensorlocation = \"DGWZ\";\n//\nlet sensorrawvalue = parseFloat(msg.payload);\nlet sensorvalue = sensorrawvalue + sensoroffset;\nlet sensorobject = {\"sensorlocation\":sensorlocation,\"sensortype\":sensortype,\"senorname\":sensorname,\"sensortimestamp\":time,\"sensorrawvalue\":sensorrawvalue,\"sensoroffset\":sensoroffset, \"sensorvalue\":sensorvalue};\nminmaxobject = minmax(sensorvalue);\nmsg.payload = Object.assign(sensorobject, minmaxobject);\nreturn msg;\n\n//-------------------------------------------\n\nfunction minmax(value){\n let x = parseFloat(value);\n let min = context.get('min');\n let max = context.get('max');\n\n if ((min === 0) && (max === 0)){\n min = x;\n context.set('min',x);\n max = x;\n context.set('max',x);\n }\n else {\n if (x < min){\n min = x;\n context.set('min',x);\n }\n if (x > max){\n max = x;\n context.set('max',x);\n }\n }\n return {'sensormin':min,'sensormax':max};\n}","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nif (context.get(\"min\") === undefined) {\n context.set(\"min\", 0.0)\n}\n\nif (context.get(\"max\") === undefined) {\n context.set(\"max\", 0.0)\n}","finalize":"","libs":[],"x":530,"y":300,"wires":[["8b7b671ec9bc2cb7"]]},{"id":"c0f2cc238c3f9dc2","type":"debug","z":"77a4781684365cf3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1370,"y":340,"wires":[]},{"id":"0b17b744ab851705","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"25.6","payloadType":"str","x":130,"y":240,"wires":[["42fb581468a416e1"]]},{"id":"5335b411815f998f","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"31.7","payloadType":"str","x":130,"y":280,"wires":[["42fb581468a416e1"]]},{"id":"a432eeb37f671c0c","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20.3","payloadType":"str","x":130,"y":320,"wires":[["42fb581468a416e1"]]},{"id":"36a1d46c.15334c","type":"mqtt-broker","name":"","broker":"10.0.0.43","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"MQTT/Development","birthQos":"0","birthRetain":"true","birthPayload":"online","birthMsg":{},"closeTopic":"MQTT/Development","closeQos":"0","closeRetain":"true","closePayload":"offline","closeMsg":{},"willTopic":"MQTT/Development","willQos":"0","willRetain":"true","willPayload":"disconnected","willMsg":{},"sessionExpiry":""}]
```

---

<div class="post-metadata">

### Author: ![juntiedt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/juntiedt/32/58357_2.png) [@juntiedt](https://discourse.nodered.org/u/juntiedt)
#### Post date: [11 April 2022 09:13 UTC](https://discourse.nodered.org/t/processing-sensor-data-and-structuring-node-red-program/56152/3 "2022-04-11T09:13:12Z")

</div>

updated version of sensor object and routing:

- added timestamps to min max values and watchdog

- sensor location and routing to different flow is more clearly defined

- init and reset of flows should be organized in a seperate init or reset flow

```auto
[{"id":"eab1516f6ab665a5","type":"switch","z":"77a4781684365cf3","name":"flow router","property":"payload.send_to","propertyType":"msg","rules":[{"t":"eq","v":"flow_1","vt":"str"},{"t":"eq","v":"flow_2","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1150,"y":300,"wires":[["5eae49bedbc1e910","f1592a072d390dc7"],["143e848171a56697","741a5693cbf3a09e"]]},{"id":"dfe81d783fd57341","type":"link in","z":"77a4781684365cf3","name":"flow_router_in","links":["b1fb0e92ce39e921","d7c9d7dbb2eeb0f2","7d0c6ad3b4eea62e","71983a5d4481ea31"],"x":1035,"y":300,"wires":[["eab1516f6ab665a5"]]},{"id":"5eae49bedbc1e910","type":"link out","z":"77a4781684365cf3","name":"to_flow_1","mode":"link","links":["04ebd35e3b8e1db7"],"x":1295,"y":260,"wires":[]},{"id":"8721ac1e9a0b8de7","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":110,"y":140,"wires":[["e87591bcd25842d7"]]},{"id":"e87591bcd25842d7","type":"change","z":"77a4781684365cf3","name":"init sensor offset","rules":[{"t":"set","p":"sensoroffset_DGWZ","pt":"flow","to":"0.5","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":140,"wires":[[]]},{"id":"ba8509f4a360bb5e","type":"mqtt in","z":"77a4781684365cf3","name":"Sensor 1 data","topic":"home/ug/Buero/unipi/1/temp/2892844D07000012","qos":"0","datatype":"auto","broker":"36a1d46c.15334c","nl":false,"rap":true,"rh":0,"inputs":0,"x":110,"y":360,"wires":[["e033b10dbd61fed1"]]},{"id":"7d0c6ad3b4eea62e","type":"link out","z":"77a4781684365cf3","name":"","links":["dfe81d783fd57341"],"x":985,"y":300,"wires":[]},{"id":"8b7b671ec9bc2cb7","type":"function","z":"77a4781684365cf3","name":"add routing information to flow_xx","func":"let sensordata = msg.payload;\nlet route = {'send_to':\"flow_1\"};\nmsg.payload = Object.assign(route, sensordata);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":300,"wires":[["7d0c6ad3b4eea62e"]]},{"id":"9731cf9db29a3c8d","type":"trigger","z":"77a4781684365cf3","name":"time - filter","op1":"","op2":"","op1type":"pay","op2type":"nul","duration":"10","extend":false,"overrideDelay":false,"units":"s","reset":"msg.reset","bytopic":"all","topic":"topic","outputs":1,"x":310,"y":340,"wires":[[]]},{"id":"ebed51f349a2b08b","type":"rbe","z":"77a4781684365cf3","name":"% - filter","func":"deadbandEq","gap":"5","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":300,"y":380,"wires":[[]]},{"id":"415aa050e48993b9","type":"inject","z":"77a4781684365cf3","name":"reset min max","props":[{"p":"reset","v":"","vt":"str"}],"repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"","x":340,"y":220,"wires":[["ce87e1a8c4dbc99e"]],"info":"typicaly midnight or midnight between sunday and monday"},{"id":"baf13327520f39ea","type":"switch","z":"77a4781684365cf3","name":"!= previous value","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"","vt":"prev"}],"checkall":"true","repair":false,"outputs":1,"x":330,"y":420,"wires":[[]]},{"id":"42fb581468a416e1","type":"function","z":"77a4781684365cf3","name":"no filter","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":300,"wires":[["ce87e1a8c4dbc99e"]]},{"id":"ce87e1a8c4dbc99e","type":"function","z":"77a4781684365cf3","name":"sensorobject","func":"if ('reset' in msg){\n context.set(\"min\", {\"min\":0.0, \"time\":0});\n context.set(\"max\", {\"max\":0.0, \"time\":0});\n return null;\n}\n\n//-------------------------------------------\n\nlet time = Date.now();\n// the next 5 lines to be edited per sensor\nlet timestring = date_time_string(\"full\",time); // Format full, dayhm, hm, hms\nlet location = \"DGWZ\";\nlet messagetype = \"sensor\";\nlet sensortype = \"enocean\";\nlet sensorname = \"ist\";\n\nlet sensoroffset = flow.get('sensoroffset_DGWZ');\n//\nlet sensorrawvalue = parseFloat(msg.payload);\nlet sensorvalue = sensorrawvalue + sensoroffset;\nlet sensorobject = {\"location\":location,\"messagetype\":messagetype,\"senorname\":sensorname,\"sensortimestamp\":time,\"sensortimestring\":timestring,\"sensorrawvalue\":sensorrawvalue,\"sensoroffset\":sensoroffset, \"sensorvalue\":sensorvalue};\nminmaxobject = minmax(sensorvalue);\nmsg.payload = Object.assign(sensorobject, minmaxobject);\nreturn msg;\n\n//-------------------------------------------\n\nfunction minmax(value){\n let x = parseFloat(value);\n let min = context.get('min');\n let max = context.get('max');\n\n if ((min.min === 0) && (max.max === 0)){\n min.min = x;\n min.time = Date.now();\n context.set('min',min);\n max.max = x;\n context.set('max',max);\n max.time = Date.now(); \n }\n else {\n if (x < min.min){\n min.min = x;\n min.time = Date.now(); \n context.set('min',min);\n }\n if (x > max.max){\n max.max = x;\n max.time = Date.now(); \n context.set('max',max);\n }\n }\n return {'sensormin':min,'sensormax':max};\n}\n\n//-------------------------------------------\n\nfunction date_time_string(type,time){\n let date =new Date(time);\n let year = date.getFullYear();\n let month = (\"0\" + (date.getMonth() + 1)).slice(-2);\n let day = (\"0\" + date.getDate()).slice(-2);\n let hours = (\"0\" + date.getHours()).slice(-2);\n let minutes = (\"0\" + date.getMinutes()).slice(-2);\n let seconds = (\"0\" + date.getSeconds()).slice(-2);\n let datetimestring = \"\";\n switch(type) {\n case \"full\":\n datetimestring = day + \"-\" + month + \"-\" + year + \" \" + hours + ':' + minutes + ':' + seconds; \n break\n case \"dayhm\":\n datetimestring = day + \"-\" + month + \" @ \" + hours + ':' + minutes; \n break \n case \"hm\": \n datetimestring = hours + ':' + minutes; \n break\n case \"hms\":\n datetimestring = hours + ':' + minutes + ':' + seconds; \n break;\n default:\n datetimestring = null; \n }\n return datetimestring;\n} \n//-------------------------------------------\n","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nif (context.get(\"min\") === undefined) {\n context.set(\"min\", {\"min\":0.0, \"time\":0});\n}\n\nif (context.get(\"max\") === undefined) {\n context.set(\"max\", {\"max\":0.0, \"time\":0});\n}","finalize":"","libs":[],"x":530,"y":300,"wires":[["8b7b671ec9bc2cb7"]]},{"id":"0b17b744ab851705","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"25.6","payloadType":"str","x":130,"y":240,"wires":[["42fb581468a416e1"]]},{"id":"5335b411815f998f","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"31.7","payloadType":"str","x":130,"y":280,"wires":[["42fb581468a416e1"]]},{"id":"a432eeb37f671c0c","type":"inject","z":"77a4781684365cf3","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20.3","payloadType":"str","x":130,"y":320,"wires":[["42fb581468a416e1"]]},{"id":"143e848171a56697","type":"link out","z":"77a4781684365cf3","name":"to_flow_2","mode":"link","links":["95d33b37acbce999"],"x":1295,"y":340,"wires":[]},{"id":"741a5693cbf3a09e","type":"debug","z":"77a4781684365cf3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1390,"y":320,"wires":[]},{"id":"ed6ec4ff9597bc17","type":"inject","z":"77a4781684365cf3","name":"reset","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"send_to\":\"flow_1\",\"location\":\"DGWZ\",\"messagetype\":\"reset\"}","payloadType":"json","x":870,"y":240,"wires":[["7d0c6ad3b4eea62e"]]},{"id":"8a5065838f4ef879","type":"inject","z":"77a4781684365cf3","name":"init all flows","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"send_to\":\"flow_1\",\"location\":\"DGWZ\",\"messagetype\":\"init\"},{\"send_to\":\"flow_2\",\"location\":\"DGSZ\",\"messagetype\":\"init\"}]","payloadType":"json","x":850,"y":200,"wires":[["7d0c6ad3b4eea62e"]]},{"id":"f1592a072d390dc7","type":"debug","z":"77a4781684365cf3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1390,"y":280,"wires":[]},{"id":"e033b10dbd61fed1","type":"trigger","z":"77a4781684365cf3","name":"watchdog timer","op1":"","op2":"sensor dead","op1type":"nul","op2type":"str","duration":"10","extend":true,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":320,"y":460,"wires":[["dc27178e40c6f16e"]]},{"id":"dc27178e40c6f16e","type":"debug","z":"77a4781684365cf3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":460,"wires":[]},{"id":"36a1d46c.15334c","type":"mqtt-broker","name":"","broker":"10.0.0.43","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"MQTT/Development","birthQos":"0","birthRetain":"true","birthPayload":"online","birthMsg":{},"closeTopic":"MQTT/Development","closeQos":"0","closeRetain":"true","closePayload":"offline","closeMsg":{},"willTopic":"MQTT/Development","willQos":"0","willRetain":"true","willPayload":"disconnected","willMsg":{},"sessionExpiry":""}]

```
