@sailingrotevista/rotevista-dash 7.0.13 → 7.0.15
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/app.js +30 -1
- package/index.js +25 -3
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -1128,13 +1128,42 @@ function connect() {
|
|
|
1128
1128
|
if (simulationMode) return;
|
|
1129
1129
|
let addr = window.location.host || CONFIG.server.fallbackIp;
|
|
1130
1130
|
try {
|
|
1131
|
-
|
|
1131
|
+
// Connessione con subscribe=none per impedire a Signal K l'invio automatico di tutto lo stream di bordo
|
|
1132
|
+
socket = new WebSocket(`ws://${addr}/signalk/v1/stream?subscribe=none`);
|
|
1132
1133
|
|
|
1133
1134
|
socket.onopen = async () => {
|
|
1134
1135
|
ui.status.className = "online";
|
|
1135
1136
|
ui.status.innerText = "ONLINE";
|
|
1136
1137
|
reconnectDelay = 1000;
|
|
1137
1138
|
|
|
1139
|
+
// Sottoscrizione selettiva bilanciata: applichiamo un filtro a 3 Hz (333ms) per i dati rapidi,
|
|
1140
|
+
// garantendo fluidità matematica senza ritardi e ottimizzando profondità (1s) e GPS (10s)
|
|
1141
|
+
const subscriptionPayload = {
|
|
1142
|
+
context: "vessels.self",
|
|
1143
|
+
subscribe: [
|
|
1144
|
+
{ path: "navigation.position", minPeriod: 60000 }, // Posizione GPS lenta (60s)
|
|
1145
|
+
{ path: "navigation.magneticVariation", minPeriod: 60000 }, // Declinazione lenta (60s)
|
|
1146
|
+
{ path: "environment.depth.belowTransducer", minPeriod: 1000 }, // Profondità di sicurezza (1s)
|
|
1147
|
+
{ path: "navigation.speedThroughWater", minPeriod: 333 }, // Velocità barca a 3 Hz (333ms)
|
|
1148
|
+
{ path: "navigation.speedOverGround", minPeriod: 333 }, // Velocità GPS a 3 Hz
|
|
1149
|
+
{ path: "navigation.courseOverGroundTrue", minPeriod: 333 }, // COG a 3 Hz
|
|
1150
|
+
{ path: "navigation.headingTrue", minPeriod: 333 }, // Heading True a 3 Hz
|
|
1151
|
+
{ path: "navigation.headingMagnetic", minPeriod: 333 }, // Heading Fallback a 3 Hz
|
|
1152
|
+
{ path: "environment.wind.speedApparent", minPeriod: 333 }, // AWS a 3 Hz
|
|
1153
|
+
{ path: "environment.wind.angleApparent", minPeriod: 333 }, // AWA a 3 Hz
|
|
1154
|
+
{ path: "environment.wind.speedTrue", minPeriod: 333 }, // TWS (Nativo) a 3 Hz
|
|
1155
|
+
{ path: "environment.wind.directionTrue", minPeriod: 333 } // TWD (Nativo) a 3 Hz
|
|
1156
|
+
]
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
// Invio del payload per configurare lo streaming selettivo a 3 Hz
|
|
1160
|
+
try {
|
|
1161
|
+
socket.send(JSON.stringify(subscriptionPayload));
|
|
1162
|
+
console.log("🔌 [WebSocket] Sottoscrizione selettiva a 3 Hz inviata con successo (Latenza azzerata).");
|
|
1163
|
+
} catch (err) {
|
|
1164
|
+
console.error("❌ [WebSocket] Impossibile inviare il payload di sottoscrizione:", err);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1138
1167
|
// SINCRONIZZAZIONE AUTOMATICA: Ogni volta che la connessione si apre o si riapre,
|
|
1139
1168
|
// scarichiamo lo storico fresco dal server e ridisegnamo i grafici
|
|
1140
1169
|
try {
|
package/index.js
CHANGED
|
@@ -83,7 +83,7 @@ module.exports = function (app) {
|
|
|
83
83
|
const localSubscription = {
|
|
84
84
|
context: 'vessels.self',
|
|
85
85
|
subscribe: [
|
|
86
|
-
{ path: 'navigation.position', minPeriod:
|
|
86
|
+
{ path: 'navigation.position', minPeriod: 60000 },
|
|
87
87
|
{ path: 'navigation.speedThroughWater', minPeriod: 1000 },
|
|
88
88
|
{ path: 'navigation.speedOverGround', minPeriod: 1000 },
|
|
89
89
|
{ path: 'environment.depth.belowTransducer', minPeriod: 1000 },
|
|
@@ -93,7 +93,7 @@ module.exports = function (app) {
|
|
|
93
93
|
{ path: 'environment.wind.directionTrue', minPeriod: 1000 },
|
|
94
94
|
{ path: 'navigation.headingTrue', minPeriod: 1000 },
|
|
95
95
|
{ path: 'navigation.headingMagnetic', minPeriod: 1000 },
|
|
96
|
-
{ path: 'navigation.magneticVariation', minPeriod:
|
|
96
|
+
{ path: 'navigation.magneticVariation', minPeriod: 60000 },
|
|
97
97
|
{ path: 'navigation.courseOverGroundTrue', minPeriod: 1000 }
|
|
98
98
|
]
|
|
99
99
|
};
|
|
@@ -141,12 +141,33 @@ module.exports = function (app) {
|
|
|
141
141
|
app.debug(msg);
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
+
// Helper per verificare se due valori sono identici (supporta anche oggetti complessi come la posizione lat/lon)
|
|
145
|
+
function isValueEqual(a, b) {
|
|
146
|
+
if (a === b) return true;
|
|
147
|
+
if (typeof a === 'object' && typeof b === 'object' && a !== null && b !== null) {
|
|
148
|
+
return a.latitude === b.latitude && a.longitude === b.longitude;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
144
153
|
/**
|
|
145
154
|
* processIncomingDelta: Decodifica i dati dei sensori in Knots/Meters ed esegue l'aggregazione
|
|
146
155
|
* Applica un filtro passa-basso continuo a ogni pacchetto e storicizza a 1Hz con dati stabilizzati.
|
|
147
156
|
*/
|
|
148
157
|
function processIncomingDelta(path, val) {
|
|
149
158
|
if (val === null || val === undefined) return;
|
|
159
|
+
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
const lastVal = raw[path];
|
|
162
|
+
const lastTime = lastPathProcessTimes[path] || 0;
|
|
163
|
+
|
|
164
|
+
// FILTRO DEDUPLICAZIONE CON HEARTBEAT DI SICUREZZA A 10 SECONDI:
|
|
165
|
+
// Se il nuovo dato è identico al precedente e sono passati meno di 10 secondi dall'ultimo invio,
|
|
166
|
+
// scartiamo subito l'elaborazione risparmiando cicli di CPU sul server.
|
|
167
|
+
// La soglia dei 10s garantisce la compatibilità con il Gap Detection dei grafici client.
|
|
168
|
+
if (lastVal !== undefined && isValueEqual(val, lastVal) && (now - lastTime < 10000)) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
150
171
|
|
|
151
172
|
// 1. Filtro anti-spike vento (> 100 nodi / 51.44 m/s)
|
|
152
173
|
if ((path === 'environment.wind.speedApparent' || path === 'environment.wind.speedTrue') && val > 51.44) {
|
|
@@ -162,7 +183,8 @@ module.exports = function (app) {
|
|
|
162
183
|
if (path === 'environment.depth.belowTransducer' && (val < -2.0 || val > 500)) {
|
|
163
184
|
return;
|
|
164
185
|
}
|
|
165
|
-
|
|
186
|
+
|
|
187
|
+
// Rimosso la seconda dichiarazione duplicata di 'now' poiché già dichiarata in cima alla funzione
|
|
166
188
|
const alpha = 1.0; // Passa-tutto istantaneo (i sensori di bordo ST60+ sono già calibrati con damping hardware a 12)
|
|
167
189
|
|
|
168
190
|
// FILTRO PASSA-BASSO CONTINUO IN TEMPO REALE (Previene gli Spike prima della storicizzazione)
|