@sailingrotevista/rotevista-dash 6.0.14 → 6.1.2
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 +58 -65
- package/index.js +10 -8
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -22,12 +22,12 @@ let CONFIG = {
|
|
|
22
22
|
minSpeed: 0.5,
|
|
23
23
|
stabilityBreakout: 15
|
|
24
24
|
},
|
|
25
|
-
graphs: { reef1:
|
|
25
|
+
graphs: { reef1: 5, reef2: 10, historyMinutes: 10, samples: 60 },
|
|
26
26
|
scales: {
|
|
27
27
|
stw: { stdMax: 4, hercSpan: 2, step: 1 },
|
|
28
28
|
sog: { stdMax: 4, hercSpan: 2, step: 1 },
|
|
29
29
|
tws: { stdMax: 15, hercSpan: 2, step: 1 },
|
|
30
|
-
depth: { stdMax:
|
|
30
|
+
depth: { stdMax: 5, hercSpan: 2, step: 1 }
|
|
31
31
|
},
|
|
32
32
|
server: { fallbackIp: "192.168.111.240:3000" }
|
|
33
33
|
};
|
|
@@ -128,6 +128,7 @@ function safeSetText(el, text) {
|
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* Inserimento sicuro nel buffer con trigonometria precaricata e pruning automatico
|
|
131
|
+
* Mantiene sempre almeno 60 minuti di memoria locale per il calcolo della bussola meteo.
|
|
131
132
|
*/
|
|
132
133
|
function safePush(buffer, val, time) {
|
|
133
134
|
if (val === null || val === undefined || isNaN(val)) return;
|
|
@@ -139,7 +140,11 @@ function safePush(buffer, val, time) {
|
|
|
139
140
|
cos: Math.cos(val)
|
|
140
141
|
});
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
// Se stiamo spingendo nel buffer TWD, conserviamo sempre almeno 60 minuti in memoria locale
|
|
144
|
+
const isTwdBuffer = (buffer === store.longBuf.twd);
|
|
145
|
+
const limitMinutes = isTwdBuffer ? 60 : CONFIG.graphs.historyMinutes;
|
|
146
|
+
const maxHistoryMs = (limitMinutes * 60000 * 2) + 60000;
|
|
147
|
+
|
|
143
148
|
while (buffer.length > 0 && (time - buffer[0].time) > maxHistoryMs) {
|
|
144
149
|
buffer.shift();
|
|
145
150
|
}
|
|
@@ -436,16 +441,20 @@ function processIncomingData(path, val, source, timeMs) {
|
|
|
436
441
|
|
|
437
442
|
// ==========================================================================
|
|
438
443
|
// 6. TREND VENTO (Tattico 2s vs 10s | Strategico 1m vs 10m)
|
|
444
|
+
// Sincronizzato sul tempo reale dei sensori per eliminare i conflitti di orologio.
|
|
439
445
|
// ==========================================================================
|
|
440
446
|
function updateWindTrend() {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const
|
|
445
|
-
|
|
447
|
+
// --- RISOLUZIONE CLOCK DRIFT SUI PALLINI METEO ---
|
|
448
|
+
// Usiamo il tempo del sensore (l'ultimo dato del TWD in memoria) invece dell'orologio del tablet
|
|
449
|
+
const latestTwdPoint = store.longBuf.twd.length > 0 ? store.longBuf.twd[store.longBuf.twd.length - 1] : null;
|
|
450
|
+
const now = latestTwdPoint ? latestTwdPoint.time : Date.now();
|
|
451
|
+
|
|
452
|
+
// --- 6.1 TREND TATTICO (AWA/TWA Sintonizzato) ---
|
|
453
|
+
const twaNow = getCircularAverageFromBuffer(store.longBuf.twa, 2000, true, now);
|
|
454
|
+
const twaRef = getCircularAverageFromBuffer(store.longBuf.twa, 10000, true, now);
|
|
446
455
|
const gaugeDots = { cw: document.getElementById('trend-gauge-cw'), ccw: document.getElementById('trend-gauge-ccw') };
|
|
447
456
|
|
|
448
|
-
// --- 6.2 ALLARME STRAMBATA CON ISTERESI (MACCHINA A STATI ANTI-BRANDEGGIO) ---
|
|
457
|
+
// --- 6.2 ALLARME STRAMBATA CON ISTERESI (MACCHINA A STATI ANTI-BRANDEGGIO Sintonizzato) ---
|
|
449
458
|
const instTwaRad = store.raw["environment.wind.angleTrueWater"];
|
|
450
459
|
let smoothedTwaDeg = null;
|
|
451
460
|
|
|
@@ -530,11 +539,15 @@ function updateWindTrend() {
|
|
|
530
539
|
}
|
|
531
540
|
}
|
|
532
541
|
|
|
533
|
-
// --- 6.3 TREND METEO STRATEGICO (TWD) ---
|
|
534
|
-
const twdNow = getCircularAverageFromBuffer(store.longBuf.twd, 60000, false);
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
const
|
|
542
|
+
// --- 6.3 TREND METEO STRATEGICO (TWD PARAMETRIZZATO E SINTONIZZATO) ---
|
|
543
|
+
const twdNow = getCircularAverageFromBuffer(store.longBuf.twd, 60000, false, now); // 1 minuto fisso
|
|
544
|
+
|
|
545
|
+
// Parametrizzazione rigida nel codice: 15 minuti in navigazione, 60 minuti all'ancora
|
|
546
|
+
const fixedTwdMinutes = isNavigating ? 15 : 60;
|
|
547
|
+
const strategicWindowMs = fixedTwdMinutes * 60000;
|
|
548
|
+
|
|
549
|
+
const twdRef = getCircularAverageFromBuffer(store.longBuf.twd, strategicWindowMs, false, now);
|
|
550
|
+
|
|
538
551
|
const compassDots = { cw: document.getElementById('trend-dot-cw'), ccw: document.getElementById('trend-dot-ccw') };
|
|
539
552
|
|
|
540
553
|
if (twdNow && twdRef) {
|
|
@@ -894,11 +907,16 @@ async function fetchServerHistory() {
|
|
|
894
907
|
}
|
|
895
908
|
}
|
|
896
909
|
// --- SILLABAZIONE STRATEGICA DELLA BUSSOLA METEO (TWD) ---
|
|
897
|
-
// Se il server ci invia lo storico del TWD, lo inseriamo
|
|
910
|
+
// Se il server ci invia lo storico del TWD, lo inseriamo calcolando i seni e coseni per i vettori
|
|
898
911
|
if (data.twd && data.twd.length > 0) {
|
|
899
|
-
store.longBuf.twd = data.twd
|
|
912
|
+
store.longBuf.twd = data.twd.map(p => ({
|
|
913
|
+
val: p.val,
|
|
914
|
+
time: p.time,
|
|
915
|
+
sin: Math.sin(p.val),
|
|
916
|
+
cos: Math.cos(p.val)
|
|
917
|
+
}));
|
|
900
918
|
console.log(`📈 Memoria strategica TWD sincronizzata dal server (${data.twd.length} punti).`);
|
|
901
|
-
|
|
919
|
+
}
|
|
902
920
|
console.log("📈 Storico dei grafici pre-popolato caricato dal server.");
|
|
903
921
|
}
|
|
904
922
|
} catch (err) {
|
|
@@ -1501,56 +1519,31 @@ window.addEventListener('contextmenu', e => e.preventDefault(), true);
|
|
|
1501
1519
|
async function init() {
|
|
1502
1520
|
loadDashboardState();
|
|
1503
1521
|
|
|
1504
|
-
//
|
|
1505
|
-
|
|
1506
|
-
startDisplayLoop();
|
|
1507
|
-
connect();
|
|
1508
|
-
|
|
1509
|
-
setInterval(watchConfigChanges, 10000);
|
|
1522
|
+
// Rileviamo se siamo sul Mac tramite file:// (Ambiente di sviluppo locale)
|
|
1523
|
+
const isLocalFile = (window.location.protocol === 'file:');
|
|
1510
1524
|
|
|
1511
|
-
//
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
if (document.visibilityState === 'visible') {
|
|
1518
|
-
// 1. Se la connessione è già attiva e sana, scarichiamo solo lo storico senza disconnetterci
|
|
1519
|
-
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
1520
|
-
console.log("⏰ Schermo sbloccato: connessione attiva, sincronizzazione dello storico.");
|
|
1521
|
-
fetchServerHistory().then(() => {
|
|
1522
|
-
['stw', 'sog', 'depth', 'tws'].forEach(refreshGraph);
|
|
1523
|
-
}).catch(err => {});
|
|
1524
|
-
}
|
|
1525
|
-
// 2. Se la connessione è persa o morta, forzatura riconnessione rapida
|
|
1526
|
-
else {
|
|
1527
|
-
console.log("⏰ Schermo sbloccato: connessione assente, forzatura riconnessione rapida.");
|
|
1528
|
-
if (socket) {
|
|
1529
|
-
try {
|
|
1530
|
-
socket.close();
|
|
1531
|
-
} catch (e) {
|
|
1532
|
-
connect();
|
|
1533
|
-
}
|
|
1534
|
-
} else {
|
|
1535
|
-
connect();
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
});
|
|
1525
|
+
// 1. CARICAMENTO STORICO GRAFICI REALI DAL CERBO GX
|
|
1526
|
+
try {
|
|
1527
|
+
await fetchServerHistory();
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
console.warn("⚠️ Impossibile caricare lo storico reale dal server.");
|
|
1530
|
+
}
|
|
1540
1531
|
|
|
1541
|
-
//
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1532
|
+
// 2. CARICAMENTO CONFIGURAZIONI REALI (Bypassato su Mac per preservare i tuoi test!)
|
|
1533
|
+
if (!isLocalFile) {
|
|
1534
|
+
await fetchServerConfig();
|
|
1535
|
+
} else {
|
|
1536
|
+
// Mantiene la CONFIG locale di app.js per farti fare le prove delle scale sul Mac
|
|
1537
|
+
console.log("🎮 Esecuzione locale file://: utilizzo delle calibrazioni di CONFIG locali di debug.");
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
startDisplayLoop();
|
|
1541
|
+
connect(); // Si collegherà in tempo reale al WebSocket reale della barca
|
|
1542
|
+
|
|
1543
|
+
// Controlla le modifiche di configurazione sul Cerbo solo se non siamo sul Mac via file://
|
|
1544
|
+
if (!isLocalFile) {
|
|
1545
|
+
setInterval(watchConfigChanges, 10000);
|
|
1546
|
+
}
|
|
1554
1547
|
}
|
|
1555
1548
|
|
|
1556
1549
|
|
package/index.js
CHANGED
|
@@ -219,16 +219,18 @@ module.exports = function (app) {
|
|
|
219
219
|
if (!isFinite(finalValue)) return;
|
|
220
220
|
finalValue = Math.max(0, finalValue);
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
222
|
+
// Salvataggio nel ring buffer dello storico principale
|
|
223
|
+
histories[type].push({ val: finalValue, time: now });
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
// Pruning automatico basato sulle impostazioni di timeline
|
|
226
|
+
// (Forziamo il server a conservare sempre almeno 60 minuti per il TWD!)
|
|
227
|
+
const limitMinutes = (type === 'twd') ? 60 : historyMinutes;
|
|
228
|
+
const maxViewportMinutes = limitMinutes * 2;
|
|
229
|
+
const maxHistoryMs = (maxViewportMinutes * 60000) + 60000;
|
|
228
230
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
while (histories[type].length > 0 && (now - histories[type][0].time) > maxHistoryMs) {
|
|
232
|
+
histories[type].shift();
|
|
233
|
+
}
|
|
232
234
|
|
|
233
235
|
graphTempBuf[type] = [];
|
|
234
236
|
// Spostiamo il timer esattamente al confine del secchiello assoluto appena concluso
|