@sailingrotevista/rotevista-dash 7.0.10 → 7.0.11
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 +28 -9
- package/index.html +2 -2
- package/package.json +1 -1
- package/weather-radar.js +2 -1
package/app.js
CHANGED
|
@@ -98,9 +98,12 @@ const ui = {
|
|
|
98
98
|
twdChevron: document.getElementById('twd-wind-chevron'),
|
|
99
99
|
leewayMask: document.getElementById('leeway-mask-rect'), leewayVal: document.getElementById('leeway-val'),
|
|
100
100
|
tackHdg: document.getElementById('tack-hdg'), tackCog: document.getElementById('tack-cog'),
|
|
101
|
-
status: document.getElementById('status'), hotspot: document.getElementById('fullscreen-hotspot')
|
|
101
|
+
status: document.getElementById('status'), hotspot: document.getElementById('fullscreen-hotspot'),
|
|
102
|
+
tackLabel: document.getElementById('tack-label')
|
|
102
103
|
};
|
|
103
104
|
|
|
105
|
+
let currentTackLabelMode = 'TACK'; // Stato dell'etichetta tattica ('TACK' o 'GYBE') con isteresi
|
|
106
|
+
|
|
104
107
|
// ==========================================================================
|
|
105
108
|
// 3. UTILITIES (MATEMATICA, BUFFER E MEMORIA) - [Esportate in utils.js]
|
|
106
109
|
// ==========================================================================
|
|
@@ -238,8 +241,13 @@ function computeTrueWind() {
|
|
|
238
241
|
if (tws_water > 0.05) {
|
|
239
242
|
const twa = Math.atan2(aws * Math.sin(awa), aws * Math.cos(awa) - stw);
|
|
240
243
|
store.raw["environment.wind.angleTrueWater"] = twa;
|
|
244
|
+
|
|
245
|
+
// Inserimento atomico e sincronizzato di TWA e AWA nei relativi buffer mobili
|
|
246
|
+
// per garantire che le medie vettoriali siano perfettamente allineate in fase
|
|
241
247
|
safePush(store.smoothBuf.twa, twa, now);
|
|
242
248
|
safePush(store.longBuf.twa, twa, now);
|
|
249
|
+
safePush(store.smoothBuf.awa, awa, now);
|
|
250
|
+
safePush(store.longBuf.awa, awa, now);
|
|
243
251
|
}
|
|
244
252
|
|
|
245
253
|
// ==========================================================================
|
|
@@ -351,16 +359,16 @@ function processIncomingData(path, val, source, timeMs) {
|
|
|
351
359
|
// Evita di eseguire calcoli trigonometrici, allocare oggetti in memoria dinamica
|
|
352
360
|
// e popolare i buffer smoothBuf/longBuf decine di volte al secondo per singolo sensore.
|
|
353
361
|
if (!lastPathProcessTimes[path]) lastPathProcessTimes[path] = 0;
|
|
354
|
-
if (now - lastPathProcessTimes[path] <
|
|
362
|
+
if (now - lastPathProcessTimes[path] < 800) {
|
|
355
363
|
return; // Esce subito risparmiando cicli di calcolo del browser e batteria del tablet
|
|
356
364
|
}
|
|
357
365
|
lastPathProcessTimes[path] = now;
|
|
358
366
|
|
|
359
367
|
// Da qui in poi, l'inserimento nei buffer fisici avviene rigorosamente a 1Hz:
|
|
360
|
-
if (path === "environment.wind.angleApparent") {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
368
|
+
//if (path === "environment.wind.angleApparent") {
|
|
369
|
+
// safePush(store.smoothBuf.awa, val, now);
|
|
370
|
+
// safePush(store.longBuf.awa, val, now);
|
|
371
|
+
//}
|
|
364
372
|
|
|
365
373
|
// BUG RISOLTO: Intercetta il TWD nativo e lo spinge nei buffer della bussola radar
|
|
366
374
|
if (path === "environment.wind.directionTrue") {
|
|
@@ -462,7 +470,7 @@ function updateWindTrend() {
|
|
|
462
470
|
// Allarme VISIVO: Se siamo in zona di pericolo poppa profonda (> 155°), accendi entrambi i LED di rosso pulsante
|
|
463
471
|
if (absTwaDeg > 155) {
|
|
464
472
|
if (gaugeDots.cw) { gaugeDots.cw.classList.add('is-gybing'); gaugeDots.cw.setAttribute('fill', '#ff3b30'); }
|
|
465
|
-
if (gaugeDots.ccw) { gaugeDots.ccw.classList.
|
|
473
|
+
if (gaugeDots.ccw) { gaugeDots.ccw.classList.remove('is-gybing'); }
|
|
466
474
|
|
|
467
475
|
// LOGICA MACCHINA A STATI CON ISTERESI:
|
|
468
476
|
// Rileviamo le mure solo se siamo fuori dalla zona cieca di poppa secca (> 170°).
|
|
@@ -537,7 +545,7 @@ function updateWindTrend() {
|
|
|
537
545
|
const compassDots = { cw: document.getElementById('trend-dot-cw'), ccw: document.getElementById('trend-dot-ccw') };
|
|
538
546
|
|
|
539
547
|
if (twdNow && twdRef) {
|
|
540
|
-
let deltaMeteo = radToDeg((twdNow.val - twdRef.val + Math.PI * 3) % (Math.PI
|
|
548
|
+
let deltaMeteo = radToDeg((twdNow.val - twdRef.val + Math.PI * 3) % (2 * Math.PI) - Math.PI);
|
|
541
549
|
if (Math.abs(deltaMeteo) > 6.0) {
|
|
542
550
|
const isSouth = store.raw["navigation.position"]?.latitude < 0;
|
|
543
551
|
let meteoColor = (!isSouth) ? (deltaMeteo < 0 ? "#27ae60" : "#c0392b") : (deltaMeteo > 0 ? "#27ae60" : "#c0392b");
|
|
@@ -737,6 +745,17 @@ function startDisplayLoop() {
|
|
|
737
745
|
let twObj = getCircularAverageFromBuffer(store.longBuf.twa, CONFIG.averaging.longWindow, true);
|
|
738
746
|
let twdObj = getCircularAverageFromBuffer(store.longBuf.twd, CONFIG.averaging.longWindow, false);
|
|
739
747
|
|
|
748
|
+
// --- GESTIONE DINAMICA ETICHETTA TACK/GYBE CON ISTERESI DI 10 GRADI ---
|
|
749
|
+
if (ui.tackLabel) {
|
|
750
|
+
const absTwa = Math.abs(radToDeg(store.raw["environment.wind.angleTrueWater"] || 0));
|
|
751
|
+
if (currentTackLabelMode === 'TACK' && absTwa > 95) {
|
|
752
|
+
currentTackLabelMode = 'GYBE';
|
|
753
|
+
} else if (currentTackLabelMode === 'GYBE' && absTwa < 85) {
|
|
754
|
+
currentTackLabelMode = 'TACK';
|
|
755
|
+
}
|
|
756
|
+
safeSetText(ui.tackLabel, currentTackLabelMode);
|
|
757
|
+
}
|
|
758
|
+
|
|
740
759
|
upUI(ui.hdg, hObj, store.raw["navigation.headingTrue"], true);
|
|
741
760
|
upUI(ui.cog, cObj, store.raw["navigation.courseOverGroundTrue"], true);
|
|
742
761
|
upUI(ui.awaAvg, awObj, store.raw["environment.wind.angleApparent"], false);
|
|
@@ -1277,7 +1296,7 @@ document.addEventListener('visibilitychange', () => {
|
|
|
1277
1296
|
// Se era già chiuso o in errore, proviamo a riconnettere subito
|
|
1278
1297
|
connect();
|
|
1279
1298
|
} else {
|
|
1280
|
-
// Se
|
|
1299
|
+
// Se resulta "OPEN" ma potrebbe essere una connessione fantasma,
|
|
1281
1300
|
// la chiudiamo forzatamente per scatenare la riconnessione pulita e il download della cronologia
|
|
1282
1301
|
console.log("🔌 [Watchdog] Riavvio precauzionale del WebSocket per evitare connessioni fantasma.");
|
|
1283
1302
|
socket.close();
|
package/index.html
CHANGED
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
|
|
51
51
|
<div class="data-box box-tack">
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
<div class="label-row"><span class="label" id="tack-label">TACK</span></div>
|
|
53
|
+
<div class="dual-value-container">
|
|
54
54
|
<div class="dual-value-col tack-hdg-col">
|
|
55
55
|
<span class="dual-label">HDG</span>
|
|
56
56
|
<span class="value dual-val" id="tack-hdg">---°</span>
|
package/package.json
CHANGED
package/weather-radar.js
CHANGED
|
@@ -138,13 +138,14 @@ function renderRadar() {
|
|
|
138
138
|
radarDataList.push({
|
|
139
139
|
twdMin: (twdDeg - 20 + 360) % 360,
|
|
140
140
|
twdMax: (twdDeg + 20 + 360) % 360,
|
|
141
|
-
twsPeak: store.futureForecast.
|
|
141
|
+
twsPeak: store.futureForecast.gust, // Chirurgico: Usiamo il Gust come picco per visualizzare l'arco delle raffiche future
|
|
142
142
|
isFuture: true
|
|
143
143
|
});
|
|
144
144
|
} else {
|
|
145
145
|
radarDataList.push(null);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
|
|
148
149
|
// 2. ANELLO 1: Presente Mobile (Real-Time Client-Side)
|
|
149
150
|
const activeRing = calculateActive30mRing();
|
|
150
151
|
radarDataList.push(activeRing);
|