@sailingrotevista/rotevista-dash 7.0.11 → 7.0.13
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 +15 -10
- package/index.js +10 -5
- package/package.json +1 -1
- package/style.css +53 -9
- package/weather-radar.js +11 -1
package/app.js
CHANGED
|
@@ -23,7 +23,7 @@ let CONFIG = {
|
|
|
23
23
|
minSpeed: 0.5,
|
|
24
24
|
stabilityBreakout: 15
|
|
25
25
|
},
|
|
26
|
-
graphs: { reef1:
|
|
26
|
+
graphs: { reef1: 10, reef2: 15, historyMinutes: 10, samples: 60 },
|
|
27
27
|
scales: {
|
|
28
28
|
stw: { stdMax: 4, hercSpan: 2, step: 1 },
|
|
29
29
|
sog: { stdMax: 4, hercSpan: 2, step: 1 },
|
|
@@ -210,18 +210,23 @@ function checkDepthAlarm(m) {
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
* computeTrueWind: Calcola TWS, TWA e TWD strategico.
|
|
214
|
+
* Gestisce il fallback separato (Split-Fallback) in caso di dati parzialmente nativi di bordo.
|
|
215
|
+
*/
|
|
216
216
|
function computeTrueWind() {
|
|
217
217
|
const aws = store.raw["environment.wind.speedApparent"], awa = store.raw["environment.wind.angleApparent"];
|
|
218
|
-
const stw = store.raw["navigation.speedThroughWater"]
|
|
218
|
+
const stw = store.raw["navigation.speedThroughWater"], sog = store.raw["navigation.speedOverGround"] || 0;
|
|
219
219
|
const hdg = store.raw["navigation.headingTrue"] || 0, cog = store.raw["navigation.courseOverGroundTrue"] || 0;
|
|
220
220
|
if (aws === undefined || awa === undefined) return;
|
|
221
221
|
|
|
222
222
|
// Usiamo il tempo esatto di arrivo del pacchetto del vento per la coerenza dei buffer
|
|
223
223
|
const now = store.timestamps["environment.wind.speedApparent"] || Date.now();
|
|
224
224
|
|
|
225
|
+
// Verifica se lo STW fisicamente attivo ha trasmesso dati negli ultimi 15 secondi
|
|
226
|
+
const hasStw = store.timestamps["navigation.speedThroughWater"] && (now - store.timestamps["navigation.speedThroughWater"] < 15000);
|
|
227
|
+
// Se lo STW non è disponibile, usa automaticamente la velocità del GPS (SOG) come riferimento
|
|
228
|
+
const speedRef = hasStw && stw !== undefined ? stw : sog;
|
|
229
|
+
|
|
225
230
|
// ==========================================================================
|
|
226
231
|
// 1. GESTIONE TWS (NATIVO vs FALLBACK)
|
|
227
232
|
// ==========================================================================
|
|
@@ -232,14 +237,14 @@ function computeTrueWind() {
|
|
|
232
237
|
// Se la barca invia il TWS nativo, usiamo direttamente quello
|
|
233
238
|
tws_water = store.raw["environment.wind.speedTrue"] ? msToKts(store.raw["environment.wind.speedTrue"]) : 0;
|
|
234
239
|
} else {
|
|
235
|
-
// Altrimenti eseguiamo il calcolo vettoriale tattico
|
|
236
|
-
tws_water = Math.sqrt(aws * aws +
|
|
240
|
+
// Altrimenti eseguiamo il calcolo vettoriale tattico utilizzando la velocità di riferimento (STW o SOG)
|
|
241
|
+
tws_water = Math.sqrt(aws * aws + speedRef * speedRef - 2 * aws * speedRef * Math.cos(awa));
|
|
237
242
|
store.raw["environment.wind.speedTrue"] = tws_water;
|
|
238
243
|
}
|
|
239
244
|
|
|
240
245
|
// BUG RISOLTO: Calcoliamo il TWA sempre, indipendentemente dal TWS nativo!
|
|
241
246
|
if (tws_water > 0.05) {
|
|
242
|
-
const twa = Math.atan2(aws * Math.sin(awa), aws * Math.cos(awa) -
|
|
247
|
+
const twa = Math.atan2(aws * Math.sin(awa), aws * Math.cos(awa) - speedRef);
|
|
243
248
|
store.raw["environment.wind.angleTrueWater"] = twa;
|
|
244
249
|
|
|
245
250
|
// Inserimento atomico e sincronizzato di TWA e AWA nei relativi buffer mobili
|
|
@@ -523,10 +528,10 @@ function updateWindTrend() {
|
|
|
523
528
|
}
|
|
524
529
|
if (deltaTac > 0) {
|
|
525
530
|
if (gaugeDots.cw) { gaugeDots.cw.classList.add('is-trending'); gaugeDots.cw.setAttribute('fill', tacticColor); }
|
|
526
|
-
if (gaugeDots.ccw) { gaugeDots.ccw.classList.remove('is-trending'); }
|
|
531
|
+
if (gaugeDots.ccw) { gaugeDots.ccw.classList.remove('is-trending'); gaugeDots.ccw.setAttribute('fill', '#bbb'); } // Resetta l'attributo di riempimento del pallino inattivo
|
|
527
532
|
} else {
|
|
528
533
|
if (gaugeDots.ccw) { gaugeDots.ccw.classList.add('is-trending'); gaugeDots.ccw.setAttribute('fill', tacticColor); }
|
|
529
|
-
if (gaugeDots.cw) { gaugeDots.cw.classList.remove('is-trending'); }
|
|
534
|
+
if (gaugeDots.cw) { gaugeDots.cw.classList.remove('is-trending'); gaugeDots.cw.setAttribute('fill', '#bbb'); } // Resetta l'attributo di riempimento del pallino inattivo
|
|
530
535
|
}
|
|
531
536
|
} else {
|
|
532
537
|
[gaugeDots.cw, gaugeDots.ccw].forEach(el => { if(el){ el.classList.remove('is-trending'); el.setAttribute('fill', '#bbb'); }});
|
package/index.js
CHANGED
|
@@ -252,15 +252,20 @@ module.exports = function (app) {
|
|
|
252
252
|
// 2. Calcolo combinato di FALLBACK (Si attiva solo se la centralina non invia TWS/TWD nativi)
|
|
253
253
|
const aws = raw["environment.wind.speedApparent"];
|
|
254
254
|
const awa = raw["environment.wind.angleApparent"];
|
|
255
|
-
const stw = raw["navigation.speedThroughWater"]
|
|
255
|
+
const stw = raw["navigation.speedThroughWater"];
|
|
256
256
|
const sog = raw["navigation.speedOverGround"] || 0;
|
|
257
257
|
const hdg = raw["navigation.headingTrue"];
|
|
258
258
|
const cog = raw["navigation.courseOverGroundTrue"] || 0;
|
|
259
259
|
|
|
260
260
|
if (aws !== undefined && awa !== undefined) {
|
|
261
261
|
const awsKts = aws * 1.94384;
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
|
|
263
|
+
// Verifica se lo STW fisicamente attivo ha trasmesso dati negli ultimi 15 secondi
|
|
264
|
+
const hasStw = lastPathProcessTimes["navigation.speedThroughWater"] && (now - lastPathProcessTimes["navigation.speedThroughWater"] < 15000);
|
|
265
|
+
// Se lo STW non è disponibile, usa automaticamente la velocità del GPS (SOG) come riferimento
|
|
266
|
+
const speedKtsRef = hasStw && stw !== undefined ? (stw * 1.94384) : (sog * 1.94384);
|
|
267
|
+
|
|
268
|
+
const tw_water_x = awsKts * Math.cos(awa) - speedKtsRef;
|
|
264
269
|
const tw_water_y = awsKts * Math.sin(awa);
|
|
265
270
|
|
|
266
271
|
// Calcoliamo il TWS di fallback solo se non abbiamo visto dati nativi negli ultimi 5 secondi
|
|
@@ -271,8 +276,8 @@ module.exports = function (app) {
|
|
|
271
276
|
|
|
272
277
|
const twa = Math.atan2(tw_water_y, tw_water_x);
|
|
273
278
|
|
|
274
|
-
// La VMG viene
|
|
275
|
-
const vmg = Math.abs(
|
|
279
|
+
// La VMG viene calcolata usando la velocità di riferimento (STW reale o SOG di fallback)
|
|
280
|
+
const vmg = Math.abs(speedKtsRef * Math.cos(twa));
|
|
276
281
|
manageHistory('vmg', vmg);
|
|
277
282
|
|
|
278
283
|
// Calcoliamo il TWD di fallback solo se non abbiamo visto dati nativi negli ultimi 5 secondi
|
package/package.json
CHANGED
package/style.css
CHANGED
|
@@ -385,7 +385,7 @@ body.night-mode .alarm-danger {
|
|
|
385
385
|
|
|
386
386
|
/* ==========================================================================
|
|
387
387
|
9. WIDGETS E OVERRIDE SVG (GIORNO)
|
|
388
|
-
|
|
388
|
+
========================================================================= */
|
|
389
389
|
#status {
|
|
390
390
|
position: absolute;
|
|
391
391
|
top: 15px; right: 15px;
|
|
@@ -463,8 +463,46 @@ body.night-mode {
|
|
|
463
463
|
.night-mode .is-focused .scale-labels { color: #ff3333 !important; }
|
|
464
464
|
|
|
465
465
|
/* --- 10.4 WIND GAUGE (STRUMENTO CENTRALE) --- */
|
|
466
|
-
.night-mode #wind-gauge circle
|
|
467
|
-
|
|
466
|
+
.night-mode #wind-gauge circle:not(#trend-gauge-cw):not(#trend-gauge-ccw) {
|
|
467
|
+
fill: #000000 !important;
|
|
468
|
+
stroke: #220000 !important;
|
|
469
|
+
}
|
|
470
|
+
.night-mode #wind-gauge > circle:nth-of-type(2), .night-mode #fullscreen-hotspot {
|
|
471
|
+
fill: #050000 !important;
|
|
472
|
+
stroke: #330000 !important;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/* 1. STATO SPENTO/RIPOSO: Attivo solo se l'attributo fill originario è grigio (#bbb o #bbbbbb) */
|
|
476
|
+
.night-mode #trend-gauge-cw[fill="#bbb"],
|
|
477
|
+
.night-mode #trend-gauge-ccw[fill="#bbb"],
|
|
478
|
+
.night-mode #trend-gauge-cw[fill="#bbbbbb"],
|
|
479
|
+
.night-mode #trend-gauge-ccw[fill="#bbbbbb"] {
|
|
480
|
+
fill: #440000 !important; /* Rosso scurissimo soffuso */
|
|
481
|
+
stroke: none !important;
|
|
482
|
+
filter: none !important;
|
|
483
|
+
opacity: 0.3 !important;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* 2. STATO ATTIVO VERDE (Buono/Sotto-vento): Attivo solo se JS imposta il colore di lift (#27ae60) */
|
|
487
|
+
.night-mode #trend-gauge-cw[fill="#27ae60"],
|
|
488
|
+
.night-mode #trend-gauge-ccw[fill="#27ae60"] {
|
|
489
|
+
fill: #00C851 !important; /* Verde smeraldo brillante */
|
|
490
|
+
stroke: none !important;
|
|
491
|
+
filter: drop-shadow(0 0 5px #00C851) !important;
|
|
492
|
+
opacity: 1 !important;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/* 3. STATO ATTIVO ROSSO (Scarso/Sopra-vento o strambata): Attivo se JS imposta il colore di header (#c0392b) o se in allarme strambata */
|
|
496
|
+
.night-mode #trend-gauge-cw[fill="#c0392b"],
|
|
497
|
+
.night-mode #trend-gauge-ccw[fill="#c0392b"],
|
|
498
|
+
.night-mode #trend-gauge-cw.is-gybing,
|
|
499
|
+
.night-mode #trend-gauge-ccw.is-gybing {
|
|
500
|
+
fill: #ff3b30 !important; /* Rosso brillante */
|
|
501
|
+
stroke: none !important;
|
|
502
|
+
filter: drop-shadow(0 0 5px #ff3b30) !important;
|
|
503
|
+
opacity: 1 !important;
|
|
504
|
+
}
|
|
505
|
+
|
|
468
506
|
.night-mode #center-glow feDropShadow { flood-color: #ff0000 !important; flood-opacity: 0.6 !important; }
|
|
469
507
|
.night-mode #boat-icon { fill: #220000 !important; stroke: #ff0000 !important; stroke-width: 0.8px !important; opacity: 1 !important; }
|
|
470
508
|
.night-mode #aws-display-group text { fill: #800000 !important; }
|
|
@@ -490,10 +528,16 @@ body.night-mode {
|
|
|
490
528
|
.night-mode #twd-boat-wrap path { fill: #ff3333 !important; opacity: 0.4 !important; }
|
|
491
529
|
.night-mode #twd-arrow #twd-wind-chevron { stroke: #ff3333 !important; }
|
|
492
530
|
|
|
493
|
-
/* --- 10.6 LOGICA RED-SHIFT TREND --- */
|
|
494
|
-
.night-mode circle[fill="#bbb"], .night-mode circle[fill="#bbbbbb"]
|
|
495
|
-
|
|
496
|
-
|
|
531
|
+
/* --- 10.6 LOGICA RED-SHIFT TREND (PULITA) --- */
|
|
532
|
+
.night-mode circle[fill="#bbb"]:not(#trend-gauge-cw):not(#trend-gauge-ccw), .night-mode circle[fill="#bbbbbb"]:not(#trend-gauge-cw):not(#trend-gauge-ccw) {
|
|
533
|
+
fill: #440000 !important;
|
|
534
|
+
}
|
|
535
|
+
.night-mode circle[fill="#27ae60"]:not(#trend-gauge-cw):not(#trend-gauge-ccw) {
|
|
536
|
+
fill: #ff0000 !important;
|
|
537
|
+
}
|
|
538
|
+
.night-mode circle[fill="#c0392b"]:not(#trend-gauge-cw):not(#trend-gauge-ccw) {
|
|
539
|
+
fill: #800000 !important;
|
|
540
|
+
}
|
|
497
541
|
|
|
498
542
|
/* ==========================================================================
|
|
499
543
|
11. TREND E ANIMAZIONI
|
|
@@ -533,11 +577,11 @@ body.night-mode {
|
|
|
533
577
|
}
|
|
534
578
|
|
|
535
579
|
/* --- OVERRIDE NIGHT MODE PER IL WIND RADAR --- */
|
|
536
|
-
.night-mode #wind-radar circle {
|
|
580
|
+
.night-mode #wind-radar circle:not(.is-trending) {
|
|
537
581
|
fill: #000000 !important;
|
|
538
582
|
stroke: #220000 !important;
|
|
539
583
|
}
|
|
540
|
-
.night-mode #wind-radar circle:nth-of-type(2),
|
|
584
|
+
.night-mode #wind-radar circle:nth-of-type(2):not(.is-trending),
|
|
541
585
|
.night-mode #radar-hotspot {
|
|
542
586
|
fill: #050000 !important;
|
|
543
587
|
stroke: #330000 !important;
|
package/weather-radar.js
CHANGED
|
@@ -238,6 +238,16 @@ function renderRadar() {
|
|
|
238
238
|
borderPath.setAttribute("stroke-linecap", "round");
|
|
239
239
|
borderPath.setAttribute("opacity", opacityValue);
|
|
240
240
|
ringsContainer.appendChild(borderPath);
|
|
241
|
+
} else {
|
|
242
|
+
const borderPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
243
|
+
borderPath.setAttribute("d", pathData);
|
|
244
|
+
borderPath.setAttribute("fill", "none");
|
|
245
|
+
const isNight = document.body.classList.contains('night-mode');
|
|
246
|
+
borderPath.setAttribute("stroke", isNight ? "#220000" : "#90a4ae");
|
|
247
|
+
borderPath.setAttribute("stroke-width", BORDER_STROKE_WIDTH);
|
|
248
|
+
borderPath.setAttribute("stroke-linecap", "round");
|
|
249
|
+
borderPath.setAttribute("opacity", "0.6");
|
|
250
|
+
ringsContainer.appendChild(borderPath);
|
|
241
251
|
}
|
|
242
252
|
|
|
243
253
|
const mainPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
@@ -246,7 +256,7 @@ function renderRadar() {
|
|
|
246
256
|
mainPath.setAttribute("stroke", strokeColor);
|
|
247
257
|
mainPath.setAttribute("stroke-width", ARC_STROKE_WIDTH);
|
|
248
258
|
mainPath.setAttribute("stroke-linecap", "round");
|
|
249
|
-
mainPath.setAttribute("opacity", data.isFuture ? "0.
|
|
259
|
+
mainPath.setAttribute("opacity", data.isFuture ? "0.7" : opacityValue);
|
|
250
260
|
mainPath.id = data.isFuture ? "" : (index === 1 ? "active-present-arc" : "");
|
|
251
261
|
ringsContainer.appendChild(mainPath);
|
|
252
262
|
});
|