We have multiple sensors(16 for now) sending data to node-red. Data is collected via BLE gateway and transferred to raspberry Pi with serial input. This data is stored in InlfuxDB database. till now our flow is working fine. Sometimes few sensors stop sending data. We want to count the number of sensors sending data, data is sent every 20s and I have no idea how to do it. any help will be highly appreciated.
current flow
[
{
"id": "68a21d34.8d0b84",
"type": "tab",
"label": "Serial",
"disabled": false,
"info": ""
},
{
"id": "4833802b.27dee",
"type": "serial in",
"z": "68a21d34.8d0b84",
"name": "Read Serial Port ACM0",
"serial": "a9f36f3f50bd604c",
"x": 120,
"y": 220,
"wires": [
[
"9861f7fa.7a7088",
"dee6b8e7.b18128"
]
]
},
{
"id": "9861f7fa.7a7088",
"type": "debug",
"z": "68a21d34.8d0b84",
"name": "Raw Serial Data Debug",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 330,
"y": 100,
"wires": []
},
{
"id": "dee6b8e7.b18128",
"type": "json",
"z": "68a21d34.8d0b84",
"name": "JSON Parser",
"property": "payload",
"action": "obj",
"pretty": false,
"x": 330,
"y": 220,
"wires": [
[
"a6e48650b73e1ba4",
"d421a66d.07b808"
]
]
},
{
"id": "3c096111.cb0c7e",
"type": "delay",
"z": "68a21d34.8d0b84",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "20",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 840,
"y": 160,
"wires": [
[
"b40fb3f0.d07c2",
"a3f2f50e.ac1dd8",
"231a5f0c.71f17"
]
]
},
{
"id": "a3f2f50e.ac1dd8",
"type": "debug",
"z": "68a21d34.8d0b84",
"name": "DB Payload Debug",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 990,
"y": 320,
"wires": []
},
{
"id": "d421a66d.07b808",
"type": "function",
"z": "68a21d34.8d0b84",
"name": "Database Mapping",
"func": "var lookupRoom = [ \n{\"name\":\"officeS01\",\t\"floor\":\"Floor00\", \"id\":\"5\" },\n{\"name\":\"livingroom\",\t\"floor\":\"Floor00\", \"id\":\"6\" },\n{\"name\":\"diningroom\",\t\"floor\":\"Floor00\", \"id\":\"7\" },\n{\"name\":\"kitchen\", \t \"floor\":\"Floor00\", \"id\":\"8\" },\n{\"name\":\"laundry\", \t\"floor\":\"Floor00\", \"id\":\"9\" },\n{\"name\":\"backdoor\", \t\"floor\":\"Floor00\", \"id\":\"10\"},\n{\"name\":\"bedroom01\", \t\"floor\":\"Floor01\", \"id\":\"11\"},\n{\"name\":\"bathroom02\", \t\"floor\":\"Floor01\", \"id\":\"12\"},\n{\"name\":\"bedroom03\", \t\"floor\":\"Floor01\", \"id\":\"13\"},\n{\"name\":\"entry\", \t \"floor\":\"Floor00\", \"id\":\"14\"},\n{\"name\":\"basement\", \t\"floor\":\"Floor-01\", \"id\":\"a\" },\n{\"name\":\"storageroom\", \t\"floor\":\"Floor00\", \"id\":\"b\" },\n{\"name\":\"bathroom01\", \t\"floor\":\"Floor01\", \"id\":\"c\" },\n{\"name\":\"officeS02\", \t\"floor\":\"Floor00\", \"id\":\"d\" },\n{\"name\":\"upstairs\", \t\"floor\":\"Floor01\", \"id\":\"e\" },\n{\"name\":\"bedroom02\", \t\"floor\":\"Floor01\", \"id\":\"f\" },\n];\nvar lookupRoomMatch = lookupRoom.find(el => msg.payload[\"02\"] === el.id);\n\n// var msgTime = new Date(msg.payload[\"03\"]).getTime() * 1e6;\nvar msgTime = new Date(msg.payload[\"03\"]);\n\n\n\nif(lookupRoomMatch) {\n var loc = lookupRoomMatch.name;\n var floor = lookupRoomMatch.floor;\n}\n\n msg.payload = [\n {\n measurement: \"enviro_data\",\n fields: {\n \"temperature\": msg.payload[\"04\"],\n \"humidity\": msg.payload[\"05\"],\n \"pressure\": msg.payload[\"06\"],\n\n \"gas_resistance\": msg.payload[\"07\"],\n \"gas_percentage\": msg.payload[\"08\"],\n \"iaq\": msg.payload[\"09\"]\n },\n tags:{\n \"ID\": msg.payload[\"02\"],\n [floor] : loc\n },\n \"timestamp\": msgTime\n }, \n\n { \n measurement: \"energy_data\",\n fields: {\n \"light\": msg.payload[\"10\"],\n \"occupancy\": msg.payload[\"11\"]\n },\n \n tags:{\n \"ID\": msg.payload[\"02\"],\n [floor] : loc\n },\n \"timestamp\": msgTime\n }, \n \n {\n measurement: \"sensor_state\",\n fields: {\n \"battery\": msg.payload[\"12\"],\n \"iaq_accuracy\": msg.payload[\"13\"],\n \"stability\": msg.payload[\"14\"]\n },\n \n tags:{\n \"ID\": msg.payload[\"02\"],\n [floor] : loc\n },\n\n \"timestamp\": msgTime\n },\n]\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 630,
"y": 220,
"wires": [
[
"3c096111.cb0c7e"
]
],
"info": "# Database Mapping\n\nThis node has changed substantially. \n\nIt has three primary sections.\n\nThe first maps the Node ID to a human recognizable name e.g. office01, and assigns a building floor number. These are used as tags in the database to allow more useful grouping and identification of different nodes.\n\nThe second section defines some variables, including the message timestamp in Unix Epoch time and the name and floor of the sensor node.\n\n**NOTE:** The database batch write node time precision must be set to *default*.\n\nThe third section defines the measurements being written to the database. We define three different groups, \"enviro_data\",\n(temperature, humidity, pressure, gas resistance, gas percentage, IAQ), \"energy data\" (ambient light and occupancy) and \"sensor state\" (battery, iaq_accuracy, stability)."
},
{
"id": "231a5f0c.71f17",
"type": "influxdb batch",
"z": "68a21d34.8d0b84",
"influxdb": "a02ac971.fe5158",
"precision": "s",
"retentionPolicy": "",
"name": "Batch Write to Cloud",
"database": "",
"retentionPolicyV18Flux": "",
"org": "",
"bucket": "",
"x": 1060,
"y": 220,
"wires": []
},
{
"id": "b40fb3f0.d07c2",
"type": "influxdb batch",
"z": "68a21d34.8d0b84",
"influxdb": "180e2781.eb4b68",
"precision": "s",
"retentionPolicy": "",
"name": "Batch Write to Local",
"database": "",
"retentionPolicyV18Flux": "",
"org": "",
"bucket": "",
"x": 1060,
"y": 160,
"wires": []
},
{
"id": "a9822510.912868",
"type": "catch",
"z": "68a21d34.8d0b84",
"name": "Error Reporting",
"scope": null,
"uncaught": false,
"x": 100,
"y": 600,
"wires": [
[
"60ca9efa.67893"
]
]
},
{
"id": "60ca9efa.67893",
"type": "debug",
"z": "68a21d34.8d0b84",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 310,
"y": 600,
"wires": []
},
{
"id": "a6e48650b73e1ba4",
"type": "debug",
"z": "68a21d34.8d0b84",
"name": "Raw JSON Debug",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 510,
"y": 380,
"wires": []
},
{
"id": "0bafb4072b5e810f",
"type": "comment",
"z": "68a21d34.8d0b84",
"name": "Click to Read Me",
"info": "# Error Reporting\n\nThe error reporting node will automatically catch and display any errors as the flow runs. Errors are displayed in the debug panel. If a message is missing a character, or has an unexpected character, it will show up there.",
"x": 100,
"y": 640,
"wires": []
},
{
"id": "199c97093567a5ef",
"type": "comment",
"z": "68a21d34.8d0b84",
"name": "Click to Read Me",
"info": "# Database Mapping\n\nThis node has changed substantially. \n\nIt has three primary sections.\n\nThe first maps the Node ID to a human recognizable name e.g. office01, and assigns a building floor number. These are used as tags in the database to allow more useful grouping and identification of different nodes.\n\nThe second section defines some variables, including the message timestamp in Unix Epoch time (nanoseconds) and the name and floor of the sensor node.\n\n**NOTE:** The database batch write node time precision must be set to *default*.\n\nThe third section defines the measurements being written to the database. We define three different groups:\n\n\"enviro data\" : temperature, humidity, pressure, gas resistance, gas percentage, IAQ\n\"energy data\" : ambient light and occupancy\n\"sensor state\" : battery, iaq_accuracy, stability",
"x": 620,
"y": 260,
"wires": []
},
{
"id": "a1b3a56e0cc39d3f",
"type": "comment",
"z": "68a21d34.8d0b84",
"name": "Click to Read Me",
"info": "# Batch Write to Database\n\nWe are performing dual writes to a cloud instance of InfluxDB and the local instance running on the Raspberry Pi.\n\n**Please make sure the cloud write is disabled**\n",
"x": 1040,
"y": 100,
"wires": []
},
{
"id": "a9f36f3f50bd604c",
"type": "serial-port",
"serialport": "/dev/ttyACM0",
"serialbaud": "57600",
"databits": "8",
"parity": "none",
"stopbits": "1",
"waitfor": "",
"dtr": "none",
"rts": "none",
"cts": "none",
"dsr": "none",
"newline": "\\n",
"bin": "false",
"out": "char",
"addchar": "",
"responsetimeout": "10000"
},
{
"id": "a02ac971.fe5158",
"type": "influxdb",
"hostname": "url",
"port": "port",
"protocol": "http",
"database": "db",
"name": "Basic 4 Batch",
"usetls": false,
"tls": "",
"influxdbVersion": "1.x",
"url": "http://localhost:8086",
"rejectUnauthorized": true
},
{
"id": "180e2781.eb4b68",
"type": "influxdb",
"hostname": "influxdb",
"port": "8086",
"protocol": "http",
"database": "sensorLocal",
"name": "influxdb",
"usetls": false,
"tls": "",
"influxdbVersion": "1.x",
"url": "http://localhost:8086",
"rejectUnauthorized": true
}
]```