@sailingrotevista/rotevista-dash 6.2.3 → 6.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/index.js CHANGED
@@ -212,12 +212,11 @@ module.exports = function (app) {
212
212
  const vmg = Math.abs(stwKts * Math.cos(twa));
213
213
  manageHistory('vmg', vmg);
214
214
 
215
- // Calcoliamo il TWD di fallback solo se non abbiamo visto dati nativi negli ultimi 5 secondi
216
- if (hdg !== undefined && (now - lastNativeTwdTime > 5000)) {
217
- const twd = (hdg + twa + 2 * Math.PI) % (2 * Math.PI);
218
- twd = (twd + 2 * Math.PI) % (2 * Math.PI); // Sicurezza extra
219
- manageHistory('twd', twd);
220
- }
215
+ // Calcoliamo il TWD di fallback solo se non abbiamo visto dati nativi negli ultimi 5 secondi
216
+ if (hdg !== undefined && (now - lastNativeTwdTime > 5000)) {
217
+ const twd = (hdg + twa + 2 * Math.PI) % (2 * Math.PI);
218
+ manageHistory('twd', twd); // BUG RISOLTO: Rimossa la riassegnazione di "const" che mandava in crash il server
219
+ }
221
220
  }
222
221
  }
223
222
 
@@ -744,6 +743,7 @@ module.exports = function (app) {
744
743
  app.error('[Open-Meteo] Forecast matching slots not found for target time');
745
744
  }
746
745
  }
746
+
747
747
  /**
748
748
  * emitDelta: Scrive ed emette un aggiornamento di rotta direttamente nel
749
749
  * server principale di Signal K per renderlo disponibile a tutti i client WebSocket.
@@ -751,6 +751,7 @@ module.exports = function (app) {
751
751
  function emitDelta(path, value) {
752
752
  if (typeof app.handleMessage === 'function') {
753
753
  app.handleMessage(plugin.id, {
754
+ context: 'vessels.self', // BUG RISOLTO: Inserito il contesto Signal K per evitare lo scarto del delta
754
755
  updates: [
755
756
  {
756
757
  source: { label: 'rotevista-dash-plugin' },
@@ -767,6 +768,5 @@ module.exports = function (app) {
767
768
  }
768
769
  }
769
770
 
770
-
771
771
  return plugin;
772
772
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailingrotevista/rotevista-dash",
3
- "version": "6.2.3",
3
+ "version": "6.2.4",
4
4
  "description": "Wind Dashboard with navigation and course aids",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
package/radar.html CHANGED
@@ -311,6 +311,16 @@
311
311
  document.getElementById('debug-tws').innerText = tws.toFixed(1);
312
312
  document.getElementById('debug-twa').innerText = Math.round(radToDeg(twa)) + '°';
313
313
  document.getElementById('debug-twd').innerText = Math.round(radToDeg(twd)) + '°';
314
+
315
+ // --- ACCUMULO DATI REALI LOCALE (1Hz) ---
316
+ // Popoliamo i buffer locali ogni secondo per garantire il disegno immediato del Presente
317
+ store.twdMinuteBuffer.push({ val: twd, min: twd, max: twd, time: now });
318
+ while(store.twdMinuteBuffer.length > 1800) store.twdMinuteBuffer.shift(); // conserva 30 minuti a 1Hz
319
+
320
+ store.twsMinuteBuffer.push({ val: tws, time: now });
321
+ while(store.twsMinuteBuffer.length > 1800) store.twsMinuteBuffer.shift();
322
+
323
+ renderRadar(); // Rinfresco grafico istantaneo reattivo
314
324
  }
315
325
  }
316
326
 
@@ -352,7 +362,7 @@
352
362
  document.getElementById('debug-gps').innerText = val.latitude.toFixed(4) + '; ' + val.longitude.toFixed(4);
353
363
  }
354
364
 
355
- // BUG RISOLTO CHIRURGICAMENTE: Allineamento chiavi REST storiche twd e tws sintonizzate!
365
+ // Sincronizzazione automatica allineata alle chiavi REST storiche reali del server
356
366
  if (data.twd) store.twdMinuteBuffer = data.twd;
357
367
  if (data.tws) store.twsMinuteBuffer = data.tws;
358
368
  }
@@ -388,7 +398,7 @@
388
398
  u.values.forEach(v => {
389
399
  processIncomingDelta(v.path, v.value, sourceLabel, timeMs);
390
400
 
391
- // COMPATIBILITÀ TOTALE DEL COPRIMENTO WEB-SOCKET:
401
+ // Ricezione live delle emissioni delta del nostro plugin server
392
402
  if (v.path === 'environment.wind.directionTrue') {
393
403
  let val, min, max;
394
404
  if (v.value && typeof v.value === 'object' && v.value.val !== undefined) {
@@ -678,7 +688,7 @@
678
688
  const radius = ringRadii[index];
679
689
  const gradId = `chord-gradient-${index}`;
680
690
 
681
- // BUG RISOLTO CHIRURGICAMENTE: Rimosso il sbiadimento grigio (opacità sempre fissa a 1 per colore solido e brillante)
691
+ // Opacità sempre fissa a 1 per colore solido e brillante (BUG RISOLTO)
682
692
  const opacityValue = 1;
683
693
 
684
694
  // Caso A: Calma Piatta
@@ -0,0 +1,233 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="it">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Signal K Wind Radar - Server RAM Diagnostic Panel</title>
8
+ <style>
9
+ body {
10
+ background-color: #0c0c0c;
11
+ color: #00ff66;
12
+ font-family: 'Courier New', Courier, monospace;
13
+ padding: 20px;
14
+ margin: 0;
15
+ box-sizing: border-box;
16
+ }
17
+
18
+ h1 {
19
+ color: #ffffff;
20
+ font-size: 1.4rem;
21
+ border-bottom: 2px solid #00ff66;
22
+ padding-bottom: 10px;
23
+ margin-top: 0;
24
+ }
25
+
26
+ .controls {
27
+ background: #111;
28
+ border: 1px solid #333;
29
+ padding: 15px;
30
+ border-radius: 8px;
31
+ margin-bottom: 20px;
32
+ display: flex;
33
+ flex-wrap: wrap;
34
+ gap: 15px;
35
+ align-items: center;
36
+ }
37
+
38
+ input[type="text"] {
39
+ background: #000;
40
+ color: #00ff66;
41
+ border: 1px solid #00ff66;
42
+ padding: 8px 12px;
43
+ font-family: monospace;
44
+ border-radius: 4px;
45
+ width: 250px;
46
+ }
47
+
48
+ button {
49
+ background: #00ff66;
50
+ color: #000000;
51
+ border: none;
52
+ padding: 8px 15px;
53
+ font-weight: bold;
54
+ font-family: monospace;
55
+ cursor: pointer;
56
+ border-radius: 4px;
57
+ }
58
+
59
+ button:hover {
60
+ background: #ffffff;
61
+ }
62
+
63
+ .status-box {
64
+ font-size: 13px;
65
+ line-height: 1.5;
66
+ margin-bottom: 20px;
67
+ padding: 15px;
68
+ background: #141414;
69
+ border: 1px solid #222;
70
+ border-radius: 8px;
71
+ }
72
+
73
+ .grid {
74
+ display: grid;
75
+ grid-template-columns: repeat(auto-fit, minmax(45%, 1fr));
76
+ gap: 20px;
77
+ }
78
+
79
+ .panel {
80
+ background: #111;
81
+ border: 1px solid #333;
82
+ border-radius: 8px;
83
+ padding: 15px;
84
+ box-sizing: border-box;
85
+ display: flex;
86
+ flex-direction: column;
87
+ }
88
+
89
+ .panel-title {
90
+ color: #ffffff;
91
+ font-weight: bold;
92
+ font-size: 1.1rem;
93
+ margin-bottom: 10px;
94
+ border-bottom: 1px solid #222;
95
+ padding-bottom: 5px;
96
+ text-transform: uppercase;
97
+ }
98
+
99
+ pre {
100
+ background: #000000;
101
+ border: 1px solid #222;
102
+ padding: 10px;
103
+ border-radius: 4px;
104
+ overflow: auto;
105
+ max-height: 400px;
106
+ font-size: 11px;
107
+ color: #00ff66;
108
+ margin: 0;
109
+ box-sizing: border-box;
110
+ flex-grow: 1;
111
+ }
112
+
113
+ .success { color: #00ff66; }
114
+ .danger { color: #ff3333; }
115
+ .warning { color: #ffcc00; }
116
+ </style>
117
+ </head>
118
+ <body>
119
+
120
+ <h1>Signal K Wind Radar - Server RAM Diagnostic Panel (v6.0)</h1>
121
+
122
+ <!-- PANNELLO DI CONTROLLO IP -->
123
+ <div class="controls">
124
+ <label>Indirizzo IP Server SK:</label>
125
+ <input type="text" id="server-ip" value="192.168.111.240:3000">
126
+ <button onclick="runManualDiagnostic()">Esegui Scansione Ora</button>
127
+ <span id="diagnostic-running" style="display: none; color: #ffcc00;">SCANSIONE IN CORSO...</span>
128
+ </div>
129
+
130
+ <!-- STATO DELLE RISPOSTE DEL SERVER -->
131
+ <div class="status-box">
132
+ <div style="font-weight: bold; font-size: 15px; margin-bottom: 8px; color: #fff;">Sintesi Connessione REST:</div>
133
+ <div>• Endpoint Configurazione (/rotevista-config): <span id="status-config" class="warning">IN ATTESA...</span></div>
134
+ <div>• Endpoint Storico RAM (/rotevista-history): <span id="status-history" class="warning">IN ATTESA...</span></div>
135
+ <div style="margin-top: 10px; border-top: 1px dashed #222; padding-top: 10px;">
136
+ • Picchi Vento in RAM (histories.tws): <span id="stat-tws" class="warning">--</span> |
137
+ • Direzioni Vento in RAM (histories.twd): <span id="stat-twd" class="warning">--</span> |
138
+ • Archi Bussola in RAM (windRadarSlots): <span id="stat-slots" class="warning">--</span>
139
+ </div>
140
+ </div>
141
+
142
+ <!-- GRIGLIA DUMP MEMORIA GREZZA -->
143
+ <div class="grid">
144
+
145
+ <!-- PANNELLO SINISTRO: DUMP CONFIG -->
146
+ <div class="panel">
147
+ <div class="panel-title">Raw Config Dump (/rotevista-config)</div>
148
+ <pre id="dump-config">In attesa di scansione...</pre>
149
+ </div>
150
+
151
+ <!-- PANNELLO DESTRO: DUMP COSTRUZIONE STORICO -->
152
+ <div class="panel">
153
+ <div class="panel-title">Raw History & Radar Dump (/rotevista-history)</div>
154
+ <pre id="dump-history">In attesa di scansione...</pre>
155
+ </div>
156
+
157
+ </div>
158
+
159
+ <script>
160
+ // Estrapola l'indirizzo dinamico dall'URL della barra indirizzi se caricato dal server
161
+ window.onload = function() {
162
+ let addr = window.location.host || "192.168.111.240:3000";
163
+ document.getElementById('server-ip').value = addr;
164
+ runManualDiagnostic();
165
+ // Esegue un poll diagnostico automatico ogni 5 secondi
166
+ setInterval(runManualDiagnostic, 5000);
167
+ };
168
+
169
+ function getTargetUrl(path) {
170
+ const ip = document.getElementById('server-ip').value;
171
+ return `http://${ip}${path}`;
172
+ }
173
+
174
+ async function runManualDiagnostic() {
175
+ document.getElementById('diagnostic-running').style.display = 'inline';
176
+
177
+ const configPre = document.getElementById('dump-config');
178
+ const historyPre = document.getElementById('dump-history');
179
+
180
+ const statusConfig = document.getElementById('status-config');
181
+ const statusHistory = document.getElementById('status-history');
182
+
183
+ // 1. SCANSIONE /rotevista-config
184
+ try {
185
+ const resConfig = await fetch(getTargetUrl('/rotevista-config'));
186
+ if (resConfig.ok) {
187
+ const data = await resConfig.json();
188
+ configPre.innerText = JSON.stringify(data, null, 2);
189
+ statusConfig.innerHTML = `<span class="success">RISPOSTA OK (200) - Configurazione Caricata</span>`;
190
+ } else {
191
+ statusConfig.innerHTML = `<span class="danger">ERRORE SERVER (${resConfig.status})</span>`;
192
+ configPre.innerText = "Il server ha risposto con un codice di errore.";
193
+ }
194
+ } catch (err) {
195
+ statusConfig.innerHTML = `<span class="danger">ERRORE DI RETE (Impossibile raggiungere il server)</span>`;
196
+ configPre.innerText = `Errore di connessione:\n${err.message}\n\nConsiglio:\n1. Verifica che l'IP del Cerbo sia corretto.\n2. Verifica che il tablet sia connesso alla rete Wi-Fi della barca.`;
197
+ }
198
+
199
+ // 2. SCANSIONE /rotevista-history
200
+ try {
201
+ const resHistory = await fetch(getTargetUrl('/rotevista-history'));
202
+ if (resHistory.ok) {
203
+ const data = await resHistory.json();
204
+ historyPre.innerText = JSON.stringify(data, null, 2);
205
+ statusHistory.innerHTML = `<span class="success">RISPOSTA OK (200) - Storico Caricato</span>`;
206
+
207
+ // Mostra statistiche dei record in RAM sul server
208
+ const countTws = data.tws ? data.tws.length : 0;
209
+ const countTwd = data.twd ? data.twd.length : 0;
210
+ const countSlots = data.windRadarSlots ? data.windRadarSlots.length : 0;
211
+
212
+ document.getElementById('stat-tws').innerHTML = `<span class="success">${countTws} punti</span>`;
213
+ document.getElementById('stat-twd').innerHTML = `<span class="success">${countTwd} punti</span>`;
214
+ document.getElementById('stat-slots').innerHTML = `<span class="success">${countSlots}/12 congelati</span>`;
215
+
216
+ } else {
217
+ statusHistory.innerHTML = `<span class="danger">ERRORE SERVER (${resHistory.status})</span>`;
218
+ historyPre.innerText = "Il server ha risposto con un codice di errore.";
219
+ }
220
+ } catch (err) {
221
+ statusHistory.innerHTML = `<span class="danger">ERRORE DI RETE (Impossibile raggiungere lo storico)</span>`;
222
+ historyPre.innerText = `Errore di connessione:\n${err.message}`;
223
+
224
+ document.getElementById('stat-tws').innerHTML = `<span class="danger">--</span>`;
225
+ document.getElementById('stat-twd').innerHTML = `<span class="danger">--</span>`;
226
+ document.getElementById('stat-slots').innerHTML = `<span class="danger">--</span>`;
227
+ }
228
+
229
+ document.getElementById('diagnostic-running').style.display = 'none';
230
+ }
231
+ </script>
232
+ </body>
233
+ </html>