From 7b8c9f82e5ac40537924d45e3251afbe4b621352 Mon Sep 17 00:00:00 2001 From: Skordy Date: Wed, 28 Aug 2024 01:10:14 -0700 Subject: [PATCH 1/6] MQTT Status based on Last Packet Received --- src/mqtt.js | 41 +++++++-------------------- src/public/index.html | 64 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/src/mqtt.js b/src/mqtt.js index 6b8d86f..3052b19 100644 --- a/src/mqtt.js +++ b/src/mqtt.js @@ -604,37 +604,6 @@ client.on("connect", () => { // handle message received client.on("message", async (topic, message) => { try { - - // handle node status - if(topic.includes("/stat/!")){ - try { - - // get node id and status - const nodeIdHex = topic.split("/").pop(); - const mqttConnectionState = message.toString(); - - // convert node id hex to int value - const nodeId = convertHexIdToNumericId(nodeIdHex); - - // update mqtt connection state for node - await prisma.node.updateMany({ - where: { - node_id: nodeId, - }, - data: { - mqtt_connection_state: mqttConnectionState, - mqtt_connection_state_updated_at: new Date(), - }, - }); - - // no need to continue with this mqtt message - return; - - } catch(e) { - console.error(e); - } - } - // decode service envelope const envelope = ServiceEnvelope.decode(message); if(!envelope.packet){ @@ -661,6 +630,16 @@ client.on("message", async (topic, message) => { } } + // Update Node MQTT status based on Last Packet Received time + const ret = await prisma.node.updateMany({ + where: { + node_id: convertHexIdToNumericId(envelope.gatewayId), + }, + data: { + mqtt_connection_state_updated_at: new Date(), + }, + }); + // attempt to decrypt encrypted packets const isEncrypted = envelope.packet.encrypted?.length > 0; if(isEncrypted){ diff --git a/src/public/index.html b/src/public/index.html index b6f2340..aff629e 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -1485,6 +1485,30 @@ + +
+ +
Nodes that have not uploaded to MQTT in this time will show as blue icons. Reload to update map.
+ +
+
@@ -1777,6 +1801,19 @@ } } + function getConfigNodesDisconnectedAgeInSeconds() { + const value = localStorage.getItem("config_nodes_disconnected_age_in_seconds"); + return value != null ? parseInt(value) : null; + } + + function setConfigNodesDisconnectedAgeInSeconds(value) { + if(value != null){ + return localStorage.setItem("config_nodes_disconnected_age_in_seconds", value); + } else { + return localStorage.removeItem("config_nodes_disconnected_age_in_seconds"); + } + } + function getConfigNodesOfflineAgeInSeconds() { const value = localStorage.getItem("config_nodes_offline_age_in_seconds"); return value != null ? parseInt(value) : null; @@ -1836,6 +1873,7 @@ isShowingAnnouncement: this.shouldShowAnnouncement(), configNodesMaxAgeInSeconds: window.getConfigNodesMaxAgeInSeconds(), + configNodesDisconnectedAgeInSeconds: window.getConfigNodesDisconnectedAgeInSeconds(), configNodesOfflineAgeInSeconds: window.getConfigNodesOfflineAgeInSeconds(), configWaypointsMaxAgeInSeconds: window.getConfigWaypointsMaxAgeInSeconds(), configNeighboursMaxDistanceInMeters: window.getConfigNeighboursMaxDistanceInMeters(), @@ -2791,6 +2829,9 @@ configNodesMaxAgeInSeconds() { window.setConfigNodesMaxAgeInSeconds(this.configNodesMaxAgeInSeconds); }, + configNodesDisconnectedAgeInSeconds() { + window.setConfigNodesDisconnectedAgeInSeconds(this.configNodesDisconnectedAgeInSeconds); + }, configNodesOfflineAgeInSeconds() { window.setConfigNodesOfflineAgeInSeconds(this.configNodesOfflineAgeInSeconds); }, @@ -3500,12 +3541,15 @@ // icon based on mqtt connection state var icon = iconMqttDisconnected; - if(node.mqtt_connection_state === "online"){ - icon = iconMqttConnected; + const now = moment(); + const configNodesDisconnectedAgeInSeconds = getConfigNodesDisconnectedAgeInSeconds(); + if(configNodesDisconnectedAgeInSeconds){ + if(now.diff(moment(node.mqtt_connection_state_updated_at)) > configNodesDisconnectedAgeInSeconds * 1000){ + icon = iconMqttConnected; + } } // use offline icon for nodes older than configured node offline age - const now = moment(); const configNodesOfflineAgeInSeconds = getConfigNodesOfflineAgeInSeconds(); if(configNodesOfflineAgeInSeconds){ const lastUpdatedAgeInMillis = now.diff(moment(node.updated_at)); @@ -3519,7 +3563,7 @@ icon: icon, tagName: node.node_id, // we want to show online nodes above offline, but without needing to use separate layer groups - zIndexOffset: node.mqtt_connection_state === "online" ? 1000 : -1000, + zIndexOffset: now.diff(moment(node.mqtt_connection_state_updated_at)) > configNodesDisconnectedAgeInSeconds * 1000 ? 1000 : -1000, }).on('click', function(event) { // close tooltip on click to prevent tooltip and popup showing at same time event.target.closeTooltip(); @@ -3937,13 +3981,13 @@ // human friendly connection state var mqttStatus = ""; - var mqttStatusLastUpdated = node.mqtt_connection_state_updated_at ? `(${moment(new Date(node.mqtt_connection_state_updated_at)).fromNow()})` : ""; - if(node.mqtt_connection_state === "online"){ - mqttStatus = `Connected ${mqttStatusLastUpdated}`; - } else if(node.mqtt_connection_state === "offline"){ - mqttStatus = `Disconnected ${mqttStatusLastUpdated}`; + var mqttStatusLastUpdated = node.mqtt_connection_state_updated_at ? `${moment(new Date(node.mqtt_connection_state_updated_at)).fromNow()}` : ""; + if(moment().diff(moment(node.mqtt_connection_state_updated_at)) > getConfigNodesDisconnectedAgeInSeconds() * 1000){ + mqttStatus = `Heard ${mqttStatusLastUpdated}`; + } else if(moment().diff(moment(node.mqtt_connection_state_updated_at)) < getConfigNodesDisconnectedAgeInSeconds() * 1000){ + mqttStatus = `Last Heard ${mqttStatusLastUpdated}`; } else { - mqttStatus = `Disconnected`; + mqttStatus = `Not heard`; } var loraFrequencyRange = getRegionFrequencyRange(node.region_name); From 485621ffa46547dda23baa7c6c11b03ea3761687 Mon Sep 17 00:00:00 2001 From: Skordy Date: Wed, 28 Aug 2024 01:14:19 -0700 Subject: [PATCH 2/6] MQTT Status based on Last Packet Received --- src/mqtt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.js b/src/mqtt.js index 3052b19..a306e1e 100644 --- a/src/mqtt.js +++ b/src/mqtt.js @@ -631,7 +631,7 @@ client.on("message", async (topic, message) => { } // Update Node MQTT status based on Last Packet Received time - const ret = await prisma.node.updateMany({ + await prisma.node.updateMany({ where: { node_id: convertHexIdToNumericId(envelope.gatewayId), }, From d163c844506ce8a5b19ac46f00d849fd195c6938 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Wed, 28 Aug 2024 20:42:24 +1200 Subject: [PATCH 3/6] don't care if updating mqtt timestamp fails --- src/mqtt.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/mqtt.js b/src/mqtt.js index a306e1e..d8939d4 100644 --- a/src/mqtt.js +++ b/src/mqtt.js @@ -604,6 +604,7 @@ client.on("connect", () => { // handle message received client.on("message", async (topic, message) => { try { + // decode service envelope const envelope = ServiceEnvelope.decode(message); if(!envelope.packet){ @@ -630,15 +631,19 @@ client.on("message", async (topic, message) => { } } - // Update Node MQTT status based on Last Packet Received time - await prisma.node.updateMany({ - where: { - node_id: convertHexIdToNumericId(envelope.gatewayId), - }, - data: { - mqtt_connection_state_updated_at: new Date(), - }, - }); + // track when a node last gated a packet to mqtt + try { + await prisma.node.updateMany({ + where: { + node_id: convertHexIdToNumericId(envelope.gatewayId), + }, + data: { + mqtt_connection_state_updated_at: new Date(), + }, + }); + } catch(e) { + // don't care if updating mqtt timestamp fails + } // attempt to decrypt encrypted packets const isEncrypted = envelope.packet.encrypted?.length > 0; From 1aed1fac7852c871e5b57a5d719a3bb9fc2a9995 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Wed, 28 Aug 2024 22:47:32 +1200 Subject: [PATCH 4/6] refactor mqtt status to own function and set default config --- src/public/index.html | 49 +++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index aff629e..8ed838c 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -1488,9 +1488,8 @@
-
Nodes that have not uploaded to MQTT in this time will show as blue icons. Reload to update map.
+
Nodes that have not uplinked to MQTT in this time will show as blue icons. Reload to update map.