@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.
Files changed (3) hide show
  1. package/app.js +58 -65
  2. package/index.js +10 -8
  3. 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: 10, reef2: 15, historyMinutes: 10, samples: 60 },
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: 8, hercSpan: 1, step: 1 }
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
- const maxHistoryMs = (CONFIG.graphs.historyMinutes * 60000 * 2) + 60000;
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
- const now = Date.now();
442
-
443
- // --- 6.1 TREND TATTICO (AWA/TWA) ---
444
- const twaNow = getCircularAverageFromBuffer(store.longBuf.twa, 2000, true);
445
- const twaRef = getCircularAverageFromBuffer(store.longBuf.twa, 10000, true);
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
- const multiplier = isNavigating ? 1 : 2;
536
- const strategicWindowMs = CONFIG.graphs.historyMinutes * 60000 * multiplier;
537
- const twdRef = getCircularAverageFromBuffer(store.longBuf.twd, strategicWindowMs, false);
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 direttamente nella memoria a lungo termine
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
- // Proviamo un primo caricamento configurazioni
1505
- await fetchServerConfig();
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
- // RICONNESSIONE RAPIDA AL RISVEGLIO (VISIBILITY WATCHDOG)
1513
- // ==========================================================================
1514
-
1515
- // Quando sblocchi l'iPad o riapri la scheda, sincronizziamo in modo intelligente
1516
- document.addEventListener('visibilitychange', () => {
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
- // Rileva se il dispositivo è andato in sospensione misurando il ritardo dei secondi
1542
- let lastHeartbeat = Date.now();
1543
- setInterval(() => {
1544
- const now = Date.now();
1545
- const diff = now - lastHeartbeat;
1546
- lastHeartbeat = now;
1547
-
1548
- // Se passano più di 6 secondi tra un ciclo e l'altro (invece di 1 secondo),
1549
- // significa che il PC era in sospensione. Avviamo il risveglio.
1550
- if (diff > 6000) {
1551
- handleWakeUp();
1552
- }
1553
- }, 1000);
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
- // Salvataggio nel ring buffer dello storico principale
223
- histories[type].push({ val: finalValue, time: now });
222
+ // Salvataggio nel ring buffer dello storico principale
223
+ histories[type].push({ val: finalValue, time: now });
224
224
 
225
- // Pruning automatico basato sulle impostazioni di timeline
226
- const maxViewportMinutes = historyMinutes * 2;
227
- const maxHistoryMs = (maxViewportMinutes * 60000) + 60000;
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
- while (histories[type].length > 0 && (now - histories[type][0].time) > maxHistoryMs) {
230
- histories[type].shift();
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailingrotevista/rotevista-dash",
3
- "version": "6.0.14",
3
+ "version": "6.1.2",
4
4
  "description": "Wind Dashboard with navigation and course aids",
5
5
  "main": "index.js",
6
6
  "publishConfig": {