@meri-imperiumi/signalk-meshtastic 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/package.json +1 -1
- package/plugin/commands/waypoint.js +1 -1
- package/plugin/index.js +19 -9
- package/plugin/telemetry.js +11 -8
package/README.md
CHANGED
|
@@ -91,6 +91,11 @@ Metrics used:
|
|
|
91
91
|
|
|
92
92
|
## Changes
|
|
93
93
|
|
|
94
|
+
* 1.2.4 (2026-02-15)
|
|
95
|
+
- Corrupted Node DB file should no longer crash the plugin
|
|
96
|
+
* 1.2.3 (2025-10-15)
|
|
97
|
+
- Nodes that haven't been seen in last two days are no longer registered to Signal K data structure
|
|
98
|
+
- Added safeties for various non-numeric telemetry and coordinate values
|
|
94
99
|
* 1.2.2 (2025-10-01)
|
|
95
100
|
- Set "last seen" timestamp of nodes based on packet payloads, not the time they're received
|
|
96
101
|
- Send timestamp with telemetry
|
package/package.json
CHANGED
|
@@ -47,7 +47,7 @@ module.exports = {
|
|
|
47
47
|
latitudeI: Math.floor(waypointVessel.navigation.position.value.latitude / 1e-7),
|
|
48
48
|
longitudeI: Math.floor(waypointVessel.navigation.position.value.longitude / 1e-7),
|
|
49
49
|
expire: Math.floor((new Date().getTime() / 1000) + (length * 60 * 60)),
|
|
50
|
-
name: waypointVessel.name,
|
|
50
|
+
name: waypointVessel.name || waypointVessel.mmsi,
|
|
51
51
|
description: `AIS vessel ${waypointVessel.mmsi}`,
|
|
52
52
|
icon: vesselIcon(waypointVessel),
|
|
53
53
|
});
|
package/plugin/index.js
CHANGED
|
@@ -101,7 +101,7 @@ function nodeToSignalK(app, node, nodeInfo, settings) {
|
|
|
101
101
|
},
|
|
102
102
|
];
|
|
103
103
|
|
|
104
|
-
if (nodeInfo.position) {
|
|
104
|
+
if (nodeInfo.position && Number.isFinite(nodeInfo.position.latitudeI)) {
|
|
105
105
|
values.push({
|
|
106
106
|
path: 'navigation.position',
|
|
107
107
|
value: {
|
|
@@ -511,7 +511,13 @@ module.exports = (app) => {
|
|
|
511
511
|
readFile(nodeDbFile, 'utf-8')
|
|
512
512
|
.catch(() => '{}')
|
|
513
513
|
.then((nodeDb) => {
|
|
514
|
-
|
|
514
|
+
let nodeDbData;
|
|
515
|
+
try {
|
|
516
|
+
nodeDbData = JSON.parse(nodeDb);
|
|
517
|
+
} catch (e) {
|
|
518
|
+
app.debug('Error reading Node DB file', e);
|
|
519
|
+
nodeDbData = {};
|
|
520
|
+
}
|
|
515
521
|
Object.keys(nodeDbData)
|
|
516
522
|
.forEach((nodeNum) => {
|
|
517
523
|
nodes[nodeNum] = nodeDbData[nodeNum];
|
|
@@ -561,10 +567,13 @@ module.exports = (app) => {
|
|
|
561
567
|
nodes[nodeInfo.num].publicKey = Buffer.from(nodeInfo.user.publicKey).toString('base64');
|
|
562
568
|
}
|
|
563
569
|
nodes[nodeInfo.num].seen = new Date(nodeInfo.lastHeard * 1000);
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
570
|
+
if (nodes[nodeInfo.num].seen > Date.now() - (1000 * 60 * 60 * 24 * 2)) {
|
|
571
|
+
// Node seen less than a two days ago, register with SK
|
|
572
|
+
const ctx = nodeToSignalK(app, nodes[nodeInfo.num], nodeInfo, settings);
|
|
573
|
+
if (ctx && ctx.indexOf('vessels.urn:mrn:imo:mmsi:') === 0) {
|
|
574
|
+
// We have an MMSI match, store it
|
|
575
|
+
nodes[nodeInfo.num].mmsi = ctx.split(':').at(-1);
|
|
576
|
+
}
|
|
568
577
|
}
|
|
569
578
|
setConnectionStatus();
|
|
570
579
|
writeNodeDb();
|
|
@@ -754,7 +763,7 @@ module.exports = (app) => {
|
|
|
754
763
|
},
|
|
755
764
|
{
|
|
756
765
|
path: 'navigation.gnss.antennaAltitude',
|
|
757
|
-
value: position.data.altitude,
|
|
766
|
+
value: position.data.altitude || 0,
|
|
758
767
|
},
|
|
759
768
|
];
|
|
760
769
|
app.handleMessage('signalk-meshtastic', {
|
|
@@ -847,7 +856,8 @@ module.exports = (app) => {
|
|
|
847
856
|
// Not connected to Meshtastic yet
|
|
848
857
|
return;
|
|
849
858
|
}
|
|
850
|
-
if (v.value.latitude
|
|
859
|
+
if (!Number.isFinite(v.value.latitude)
|
|
860
|
+
|| !Number.isFinite(v.value.longitude)) {
|
|
851
861
|
// No position
|
|
852
862
|
return;
|
|
853
863
|
}
|
|
@@ -911,7 +921,7 @@ module.exports = (app) => {
|
|
|
911
921
|
}
|
|
912
922
|
}
|
|
913
923
|
}
|
|
914
|
-
if (!mobPosition || !mobPosition.latitude) {
|
|
924
|
+
if (!mobPosition || !Number.isFinite(mobPosition.latitude)) {
|
|
915
925
|
return;
|
|
916
926
|
}
|
|
917
927
|
const setWaypointMessage = create(Protobuf.Mesh.WaypointSchema, {
|
package/plugin/telemetry.js
CHANGED
|
@@ -14,16 +14,16 @@ class Telemetry {
|
|
|
14
14
|
|
|
15
15
|
toMeshtastic() {
|
|
16
16
|
const values = {};
|
|
17
|
-
if (this.data['environment.outside.temperature']) {
|
|
17
|
+
if (Number.isFinite(this.data['environment.outside.temperature'])) {
|
|
18
18
|
values.temperature = this.data['environment.outside.temperature'] - 273.15;
|
|
19
19
|
}
|
|
20
|
-
if (this.data['environment.outside.relativeHumidity']) {
|
|
20
|
+
if (Number.isFinite(this.data['environment.outside.relativeHumidity'])) {
|
|
21
21
|
values.relativeHumidity = this.data['environment.outside.relativeHumidity'] * 100;
|
|
22
22
|
}
|
|
23
|
-
if (this.data['environment.outside.pressure']) {
|
|
23
|
+
if (Number.isFinite(this.data['environment.outside.pressure'])) {
|
|
24
24
|
values.barometricPressure = this.data['environment.outside.pressure'] / 100;
|
|
25
25
|
}
|
|
26
|
-
if (this.data['environment.wind.directionTrue']) {
|
|
26
|
+
if (Number.isFinite(this.data['environment.wind.directionTrue'])) {
|
|
27
27
|
values.windDirection = Math.floor(this.data['environment.wind.directionTrue'] * (180 / Math.PI));
|
|
28
28
|
}
|
|
29
29
|
if (this.data['environment.wind.speedOverGround'] && this.data['environment.wind.speedOverGround'].length) {
|
|
@@ -38,16 +38,16 @@ class Telemetry {
|
|
|
38
38
|
// Clear wind history
|
|
39
39
|
this.data['environment.wind.speedOverGround'] = [];
|
|
40
40
|
}
|
|
41
|
-
if (this.data['electrical.batteries.house.voltage']) {
|
|
41
|
+
if (Number.isFinite(this.data['electrical.batteries.house.voltage'])) {
|
|
42
42
|
values.voltage = this.data['electrical.batteries.house.voltage'];
|
|
43
43
|
}
|
|
44
|
-
if (this.data['electrical.batteries.house.current']) {
|
|
44
|
+
if (Number.isFinite(this.data['electrical.batteries.house.current'])) {
|
|
45
45
|
values.current = this.data['electrical.batteries.house.current'] * 1000;
|
|
46
46
|
}
|
|
47
|
-
if (this.data['navigation.anchor.distanceFromBow']) {
|
|
47
|
+
if (Number.isFinite(this.data['navigation.anchor.distanceFromBow'])) {
|
|
48
48
|
// Using distance is a bit silly here as the unit is mm, but what can we do
|
|
49
49
|
values.distance = this.data['navigation.anchor.distanceFromBow'] * 1000;
|
|
50
|
-
} else if (this.data['environment.depth.belowSurface']) {
|
|
50
|
+
} else if (Number.isFinite(this.data['environment.depth.belowSurface'])) {
|
|
51
51
|
// If not anchored, report depth as distance. Still mm.
|
|
52
52
|
values.distance = this.data['environment.depth.belowSurface'] * 1000;
|
|
53
53
|
}
|
|
@@ -55,6 +55,9 @@ class Telemetry {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
updateWindSpeed(windSpeed) {
|
|
58
|
+
if (!Number.isFinite(windSpeed)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
58
61
|
if (!this.data['environment.wind.speedOverGround']) {
|
|
59
62
|
this.data['environment.wind.speedOverGround'] = [];
|
|
60
63
|
}
|