@sailingrotevista/rotevista-dash 7.0.23 → 7.0.26
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 +20 -7
- package/charts.js +13 -3
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -514,11 +514,27 @@ function updateWindTrend() {
|
|
|
514
514
|
// Abbiamo eseguito una vera strambata stabile e siamo usciti dalla zona di poppa secca!
|
|
515
515
|
lastGybeSide = currentTack;
|
|
516
516
|
|
|
517
|
+
// Estraggo i dati correnti di vento reale (TWS), velocità (SOG) e l'angolo TWA smorzato
|
|
518
|
+
const twsKts = store.raw["environment.wind.speedTrue"] ? msToKts(store.raw["environment.wind.speedTrue"]) : 0;
|
|
519
|
+
const sogKts = msToKts(store.raw["navigation.speedOverGround"] || 0);
|
|
520
|
+
const twaDeg = Math.abs(smoothedTwaDeg);
|
|
521
|
+
|
|
522
|
+
// RILEVAMENTO AERODINAMICO MOTORE IN POPPA:
|
|
523
|
+
// Se siamo di poppa (TWA > 135°) e la velocità della barca supera il 75% della velocità del vento reale,
|
|
524
|
+
// è fisicamente impossibile essere a vela pura. Siamo a motore o in motorsailing.
|
|
525
|
+
const isMotoringDownwind = (twaDeg > 135) && (sogKts > (twsKts * 0.75));
|
|
526
|
+
|
|
527
|
+
// L'allarme strambata acustico è reale e attivo solo se:
|
|
528
|
+
// 1. C'è vento significativo (> 7.0 nodi)
|
|
529
|
+
// 2. La barca è in movimento (> 1.0 nodi)
|
|
530
|
+
// 3. NON siamo a motore/motorsailing (isMotoringDownwind è falso)
|
|
531
|
+
const isGybeDangerous = twsKts > 7.0 && sogKts > 1.0 && !isMotoringDownwind;
|
|
532
|
+
|
|
517
533
|
// Attivazione allarme acustico con blocco temporale di sicurezza (60 secondi)
|
|
518
|
-
if (
|
|
534
|
+
if (isGybeDangerous && (now - lastGybeAlarmTime > 60000)) {
|
|
519
535
|
lastGybeAlarmTime = now;
|
|
520
536
|
playGybeAlarm();
|
|
521
|
-
console.log(`⚠️ GYBE ALARM TRIGGERED: Tack switched to ${currentTack} (TWA: ${
|
|
537
|
+
console.log(`⚠️ GYBE ALARM TRIGGERED: Tack switched to ${currentTack} (TWA: ${twaDeg.toFixed(1)}°, TWS: ${twsKts.toFixed(1)}kts, SOG: ${sogKts.toFixed(1)}kts)`);
|
|
522
538
|
}
|
|
523
539
|
}
|
|
524
540
|
}
|
|
@@ -976,12 +992,9 @@ async function fetchServerHistory() {
|
|
|
976
992
|
}
|
|
977
993
|
}
|
|
978
994
|
|
|
979
|
-
// Sincronizza i dati specifici del radar storici
|
|
995
|
+
// Sincronizza i dati specifici del radar storici mantendo i timestamp calendarizzati assoluti (0% sfasamento dei perni)
|
|
980
996
|
if (data.windRadarSlots) {
|
|
981
|
-
store.windRadarSlots = data.windRadarSlots
|
|
982
|
-
...s,
|
|
983
|
-
timestamp: s.timestamp + timeDelta
|
|
984
|
-
}));
|
|
997
|
+
store.windRadarSlots = data.windRadarSlots; // Mantiene gli orari spaccati al minuto per l'uguaglianza del radar
|
|
985
998
|
}
|
|
986
999
|
if (data.futureForecast) {
|
|
987
1000
|
store.futureForecast = {
|
package/charts.js
CHANGED
|
@@ -163,15 +163,25 @@ function refreshGraph(t) {
|
|
|
163
163
|
|
|
164
164
|
if (!rawData || rawData.length < 2) return;
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
// ALINEAMENTO STRUTTURALE: Filtriamo lo storico mantenendo solo la finestra temporale visibile
|
|
167
|
+
// prima di calcolare la scala, allineando millimetricamente la scala Y con i pixel disegnati a schermo.
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
const visibleMinutes = CONFIG.graphs.historyMinutes * (isNavigating ? 1 : 2);
|
|
170
|
+
const viewportMs = visibleMinutes * 60000;
|
|
171
|
+
const viewportStart = now - viewportMs;
|
|
172
|
+
|
|
173
|
+
const visibleData = rawData.filter(p => p.time >= viewportStart);
|
|
174
|
+
if (visibleData.length < 2) return; // Abortisce se non ci sono abbastanza punti visibili
|
|
175
|
+
|
|
176
|
+
const values = visibleData.map(p => p.val); // Estrae i valori solo dei punti visibili
|
|
167
177
|
const mode = graphModes[boxType];
|
|
168
|
-
const cfg = calculateScale(boxType, values, mode);
|
|
178
|
+
const cfg = calculateScale(boxType, values, mode); // Calcola la scala Y esatta per la viewBox corrente
|
|
169
179
|
|
|
170
180
|
const box = document.querySelector(`.box-${boxType}`);
|
|
171
181
|
if (box) box.classList.toggle('box-hercules', mode === 'hercules');
|
|
172
182
|
|
|
173
183
|
updateScaleLabels(boxType, cfg.min, cfg.max);
|
|
174
|
-
drawGraph(
|
|
184
|
+
drawGraph(visibleData, boxType + '-graph', cfg.min, cfg.max, t === 'tws', mode === 'hercules');
|
|
175
185
|
}
|
|
176
186
|
|
|
177
187
|
// Genera fisicamente le curve e le aree SVG
|