From df8c548fdfa1b46cd3f62d6191587ed4eef04df1 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:20:12 -0800 Subject: [PATCH 1/3] Update Flows for 2.2.15-4 Updates Flows for compatability with `@meshtastic/node-red-contrib-meshtastic` 2.2.15-4 --- meshtastic.json | 1166 +++++++++++++++++++++++++++-------------------- 1 file changed, 661 insertions(+), 505 deletions(-) diff --git a/meshtastic.json b/meshtastic.json index 2b9dc25..13945f3 100644 --- a/meshtastic.json +++ b/meshtastic.json @@ -10,17 +10,17 @@ { "id": "a832ad4ec196570a", "type": "subflow", - "name": "Ingest Packets from MQTT", + "name": "Ingest from MQTT", "info": "", - "category": "", + "category": "input", "in": [], "out": [ { - "x": 1510, - "y": 380, + "x": 1430, + "y": 100, "wires": [ { - "id": "0d0579462fe73908", + "id": "13c14b6192865d27", "port": 0 } ] @@ -28,39 +28,141 @@ ], "env": [], "meta": {}, - "color": "#3FADB5", + "color": "#67EA94", "outputLabels": [ "Decoded Packets" ], - "icon": "node-red/comment.svg" + "icon": "@meshtastic/node-red-contrib-meshtastic/logo.svg" }, { - "id": "f2f8954e5d01d9c6", + "id": "8dd264d8b2b469c1", "type": "subflow", - "name": "Push to InfluxDB", + "name": "Measurement: Mesh", "info": "", - "category": "", + "category": "output", "in": [ { - "x": 180, - "y": 220, + "x": 120, + "y": 200, "wires": [ { - "id": "330c1024763a96f8" + "id": "96e553854838f2f4" } ] } ], "out": [], - "env": [ + "env": [], + "meta": {}, + "color": "#C0DEED", + "inputLabels": [ + "Packet" + ], + "icon": "node-red-contrib-influxdb/influxdb.png" + }, + { + "id": "3e0ee1b8ba4768f0", + "type": "subflow", + "name": "Measurement: Packet", + "info": "", + "category": "output", + "in": [ { - "name": "Template", - "type": "str", - "value": "" + "x": 120, + "y": 140, + "wires": [ + { + "id": "ea40b1047dcb281e" + } + ] } ], + "out": [], + "env": [], "meta": {}, - "color": "#DDAA99" + "color": "#C0DEED", + "inputLabels": [ + "Packet" + ], + "icon": "node-red-contrib-influxdb/influxdb.png" + }, + { + "id": "f9e40322037c429a", + "type": "subflow", + "name": "Measurement: Position", + "info": "", + "category": "output", + "in": [ + { + "x": 160, + "y": 180, + "wires": [ + { + "id": "af1ead55008aa3a1" + } + ] + } + ], + "out": [], + "env": [], + "meta": {}, + "color": "#C0DEED", + "inputLabels": [ + "Position" + ], + "icon": "node-red-contrib-influxdb/influxdb.png" + }, + { + "id": "496cbfc0434e783d", + "type": "subflow", + "name": "Measurement: Device Telemetry", + "info": "", + "category": "output", + "in": [ + { + "x": 100, + "y": 120, + "wires": [ + { + "id": "33c5dc88fcd1bf4b" + } + ] + } + ], + "out": [], + "env": [], + "meta": {}, + "color": "#C0DEED", + "inputLabels": [ + "Device Telemetry" + ], + "icon": "node-red-contrib-influxdb/influxdb.png" + }, + { + "id": "0ca01258e3f5252a", + "type": "subflow", + "name": "Measurement: Environment Telemetry", + "info": "", + "category": "output", + "in": [ + { + "x": 60, + "y": 120, + "wires": [ + { + "id": "8569754e02703706" + } + ] + } + ], + "out": [], + "env": [], + "meta": {}, + "color": "#C0DEED", + "inputLabels": [ + "Environment Telemetry" + ], + "icon": "node-red-contrib-influxdb/influxdb.png" }, { "id": "d96c8f45d69c34f7", @@ -105,134 +207,6 @@ "userProps": "", "sessionExpiry": "" }, - { - "id": "8150da8a82682754", - "type": "function", - "z": "a832ad4ec196570a", - "name": "Translate Node Identifiers to Hex", - "func": "msg.payload.packet.toHex = '!' + msg.payload.packet.to.toString(16).padStart(8,0)\nmsg.payload.packet.fromHex = '!' + msg.payload.packet.from.toString(16).padStart(8, 0)\nreturn msg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 840, - "y": 380, - "wires": [ - [ - "0d0579462fe73908", - "8b0bf419f2d0d299" - ] - ] - }, - { - "id": "517d26c82b500334", - "type": "debug", - "z": "a832ad4ec196570a", - "name": "Original Messages", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 790, - "y": 340, - "wires": [] - }, - { - "id": "7d7f8c87bd912724", - "type": "debug", - "z": "a832ad4ec196570a", - "name": "Duplicate Messages", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 800, - "y": 420, - "wires": [] - }, - { - "id": "1aceb1178050204c", - "type": "mqtt in", - "z": "a832ad4ec196570a", - "name": "Injest from MQTT", - "topic": "msh/+/c/#", - "qos": "1", - "datatype": "auto-detect", - "broker": "07b2da65ae42f546", - "nl": false, - "rap": true, - "rh": 0, - "inputs": 0, - "x": 100, - "y": 380, - "wires": [ - [ - "ee2a2830c32d5593" - ] - ] - }, - { - "id": "773f6b430fa18d6e", - "type": "debug", - "z": "a832ad4ec196570a", - "name": "Decoded Message", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 490, - "y": 340, - "wires": [] - }, - { - "id": "8b0bf419f2d0d299", - "type": "debug", - "z": "a832ad4ec196570a", - "name": "Nodes Identified by Hex", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1130, - "y": 340, - "wires": [] - }, - { - "id": "0d0579462fe73908", - "type": "function", - "z": "a832ad4ec196570a", - "name": "Inject Node Names and Hardware", - "func": "var nodeShortNames = global.get('nodeShortNames')\nvar nodeLongNames = global.get('nodeLongNames')\nvar nodeHardware = global.get('nodeHardware')\n\nif (nodeShortNames === undefined) nodeShortNames = {}\nif (nodeLongNames === undefined) nodeLongNames = {}\nif (nodeHardware === undefined) nodeHardware = {}\n\nvar packet = msg.payload.packet\n\nvar unknown = \"unknown\"\n\nvar hardwareMap = {\n 0: \"UNSET\",\n 1: \"TLORA_V2\",\n 2: \"TLORA_V1\",\n 3: \"TLORA_V2_1_1.6\",\n 4: \"TBEAM\",\n 5: \"HELTEC_V2_0\",\n 6: \"TBEAM_V0.7\",\n 7: \"T_ECHO\",\n 8: \"TLORA_V1_1.3\",\n 9: \"RAK4631\",\n 10: \"HELTEC_V2_1\",\n 11: \"HELTEC_V1\",\n 12: \"LILYGO_TBEAM_S3_CORE\",\n 13: \"RAK11200\",\n 14: \"NANO_G1\",\n 15: \"TLORA_V2_1_1.8\",\n 16: \"TLORA_T3_S3\",\n 17: \"NANO_G1_EXPLORER\",\n 18: \"NANO_G2_ULTRA\",\n 19: \"LORA_TYPE\",\n 25: \"STATION_G1\",\n 26: \"RAK11310\",\n 32: \"LORA_RELAY_V1\",\n 33: \"NRF52840DK\",\n 34: \"PPR\",\n 35: \"GENIEBLOCKS\",\n 36: \"NRF52_UNKNOWN\",\n 37: \"PORTDUINO\",\n 38: \"ANDROID_SIM\",\n 39: \"DIY_V1\",\n 40: \"NRF52840_PCA10059\",\n 41: \"DR_DEV\",\n 42: \"M5STACK\",\n 43: \"HELTEC_V3\",\n 44: \"HELTEC_WSL_V3\",\n 45: \"BETAFPV_2400_TX\",\n 46: \"BETAFPV_900_NANO_TX\",\n 47: \"RPI_PICO\",\n 48: \"HELTEC_WIRELESS_TRACKER\",\n 49: \"HELTEC_WIRELESS_PAPER\",\n 50: \"T_DECK\",\n 51: \"T_WATCH_S3\",\n 52: \"PICOMPUTER_S3\",\n 53: \"HELTEC_HT62\",\n 54: \"EBYTE_ESP32_S3\",\n 255: \"PRIVATE_HW\"\n}\n\n// inject From names and hardware info\nif (nodeShortNames.hasOwnProperty(packet.fromHex)){\n packet.fromShortName = nodeShortNames[packet.fromHex]\n} else {\n packet.fromShortName = unknown\n}\n\nif (nodeShortNames.hasOwnProperty(packet.fromHex)) {\n packet.fromShortName = nodeShortNames[packet.fromHex]\n} else {\n packet.fromShortName = unknown\n}\n\nif (nodeLongNames.hasOwnProperty(packet.fromHex)) {\n packet.fromLongName = nodeLongNames[packet.fromHex]\n} else {\n packet.fromLongName = unknown\n}\n\nif (nodeHardware.hasOwnProperty(packet.fromHex)) {\n packet.fromHardware = hardwareMap[nodeHardware[packet.fromHex]]\n} else {\n packet.fromHardware = unknown\n}\n\n// handle messages to mesh\nif (packet.toHex === \"!ffffffff\") {\n packet.toShortName = \"mesh\"\n packet.toLongName = \"Mesh\"\n packet.toHardware = \"MESH\"\n return msg\n}\n\n// inject To names and hardware info\nif (nodeShortNames.hasOwnProperty(packet.toHex)) {\n packet.toShortName = nodeShortNames[packet.toHex]\n packet.toLongName = nodeLongNames[packet.toHex]\n packet.toHardware = hardwareMap[nodeHardware[packet.toHex]]\n} else {\n packet.toShortName = unknown\n packet.toLongName = unknown\n packet.toHardware = unknown\n}\n\nreturn msg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1160, - "y": 380, - "wires": [ - [ - "63da12e4baeff017" - ] - ] - }, { "id": "63da12e4baeff017", "type": "debug", @@ -246,12 +220,140 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1570, - "y": 420, + "x": 1490, + "y": 40, "wires": [] }, { - "id": "add09a79e135bd52", + "id": "4c809ff0174c8ff0", + "type": "function", + "z": "a832ad4ec196570a", + "name": "Translate Node Identifiers to Hex", + "func": "msg.payload.packet.toHex = '!' + msg.payload.packet.to.toString(16).padStart(8,0)\nmsg.payload.packet.fromHex = '!' + msg.payload.packet.from.toString(16).padStart(8, 0)\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 840, + "y": 100, + "wires": [ + [ + "13c14b6192865d27", + "63fd66d3272ed10b" + ] + ] + }, + { + "id": "7e3ebbab282b1482", + "type": "debug", + "z": "a832ad4ec196570a", + "name": "Original Messages", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 790, + "y": 60, + "wires": [] + }, + { + "id": "08806f9cfe03f282", + "type": "debug", + "z": "a832ad4ec196570a", + "name": "Duplicate Messages", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 800, + "y": 140, + "wires": [] + }, + { + "id": "938a1c3c0bdbd155", + "type": "mqtt in", + "z": "a832ad4ec196570a", + "name": "Injest from MQTT", + "topic": "msh/+/c/#", + "qos": "1", + "datatype": "auto-detect", + "broker": "07b2da65ae42f546", + "nl": false, + "rap": true, + "rh": 0, + "inputs": 0, + "x": 100, + "y": 100, + "wires": [ + [ + "1ed79fa8cae54ee4" + ] + ] + }, + { + "id": "e35eb249e35ecfb3", + "type": "debug", + "z": "a832ad4ec196570a", + "name": "Decoded Message", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 490, + "y": 60, + "wires": [] + }, + { + "id": "63fd66d3272ed10b", + "type": "debug", + "z": "a832ad4ec196570a", + "name": "Nodes Identified by Hex", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1130, + "y": 60, + "wires": [] + }, + { + "id": "13c14b6192865d27", + "type": "function", + "z": "a832ad4ec196570a", + "name": "Inject Node Names and Hardware", + "func": "var nodeShortNames = global.get('nodeShortNames')\nvar nodeLongNames = global.get('nodeLongNames')\nvar nodeHardware = global.get('nodeHardware')\n\nif (nodeShortNames === undefined) nodeShortNames = {}\nif (nodeLongNames === undefined) nodeLongNames = {}\nif (nodeHardware === undefined) nodeHardware = {}\n\nvar packet = msg.payload.packet\n\nvar unknown = \"unknown\"\n\nvar hardwareMap = {\n 0: \"UNSET\",\n 1: \"TLORA_V2\",\n 2: \"TLORA_V1\",\n 3: \"TLORA_V2_1_1.6\",\n 4: \"TBEAM\",\n 5: \"HELTEC_V2_0\",\n 6: \"TBEAM_V0.7\",\n 7: \"T_ECHO\",\n 8: \"TLORA_V1_1.3\",\n 9: \"RAK4631\",\n 10: \"HELTEC_V2_1\",\n 11: \"HELTEC_V1\",\n 12: \"LILYGO_TBEAM_S3_CORE\",\n 13: \"RAK11200\",\n 14: \"NANO_G1\",\n 15: \"TLORA_V2_1_1.8\",\n 16: \"TLORA_T3_S3\",\n 17: \"NANO_G1_EXPLORER\",\n 18: \"NANO_G2_ULTRA\",\n 19: \"LORA_TYPE\",\n 25: \"STATION_G1\",\n 26: \"RAK11310\",\n 32: \"LORA_RELAY_V1\",\n 33: \"NRF52840DK\",\n 34: \"PPR\",\n 35: \"GENIEBLOCKS\",\n 36: \"NRF52_UNKNOWN\",\n 37: \"PORTDUINO\",\n 38: \"ANDROID_SIM\",\n 39: \"DIY_V1\",\n 40: \"NRF52840_PCA10059\",\n 41: \"DR_DEV\",\n 42: \"M5STACK\",\n 43: \"HELTEC_V3\",\n 44: \"HELTEC_WSL_V3\",\n 45: \"BETAFPV_2400_TX\",\n 46: \"BETAFPV_900_NANO_TX\",\n 47: \"RPI_PICO\",\n 48: \"HELTEC_WIRELESS_TRACKER\",\n 49: \"HELTEC_WIRELESS_PAPER\",\n 50: \"T_DECK\",\n 51: \"T_WATCH_S3\",\n 52: \"PICOMPUTER_S3\",\n 53: \"HELTEC_HT62\",\n 54: \"EBYTE_ESP32_S3\",\n 255: \"PRIVATE_HW\"\n}\n\n// inject From names and hardware info\nif (nodeShortNames.hasOwnProperty(packet.fromHex)){\n packet.fromShortName = nodeShortNames[packet.fromHex]\n} else {\n packet.fromShortName = unknown\n}\n\nif (nodeShortNames.hasOwnProperty(packet.fromHex)) {\n packet.fromShortName = nodeShortNames[packet.fromHex]\n} else {\n packet.fromShortName = unknown\n}\n\nif (nodeLongNames.hasOwnProperty(packet.fromHex)) {\n packet.fromLongName = nodeLongNames[packet.fromHex]\n} else {\n packet.fromLongName = unknown\n}\n\nif (nodeHardware.hasOwnProperty(packet.fromHex)) {\n packet.fromHardware = hardwareMap[nodeHardware[packet.fromHex]]\n} else {\n packet.fromHardware = unknown\n}\n\n// handle messages to mesh\nif (packet.toHex === \"!ffffffff\") {\n packet.toShortName = \"mesh\"\n packet.toLongName = \"Mesh\"\n packet.toHardware = \"MESH\"\n return msg\n}\n\n// inject To names and hardware info\nif (nodeShortNames.hasOwnProperty(packet.toHex)) {\n packet.toShortName = nodeShortNames[packet.toHex]\n packet.toLongName = nodeLongNames[packet.toHex]\n packet.toHardware = hardwareMap[nodeHardware[packet.toHex]]\n} else {\n packet.toShortName = unknown\n packet.toLongName = unknown\n packet.toHardware = unknown\n}\n\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 100, + "wires": [ + [ + "63da12e4baeff017" + ] + ] + }, + { + "id": "855fd449b14d6e09", "type": "function", "z": "a832ad4ec196570a", "name": "Deduplicate Packets by Id", @@ -262,14 +364,14 @@ "finalize": "", "libs": [], "x": 510, - "y": 380, + "y": 100, "wires": [ [ - "8150da8a82682754", - "517d26c82b500334" + "4c809ff0174c8ff0", + "7e3ebbab282b1482" ], [ - "7d7f8c87bd912724" + "08806f9cfe03f282" ] ], "outputLabels": [ @@ -279,43 +381,100 @@ "icon": "node-red/split.svg" }, { - "id": "ee2a2830c32d5593", + "id": "1ed79fa8cae54ee4", "type": "decode", "z": "a832ad4ec196570a", + "name": "Decode", "x": 300, - "y": 380, + "y": 100, "wires": [ [ - "add09a79e135bd52" + "e35eb249e35ecfb3", + "855fd449b14d6e09" ] ] }, { - "id": "330c1024763a96f8", + "id": "96e553854838f2f4", "type": "template", - "z": "f2f8954e5d01d9c6", - "name": "Generate Packet Measurement", + "z": "8dd264d8b2b469c1", + "name": "Generate Mesh Measurement", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", - "template": "{{env.Template}}", + "template": "[{\n \"id\": \"{{payload.packet.from}}{{payload.packet.to}}\",\n \"source\": \"{{payload.packet.fromLongName}}\",\n \"target\": \"{{payload.packet.toLongName}}\",\n \"rxSnr\": {{payload.packet.rxSnr}},\n \"rxRssi\": {{payload.packet.rxRssi}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", "output": "json", - "x": 390, - "y": 220, + "x": 330, + "y": 200, "wires": [ [ - "ae93a5d5e05d1b8c", - "716232a19027c25a" + "70d77a69a1aedb60", + "565bf6107aace3ce" ] ], "icon": "font-awesome/fa-power-off" }, { - "id": "ae93a5d5e05d1b8c", + "id": "70d77a69a1aedb60", "type": "influxdb out", - "z": "f2f8954e5d01d9c6", - "d": true, + "z": "8dd264d8b2b469c1", + "influxdb": "d96c8f45d69c34f7", + "name": "Write Mesh Measurement", + "measurement": "Mesh", + "precision": "", + "retentionPolicy": "", + "database": "database", + "precisionV18FluxV20": "ms", + "retentionPolicyV18Flux": "", + "org": "organisation", + "bucket": "bucket", + "x": 710, + "y": 180, + "wires": [] + }, + { + "id": "565bf6107aace3ce", + "type": "debug", + "z": "8dd264d8b2b469c1", + "name": "Mesh Measurement", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 700, + "y": 220, + "wires": [] + }, + { + "id": "ea40b1047dcb281e", + "type": "template", + "z": "3e0ee1b8ba4768f0", + "name": "Generate Packet Measurement", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "[{\n \"rxTime\": {{payload.packet.rxTime}},\n \"rxSnr\": {{payload.packet.rxSnr}},\n \"hopLimit\": {{payload.packet.hopLimit}},\n \"priority\": {{payload.packet.priority}},\n \"rxRssi\": {{payload.packet.rxRssi}},\n \"delayed\": {{payload.packet.delayed}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", + "output": "json", + "x": 330, + "y": 140, + "wires": [ + [ + "54c9586ca95b7ed1", + "eabe626826678b37" + ] + ], + "icon": "font-awesome/fa-power-off" + }, + { + "id": "54c9586ca95b7ed1", + "type": "influxdb out", + "z": "3e0ee1b8ba4768f0", "influxdb": "d96c8f45d69c34f7", "name": "Write Packet Measurement", "measurement": "Packet", @@ -326,25 +485,193 @@ "retentionPolicyV18Flux": "", "org": "organisation", "bucket": "bucket", - "x": 700, - "y": 220, + "x": 720, + "y": 120, "wires": [] }, { - "id": "716232a19027c25a", + "id": "eabe626826678b37", "type": "debug", - "z": "f2f8954e5d01d9c6", - "name": "Subflow Packet Measurement", - "active": true, + "z": "3e0ee1b8ba4768f0", + "name": "Packet Measurement", + "active": false, "tosidebar": true, "console": false, "tostatus": false, - "complete": "payload", - "targetType": "msg", + "complete": "true", + "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 710, - "y": 260, + "x": 700, + "y": 160, + "wires": [] + }, + { + "id": "af1ead55008aa3a1", + "type": "function", + "z": "f9e40322037c429a", + "name": "Generate Position Measurement", + "func": "var payload = msg.payload.packet.decoded.payload\n\nvar out = [{\n \"latitude\": (payload.latitudeI * 1e-7),\n \"longitude\": (payload.longitudeI * 1e-7),\n \"altitude\": payload.altitude,\n \"satsInView\": payload.satsInView,\n \"groundSpeed\": payload.groundSpeed,\n \"groundTrack\": payload.groundTrack,\n \"pDOP\": payload.pDOP,\n},\n{\n \"from\": msg.payload.packet.fromHex,\n \"fromShortName\": msg.payload.packet.fromShortName,\n \"fromLongName\": msg.payload.packet.fromLongName,\n \"fromHardware\": msg.payload.packet.fromHardware,\n \"to\": msg.payload.packet.toHex,\n \"toShortName\": msg.payload.packet.toShortName,\n \"toLongName\": msg.payload.packet.toLongName,\n \"toHardware\": msg.payload.packet.toHardware,\n \"channelId\": msg.payload.channelId,\n \"gatewayId\": msg.payload.gatewayId\n}]\n\nmsg.payload = out\n\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 370, + "y": 180, + "wires": [ + [ + "99f9cca4b6a6bf62", + "8359de37e139c84e" + ] + ], + "icon": "font-awesome/fa-location-arrow" + }, + { + "id": "99f9cca4b6a6bf62", + "type": "influxdb out", + "z": "f9e40322037c429a", + "influxdb": "d96c8f45d69c34f7", + "name": "Write Position Measurement", + "measurement": "Position", + "precision": "", + "retentionPolicy": "", + "database": "database", + "precisionV18FluxV20": "ms", + "retentionPolicyV18Flux": "", + "org": "organisation", + "bucket": "bucket", + "x": 680, + "y": 180, + "wires": [] + }, + { + "id": "8359de37e139c84e", + "type": "debug", + "z": "f9e40322037c429a", + "name": "Position Measurement", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 660, + "y": 140, + "wires": [] + }, + { + "id": "61aa5d3ba2f9797f", + "type": "debug", + "z": "496cbfc0434e783d", + "name": "Device Measurement", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 640, + "y": 80, + "wires": [] + }, + { + "id": "33c5dc88fcd1bf4b", + "type": "template", + "z": "496cbfc0434e783d", + "name": "Generate Device Measurement", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "[{\n \"air_util_tx\": {{payload.packet.decoded.payload.deviceMetrics.airUtilTx}},\n \"battery_level\": {{payload.packet.decoded.payload.deviceMetrics.batteryLevel}},\n \"channel_utilization\": {{payload.packet.decoded.payload.deviceMetrics.channelUtilization}},\n \"voltage\": {{payload.packet.decoded.payload.deviceMetrics.voltage}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", + "output": "json", + "x": 310, + "y": 120, + "wires": [ + [ + "61aa5d3ba2f9797f", + "c7fd5f39b31851f5" + ] + ], + "icon": "font-awesome/fa-power-off" + }, + { + "id": "c7fd5f39b31851f5", + "type": "influxdb out", + "z": "496cbfc0434e783d", + "influxdb": "d96c8f45d69c34f7", + "name": "Write Device Measurement", + "measurement": "Device", + "precision": "", + "retentionPolicy": "", + "database": "database", + "precisionV18FluxV20": "ms", + "retentionPolicyV18Flux": "", + "org": "organisation", + "bucket": "bucket", + "x": 660, + "y": 120, + "wires": [] + }, + { + "id": "8569754e02703706", + "type": "template", + "z": "0ca01258e3f5252a", + "name": "Generate Environment Measurement", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "[{\n \"barometric_pressure\": {{payload.packet.decoded.payload.environmentMetrics.barometricPressure}},\n \"gas_resistance\": {{payload.packet.decoded.payload.environmentMetrics.gasResistance}},\n \"relative_humidity\": {{payload.packet.decoded.payload.environmentMetrics.relativeHumidity}},\n \"temperature\": {{payload.packet.decoded.payload.environmentMetrics.temperature}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", + "output": "json", + "x": 290, + "y": 120, + "wires": [ + [ + "d714c7fefad20f11", + "a3c383330d74e1bb" + ] + ], + "icon": "font-awesome/fa-thermometer-2" + }, + { + "id": "d714c7fefad20f11", + "type": "debug", + "z": "0ca01258e3f5252a", + "name": "Environment Measurement", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 620, + "y": 80, + "wires": [] + }, + { + "id": "a3c383330d74e1bb", + "type": "influxdb out", + "z": "0ca01258e3f5252a", + "influxdb": "d96c8f45d69c34f7", + "name": "Write Environment Measurement", + "measurement": "Environment", + "precision": "", + "retentionPolicy": "", + "database": "database", + "precisionV18FluxV20": "ms", + "retentionPolicyV18Flux": "", + "org": "organisation", + "bucket": "bucket", + "x": 640, + "y": 120, "wires": [] }, { @@ -352,7 +679,7 @@ "type": "switch", "z": "f86392651850d084", "name": "Split by PortNum", - "property": "payload.packet.payloadVariant.decoded.portnum", + "property": "payload.packet.decoded.portnum", "propertyType": "msg", "rules": [ { @@ -477,8 +804,8 @@ "checkall": "false", "repair": false, "outputs": 24, - "x": 470, - "y": 700, + "x": 550, + "y": 580, "wires": [ [ "0cbf9e15ee49dd3b" @@ -490,7 +817,7 @@ "c444184615027953" ], [ - "af1ead55008aa3a1" + "773afcf51939b5fa" ], [ "32de28bb83f90d75" @@ -541,7 +868,7 @@ "05dd3202f55db6c6" ], [ - "2769fe94db570fcb" + "d2fee47f93ca47de" ], [ "f66a3825a2bc89b5" @@ -581,23 +908,6 @@ ], "icon": "font-awesome/fa-inbox" }, - { - "id": "61aa5d3ba2f9797f", - "type": "debug", - "z": "f86392651850d084", - "name": "Device Measurement", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1560, - "y": 800, - "wires": [] - }, { "id": "800ecb302b9aeda5", "type": "debug", @@ -611,25 +921,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 830, - "y": 260, - "wires": [] - }, - { - "id": "4663655785e75cd6", - "type": "debug", - "z": "f86392651850d084", - "name": "Neighbor Info", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1060, - "y": 1100, + "x": 910, + "y": 180, "wires": [] }, { @@ -645,8 +938,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 860, - "y": 220, + "x": 940, + "y": 140, "wires": [] }, { @@ -662,46 +955,25 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1160, - "y": 420, + "x": 1240, + "y": 280, "wires": [] }, - { - "id": "33c5dc88fcd1bf4b", - "type": "template", - "z": "f86392651850d084", - "name": "Generate Device Measurement", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "[{\n \"air_util_tx\": {{payload.packet.payloadVariant.decoded.payload.variant.deviceMetrics.airUtilTx}},\n \"battery_level\": {{payload.packet.payloadVariant.decoded.payload.variant.deviceMetrics.batteryLevel}},\n \"channel_utilization\": {{payload.packet.payloadVariant.decoded.payload.variant.deviceMetrics.channelUtilization}},\n \"voltage\": {{payload.packet.payloadVariant.decoded.payload.variant.deviceMetrics.voltage}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", - "output": "json", - "x": 1230, - "y": 840, - "wires": [ - [ - "61aa5d3ba2f9797f", - "c7fd5f39b31851f5" - ] - ], - "icon": "font-awesome/fa-power-off" - }, { "id": "5621d444d33ec358", "type": "switch", "z": "f86392651850d084", "name": "Telemetry Type", - "property": "payload.packet.payloadVariant.decoded.payload.variant.oneofKind", + "property": "payload.packet.decoded.payload", "propertyType": "msg", "rules": [ { - "t": "eq", + "t": "hask", "v": "deviceMetrics", "vt": "str" }, { - "t": "eq", + "t": "hask", "v": "environmentMetrics", "vt": "str" }, @@ -712,14 +984,14 @@ "checkall": "true", "repair": false, "outputs": 3, - "x": 860, - "y": 920, + "x": 940, + "y": 800, "wires": [ [ - "33c5dc88fcd1bf4b" + "b580aaf34162d927" ], [ - "8569754e02703706" + "7cc5becf0784992e" ], [ "1a84a37a75dbd35f" @@ -745,8 +1017,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1190, - "y": 980, + "x": 1270, + "y": 840, "wires": [] }, { @@ -756,8 +1028,8 @@ "name": "", "scope": null, "uncaught": false, - "x": 80, - "y": 60, + "x": 100, + "y": 100, "wires": [ [ "459e35735d9b3edc" @@ -777,37 +1049,16 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 230, - "y": 60, + "x": 250, + "y": 100, "wires": [] }, - { - "id": "af1ead55008aa3a1", - "type": "function", - "z": "f86392651850d084", - "name": "Generate Position Measurement", - "func": "var payload = msg.payload.packet.payloadVariant.decoded.payload\n\nvar out = [{\n \"latitude\": (payload.latitudeI * 1e-7),\n \"longitude\": (payload.longitudeI * 1e-7),\n \"altitude\": payload.altitude,\n \"satsInView\": payload.satsInView,\n \"groundSpeed\": payload.groundSpeed,\n \"groundTrack\": payload.groundTrack,\n \"pDOP\": payload.pDOP,\n},\n{\n \"from\": msg.payload.packet.fromHex,\n \"fromShortName\": msg.payload.packet.fromShortName,\n \"fromLongName\": msg.payload.packet.fromLongName,\n \"fromHardware\": msg.payload.packet.fromHardware,\n \"to\": msg.payload.packet.toHex,\n \"toShortName\": msg.payload.packet.toShortName,\n \"toLongName\": msg.payload.packet.toLongName,\n \"toHardware\": msg.payload.packet.toHardware,\n \"channelId\": msg.payload.channelId,\n \"gatewayId\": msg.payload.gatewayId\n}]\n\nmsg.payload = out\n\nreturn msg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 910, - "y": 380, - "wires": [ - [ - "99f9cca4b6a6bf62", - "8359de37e139c84e" - ] - ], - "icon": "font-awesome/fa-location-arrow" - }, { "id": "05dd3202f55db6c6", "type": "debug", "z": "f86392651850d084", "name": "Trace Route", - "active": false, + "active": true, "tosidebar": true, "console": false, "tostatus": false, @@ -815,64 +1066,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 850, - "y": 1060, - "wires": [] - }, - { - "id": "8569754e02703706", - "type": "template", - "z": "f86392651850d084", - "name": "Generate Environment Measurement", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "[{\n \"barometric_pressure\": {{payload.packet.payloadVariant.decoded.payload.variant.environmentMetrics.barometricPressure}},\n \"gas_resistance\": {{payload.packet.payloadVariant.decoded.payload.variant.environmentMetrics.gasResistance}},\n \"relative_humidity\": {{payload.packet.payloadVariant.decoded.payload.variant.environmentMetrics.relativeHumidity}},\n \"temperature\": {{payload.packet.payloadVariant.decoded.payload.variant.environmentMetrics.temperature}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", - "output": "json", - "x": 1250, - "y": 920, - "wires": [ - [ - "d714c7fefad20f11", - "a3c383330d74e1bb" - ] - ], - "icon": "font-awesome/fa-thermometer-2" - }, - { - "id": "d714c7fefad20f11", - "type": "debug", - "z": "f86392651850d084", - "name": "Environment Measurement", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1580, - "y": 880, - "wires": [] - }, - { - "id": "99f9cca4b6a6bf62", - "type": "influxdb out", - "z": "f86392651850d084", - "influxdb": "d96c8f45d69c34f7", - "name": "Write Position Measurement", - "measurement": "Position", - "precision": "", - "retentionPolicy": "", - "database": "database", - "precisionV18FluxV20": "ms", - "retentionPolicyV18Flux": "", - "org": "organisation", - "bucket": "bucket", - "x": 1220, - "y": 380, + "x": 930, + "y": 940, "wires": [] }, { @@ -888,8 +1083,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 460, + "x": 920, + "y": 340, "wires": [] }, { @@ -905,8 +1100,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 830, - "y": 500, + "x": 910, + "y": 380, "wires": [] }, { @@ -922,8 +1117,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 540, + "x": 920, + "y": 420, "wires": [] }, { @@ -939,8 +1134,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 580, + "x": 920, + "y": 460, "wires": [] }, { @@ -956,8 +1151,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 830, - "y": 620, + "x": 910, + "y": 500, "wires": [] }, { @@ -973,8 +1168,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 870, - "y": 660, + "x": 950, + "y": 540, "wires": [] }, { @@ -990,8 +1185,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 830, - "y": 700, + "x": 910, + "y": 580, "wires": [] }, { @@ -1007,8 +1202,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 740, + "x": 920, + "y": 620, "wires": [] }, { @@ -1024,8 +1219,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 830, - "y": 780, + "x": 910, + "y": 660, "wires": [] }, { @@ -1041,8 +1236,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 860, - "y": 820, + "x": 940, + "y": 700, "wires": [] }, { @@ -1058,8 +1253,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 850, - "y": 860, + "x": 930, + "y": 740, "wires": [] }, { @@ -1075,8 +1270,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 870, - "y": 300, + "x": 950, + "y": 220, "wires": [] }, { @@ -1092,8 +1287,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 880, - "y": 980, + "x": 960, + "y": 860, "wires": [] }, { @@ -1109,8 +1304,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 1020, + "x": 920, + "y": 900, "wires": [] }, { @@ -1126,8 +1321,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 840, - "y": 1140, + "x": 920, + "y": 1020, "wires": [] }, { @@ -1143,8 +1338,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 860, - "y": 1180, + "x": 940, + "y": 1060, "wires": [] }, { @@ -1160,136 +1355,8 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 860, - "y": 1220, - "wires": [] - }, - { - "id": "8359de37e139c84e", - "type": "debug", - "z": "f86392651850d084", - "name": "Position Measurement", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1200, - "y": 340, - "wires": [] - }, - { - "id": "2769fe94db570fcb", - "type": "function", - "z": "f86392651850d084", - "name": "Decode Payload", - "func": "msg.payload.packet.payloadVariant.decoded.payload = Buffer.from(msg.payload.packet.payloadVariant.decoded.payload).toJSON()\nreturn msg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 860, + "x": 940, "y": 1100, - "wires": [ - [ - "4663655785e75cd6" - ] - ] - }, - { - "id": "a3c383330d74e1bb", - "type": "influxdb out", - "z": "f86392651850d084", - "influxdb": "d96c8f45d69c34f7", - "name": "Write Environment Measurement", - "measurement": "Environment", - "precision": "", - "retentionPolicy": "", - "database": "database", - "precisionV18FluxV20": "ms", - "retentionPolicyV18Flux": "", - "org": "organisation", - "bucket": "bucket", - "x": 1600, - "y": 920, - "wires": [] - }, - { - "id": "c7fd5f39b31851f5", - "type": "influxdb out", - "z": "f86392651850d084", - "influxdb": "d96c8f45d69c34f7", - "name": "Write Device Measurement", - "measurement": "Device", - "precision": "", - "retentionPolicy": "", - "database": "database", - "precisionV18FluxV20": "ms", - "retentionPolicyV18Flux": "", - "org": "organisation", - "bucket": "bucket", - "x": 1580, - "y": 840, - "wires": [] - }, - { - "id": "ea40b1047dcb281e", - "type": "template", - "z": "f86392651850d084", - "name": "Generate Packet Measurement", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "[{\n \"rxTime\": {{payload.packet.rxTime}},\n \"rxSnr\": {{payload.packet.rxSnr}},\n \"hopLimit\": {{payload.packet.hopLimit}},\n \"priority\": {{payload.packet.priority}},\n \"rxRssi\": {{payload.packet.rxRssi}},\n \"delayed\": {{payload.packet.delayed}}\n},\n{\n \"from\": \"{{payload.packet.fromHex}}\",\n \"fromShortName\": \"{{payload.packet.fromShortName}}\",\n \"fromLongName\": \"{{payload.packet.fromLongName}}\",\n \"fromHardware\": \"{{payload.packet.fromHardware}}\",\n \"to\": \"{{payload.packet.toHex}}\",\n \"toShortName\": \"{{payload.packet.toShortName}}\",\n \"toLongName\": \"{{payload.packet.toLongName}}\",\n \"toHardware\": \"{{payload.packet.toHardware}}\",\n \"channelId\": \"{{payload.channelId}}\",\n \"gatewayId\": \"{{payload.gatewayId}}\"\n}]", - "output": "json", - "x": 510, - "y": 120, - "wires": [ - [ - "54c9586ca95b7ed1", - "eabe626826678b37" - ] - ], - "icon": "font-awesome/fa-power-off" - }, - { - "id": "54c9586ca95b7ed1", - "type": "influxdb out", - "z": "f86392651850d084", - "influxdb": "d96c8f45d69c34f7", - "name": "Write Packet Measurement", - "measurement": "Packet", - "precision": "", - "retentionPolicy": "", - "database": "database", - "precisionV18FluxV20": "ms", - "retentionPolicyV18Flux": "", - "org": "organisation", - "bucket": "bucket", - "x": 900, - "y": 100, - "wires": [] - }, - { - "id": "eabe626826678b37", - "type": "debug", - "z": "f86392651850d084", - "name": "Packet Measurement", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 880, - "y": 140, "wires": [] }, { @@ -1297,14 +1364,14 @@ "type": "function", "z": "f86392651850d084", "name": "Add Node Info to Global Context", - "func": "var nodeShortNames = global.get('nodeShortNames')\nvar nodeLongNames = global.get('nodeLongNames')\nvar nodeHardware = global.get('nodeHardware')\n\nif (nodeShortNames === undefined) nodeShortNames = {}\nif (nodeLongNames === undefined) nodeLongNames = {}\nif (nodeHardware === undefined) nodeHardware = {}\n\nvar payload = msg.payload.packet.payloadVariant.decoded.payload\n\nif (!(nodeShortNames.hasOwnProperty(payload.id)) || !(nodeShortNames[payload.id] === payload.shortName)){\n nodeShortNames[payload.id] = payload.shortName\n}\n\nif (!(nodeLongNames.hasOwnProperty(payload.id)) || !(nodeLongNames[payload.id] === payload.longName)) {\n nodeLongNames[payload.id] = payload.longName\n}\n\nif (!(nodeHardware.hasOwnProperty(payload.id)) || !(nodeHardware[payload.id] === payload.hwModel)) {\n nodeHardware[payload.id] = payload.hwModel\n}\n\nglobal.set('nodeShortNames', nodeShortNames)\nglobal.set('nodeLongNames', nodeLongNames)\nglobal.set('nodeHardware', nodeHardware)\n\nconst nodeInfo = {\n nodeShortNames, \n nodeLongNames, \n nodeHardware}\n\nreturn [msg, nodeInfo];", + "func": "var nodeShortNames = global.get('nodeShortNames')\nvar nodeLongNames = global.get('nodeLongNames')\nvar nodeHardware = global.get('nodeHardware')\n\nif (nodeShortNames === undefined) nodeShortNames = {}\nif (nodeLongNames === undefined) nodeLongNames = {}\nif (nodeHardware === undefined) nodeHardware = {}\n\nvar payload = msg.payload.packet.decoded.payload\n\nif (!(nodeShortNames.hasOwnProperty(payload.id)) || !(nodeShortNames[payload.id] === payload.shortName)){\n nodeShortNames[payload.id] = payload.shortName\n}\n\nif (!(nodeLongNames.hasOwnProperty(payload.id)) || !(nodeLongNames[payload.id] === payload.longName)) {\n nodeLongNames[payload.id] = payload.longName\n}\n\nif (!(nodeHardware.hasOwnProperty(payload.id)) || !(nodeHardware[payload.id] === payload.hwModel)) {\n nodeHardware[payload.id] = payload.hwModel\n}\n\nglobal.set('nodeShortNames', nodeShortNames)\nglobal.set('nodeLongNames', nodeLongNames)\nglobal.set('nodeHardware', nodeHardware)\n\nconst nodeInfo = {\n nodeShortNames, \n nodeLongNames, \n nodeHardware}\n\nreturn [msg, nodeInfo];", "outputs": 2, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 910, - "y": 420, + "x": 990, + "y": 300, "wires": [ [ "7fa2849d08656963" @@ -1312,6 +1379,13 @@ [ "3442c0ba5b13848f" ] + ], + "inputLabels": [ + "NodeInfo" + ], + "outputLabels": [ + "NodeInfo", + "Global Context" ] }, { @@ -1327,22 +1401,104 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1210, - "y": 460, + "x": 1290, + "y": 320, "wires": [] }, { - "id": "d65682898df0b2cb", + "id": "d2fee47f93ca47de", + "type": "function", + "z": "f86392651850d084", + "name": "Translate NeighborInfo Node Identifiers to Hex", + "func": "let payload = msg.payload.packet.decoded.payload;\n\npayload.nodeIdHex = '!' + payload.nodeId.toString(16).padStart(8,0);\npayload.lastSentByIdHex = '!' + payload.lastSentById.toString(16).padStart(8, 0);\n\npayload.neighbors.forEach(function(neighbor) {\n neighbor.nodeIdHex = '!' + neighbor.nodeId.toString(16).padStart(8, 0)\n});\n\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1040, + "y": 980, + "wires": [ + [ + "4663655785e75cd6" + ] + ] + }, + { + "id": "4663655785e75cd6", + "type": "debug", + "z": "f86392651850d084", + "name": "Neighbor Info", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1340, + "y": 980, + "wires": [] + }, + { + "id": "3757dfefbc17bb5c", "type": "subflow:a832ad4ec196570a", "z": "f86392651850d084", "name": "", "x": 130, - "y": 700, + "y": 580, "wires": [ [ "a047428628dbff56", - "ea40b1047dcb281e" + "32e8b9b72c6c19ce", + "51611eebf11d2a12" ] ] + }, + { + "id": "32e8b9b72c6c19ce", + "type": "subflow:8dd264d8b2b469c1", + "z": "f86392651850d084", + "name": "Measurement: Mesh", + "x": 560, + "y": 320, + "wires": [] + }, + { + "id": "51611eebf11d2a12", + "type": "subflow:3e0ee1b8ba4768f0", + "z": "f86392651850d084", + "name": "Measurement: Packet", + "x": 560, + "y": 360, + "wires": [] + }, + { + "id": "773afcf51939b5fa", + "type": "subflow:f9e40322037c429a", + "z": "f86392651850d084", + "name": "Measurement: Position", + "x": 960, + "y": 260, + "wires": [] + }, + { + "id": "b580aaf34162d927", + "type": "subflow:496cbfc0434e783d", + "z": "f86392651850d084", + "name": "Measurement: Device Telemetry", + "x": 1310, + "y": 760, + "wires": [] + }, + { + "id": "7cc5becf0784992e", + "type": "subflow:0ca01258e3f5252a", + "z": "f86392651850d084", + "name": "Measurement: Environment Telemetry", + "x": 1330, + "y": 800, + "wires": [] } ] From cd36afd58c91bbcbf3361570dfa8dede11e17715 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:23:33 -0800 Subject: [PATCH 2/3] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c35fedb..8acbf53 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,13 @@ Node-RED Configuration for Meshtastic Packets - Writing Packet, Device, Environment and Position measurements to InfluxDB - Debug nodes for all outputs +### Included Subflows +- Ingest from MQTT +- Measurement: Mesh +- Measurement: Packet +- Measurement: Device Telemetry +- Measurement: Environment Telemetry + ## Dependencies The following Node-RED modules need to be added to the palette before importing the workflow: - [@meshtastic/node-red-contrib-meshtastic](https://flows.nodered.org/node/@meshtastic/node-red-contrib-meshtastic) @@ -19,5 +26,3 @@ The following Node-RED modules need to be added to the palette before importing ## Flow Preview ![meshtastic-flow](./meshtastic-flow.png) -## Known Limitations -- NeighbourInfo payloads are not correctly decoded From 852447c09220ff346859d9df75af922f8b8f9eda Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:25:07 -0800 Subject: [PATCH 3/3] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8acbf53..05d1374 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ Node-RED Configuration for Meshtastic Packets - Ingestion from MQTT - Protobufs decoding - Message deduplication by ID -- Translating integer To/From node ids to hex -- Annotating packets with known NodeInfo +- Annotate integer-based node ids to hex +- Annotate packets with known NodeInfo - Split for all current port numbers -- Writing Packet, Device, Environment and Position measurements to InfluxDB +- Writing Mesh, Packet, Device, Environment and Position measurements to InfluxDB - Debug nodes for all outputs ### Included Subflows