signalk-pypilot-newui 2.7.0 → 2.7.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.
- package/CHANGELOG.md +146 -1839
- package/README.md +136 -220
- package/dist/test/plugin.test.js +70 -0
- package/package.json +8 -7
- package/public/screenshots/01-control-rose.jpg +0 -0
- package/public/screenshots/02-chart-trip-stats.jpg +0 -0
- package/public/screenshots/03-tune-gains.jpg +0 -0
- package/public/screenshots/04-setup-launcher.jpg +0 -0
- package/public/screenshots/05-race-timer.jpg +0 -0
- package/public/screenshots/06-info.jpg +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,1870 +1,177 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2.7.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- **
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
server sets a sticky `coreOffline` that only clears when the core
|
|
96
|
-
actually starts talking again — a fresh catalog delivery or a live
|
|
97
|
-
`pypilot` value. `healthy` and `set()` both consume this flag, so
|
|
98
|
-
a socket that keeps ponging while the core is dead can no longer
|
|
99
|
-
report success on writes. New events `pypilot_offline` /
|
|
100
|
-
`pypilot_online` are wired into `index.ts` to update plugin status
|
|
101
|
-
and mark the AP provider offline.
|
|
102
|
-
- **`allowWrites` gate is now global** (audit R05). Previously only
|
|
103
|
-
the plugin's own HTTP routes honoured it — the Autopilot API v2
|
|
104
|
-
provider interface, the KIP action PUT handlers and the momentary
|
|
105
|
-
switches all bypassed it. The check now lives in
|
|
106
|
-
`PypilotClient.set()` (single point every writer routes through)
|
|
107
|
-
plus a `writesOff()` 403 response on every PUT handler so
|
|
108
|
-
KIP/WilhelmSK/freeboard see a legible reason instead of a silent
|
|
109
|
-
no-op.
|
|
110
|
-
- **Generation counter cancels stale engage retries** (audit
|
|
111
|
-
R01+R04). `AutopilotProvider` bumps `engageGen` on every
|
|
112
|
-
`setState` call and cancels any pending NAV-mode 500 ms timer.
|
|
113
|
-
`_setWithRetry` accepts an `isStale()` callback that aborts the
|
|
114
|
-
backoff between attempts. A disengage landing mid-retry now
|
|
115
|
-
invalidates the still-pending engage, and vice versa; the delayed
|
|
116
|
-
NAV activation can no longer wake up after a disengage.
|
|
117
|
-
- **Restore banner sequenced with hard-fail** (audit R02). The "yes,
|
|
118
|
-
restore" path now runs mode → target → engage in that order, each
|
|
119
|
-
step guarded by `throwIfNotOk(res, op)` that treats both an
|
|
120
|
-
absent response and any HTTP >=400 as a stop condition. Target
|
|
121
|
-
is prepared before engage so the AP does not latch on the current
|
|
122
|
-
heading first and then jerk. Failure is spoken ("Restore failed"
|
|
123
|
-
/ "Restauración fallida") and shown as a red line in the banner
|
|
124
|
-
instead of the previous silent `catch`.
|
|
125
|
-
- **Access-request precedence bug** (audit T09). Fixed `j.href ||
|
|
126
|
-
j.requestId ? ... : null` operator precedence that was building
|
|
127
|
-
`/requests/undefined` when the server returned an explicit
|
|
128
|
-
`href`. Now `j.href || (j.requestId ? ... : null)`.
|
|
129
|
-
|
|
130
|
-
**Rev272 fixes** (close the remaining two audit points):
|
|
131
|
-
|
|
132
|
-
- **`adjustTarget` serialisation** (audit R06). Two concurrent
|
|
133
|
-
`+Δ` calls used to read the same base from `data.target` before
|
|
134
|
-
awaiting the write and both wrote `base+Δ`, losing one increment.
|
|
135
|
-
A single `_adjustChain` promise now serialises adjusts through
|
|
136
|
-
the provider so the second call reads the base written by the
|
|
137
|
-
first. Errors on one call do not poison the next caller's turn.
|
|
138
|
-
- **`shortestArcRad` bounded + finite guards** (audit R07). The
|
|
139
|
-
angular normalisation loop is now a single modulo (constant cost)
|
|
140
|
-
and returns 0 on a non-finite delta. `setTarget` and
|
|
141
|
-
`adjustTarget` also reject `NaN` / `Infinity` / astronomically
|
|
142
|
-
large radians at the boundary with a clear error, so a
|
|
143
|
-
misbehaving integration cannot poison provider state.
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## 2.7.0 headline — Rev246..Rev269: connection resilience + reliability + full i18n audit
|
|
148
|
-
|
|
149
|
-
Sea-trial-driven release. After several sessions of **intensive
|
|
150
|
-
sailing and beta testing** on Tunatunes we surfaced (and closed) a
|
|
151
|
-
long list of connection-resilience holes, TTS gaps, i18n drifts and
|
|
152
|
-
UX rough edges that only show up when the boat is under way, the
|
|
153
|
-
TinyPilot resets, or the link flakes. The whole batch was audited
|
|
154
|
-
twice by an external LLM auditor between iterations before being
|
|
155
|
-
folded back in.
|
|
156
|
-
|
|
157
|
-
### English
|
|
158
|
-
|
|
159
|
-
**Added**
|
|
160
|
-
|
|
161
|
-
- **Full "Pypilot down" UX cycle**: passive UI reflection tied to a
|
|
162
|
-
pong-based heartbeat. When the socket goes silent for > 8 s the
|
|
163
|
-
target diamond and TGT chip hide immediately, AP-affecting
|
|
164
|
-
controls grey out with a `.pypilot-offline` class, and the
|
|
165
|
-
alarm rule `pypilot-disconnected` fires with a spoken message
|
|
166
|
-
("Pypilot desconectado desde hace N segundos") whose h / min / s
|
|
167
|
-
units are read as full words instead of abbreviations. On
|
|
168
|
-
reconnect: green "Pypilot operativo" toast + voice announcement
|
|
169
|
-
+ controls reactivate.
|
|
170
|
-
- **Three-tier outage handler**: on reconnect the visor compares
|
|
171
|
-
the outage length against the last known target. < 20 s: no
|
|
172
|
-
action (probably a hiccup). 20 s – 5 min: banner offers to
|
|
173
|
-
restore the previous target with Sí / No buttons. > 5 min:
|
|
174
|
-
nothing (too long, sailor most likely wants a fresh engage).
|
|
175
|
-
- **Optimistic write-then-throw pattern** with `client.set()`
|
|
176
|
-
returning `boolean`. `apEngage / apDisengage / apSetMode /
|
|
177
|
-
apSetTargetRad / apTack` reject BEFORE mutating optimistic state,
|
|
178
|
-
so a phantom command against an offline TinyPilot cannot leave
|
|
179
|
-
the UI stuck in "engaged" waiting for a delta that will never
|
|
180
|
-
arrive.
|
|
181
|
-
- **`_setWithRetry` helper** (250 ms + 750 ms backoff) around the
|
|
182
|
-
autopilot-provider adapter for transient socket blips.
|
|
183
|
-
- **Watchdog + pong heartbeat** in `pypilot-client.ts`: `healthy`
|
|
184
|
-
getter combines `socket.connected` with `lastPongMs <= 8 s`.
|
|
185
|
-
Alarm engine consumes `client.healthy` (not `.connected`) so
|
|
186
|
-
the network layer and the alarm engine agree on liveness. Alarm
|
|
187
|
-
ordering also reworked so `sensor-lost` no longer fires _before_
|
|
188
|
-
`pypilot-disconnected` when the whole socket dies.
|
|
189
|
-
- **Multi-tab session isolation**: owner keys now live in
|
|
190
|
-
`sessionStorage` (per-tab) not `localStorage`, so two visor tabs
|
|
191
|
-
do not race to release focus watches.
|
|
192
|
-
- **Signed-delta rotation counter** (Rev247) for the HUD progress
|
|
193
|
-
during tack maneuvers: accumulates the SIGNED angular delta so
|
|
194
|
-
IMU / compass jitter cancels around zero and the counter no
|
|
195
|
-
longer drifts to "0° remaining" with the boat still 100°
|
|
196
|
-
short. The 0.5° threshold that produced the false report
|
|
197
|
-
was removed entirely.
|
|
198
|
-
- **Full i18n audit** across EN / ES / DE / FR: purged mixed
|
|
199
|
-
Spanish text from EN-only modals (Boat menu, Tack log, Trip
|
|
200
|
-
detail, Trip share, Gust marker overlay, Bottom-bar picker,
|
|
201
|
-
nav-toggle aria-label), added `data-lang` variants, moved the
|
|
202
|
-
bottom-bar strings to i18n keys, added `data-i18n-title` on the
|
|
203
|
-
tack buttons. Rebrand "Gota Chain" (which "nobody understood",
|
|
204
|
-
per Carlos) as **"Target & Wind arrows"** / "Flechas
|
|
205
|
-
Target y Viento" everywhere it is public-facing (README, Info
|
|
206
|
-
modal, NPM screenshot title).
|
|
207
|
-
- **Spanish orthography pass**: `"COMPAS"` → `"COMPÁS"`
|
|
208
|
-
in the ES mode label, `<code>compas / gps / viento / real</code>`
|
|
209
|
-
→ the literal `<code>compass / gps / wind / true</code>`
|
|
210
|
-
string (they are pypilot enum values, not translatable words).
|
|
211
|
-
- **Full instructions section** in the Info modal (EN + ES)
|
|
212
|
-
covering every tab now that Chart / Race / Doctor / Smart Pilot
|
|
213
|
-
/ Alarms / Sensor Quality / Session recorder / Log capture /
|
|
214
|
-
Debug console / Remote Control Console / Watchdog have all
|
|
215
|
-
landed.
|
|
216
|
-
- **Health status endpoint** (`/status`) now returns
|
|
217
|
-
`healthy: boolean` alongside `connected`.
|
|
218
|
-
- **Focus-watch owner map**: `_focusWatches` moved to
|
|
219
|
-
`Map<key, Map<owner, entry>>` so a stale owner from a crashed
|
|
220
|
-
tab does not hold a watch alive.
|
|
221
|
-
|
|
222
|
-
**Fixed**
|
|
223
|
-
|
|
224
|
-
- **Phantom writes on offline socket**: `client.set()` no longer
|
|
225
|
-
returns a silent success when the socket has no live pong. Every
|
|
226
|
-
API-level writer either resolves after the retry succeeds or
|
|
227
|
-
throws with `"pypilot offline: <path>"`. Fixes a class of "the
|
|
228
|
-
UI says engaged but the boat is going straight" reports.
|
|
229
|
-
- **Slow reconnect after power-cycling pypilot**: watchdog interval
|
|
230
|
-
reduced to 15 s with a 20 s liveness threshold, and the ap
|
|
231
|
-
provider now reconciles state on the reconnect delta so the
|
|
232
|
-
visor picks up the fresh mode / target immediately.
|
|
233
|
-
- **`refreshPypilotValues` merge bug**: pilot / profile switch was
|
|
234
|
-
masked by the "don't overwrite existing keys" heuristic. Delta
|
|
235
|
-
handlers for `ap.pilot` and `profile` now pass `{replace: true}`.
|
|
236
|
-
- **`gainReady` exit too early**: the readiness gate was leaving
|
|
237
|
-
as soon as any gain from any pilot arrived. Now scoped to
|
|
238
|
-
`state.pilot` so a stale pilot's gains cannot short-circuit the
|
|
239
|
-
boot pull for the active one.
|
|
240
|
-
- **Tack pill "executing" missing target**: the pill fell back to
|
|
241
|
-
`null` after the arming phase closed. Now falls back through
|
|
242
|
-
`_tackPendingFinalTargetRad ?? _countdownPlannedTargetRad ??
|
|
243
|
-
state.target`.
|
|
244
|
-
- **TGT stays visible with AP engaged + connection lost**: no
|
|
245
|
-
disengage delta arrives when the pypilot vanishes, so the
|
|
246
|
-
target was staying pinned. Now the formatter and
|
|
247
|
-
`renderTargetArrow` bail on `state.pypilotHealthy === false`;
|
|
248
|
-
`scheduleRenderControl()` and `renderTargetArrow()` are also
|
|
249
|
-
kicked on every healthy transition.
|
|
250
|
-
- **Voice not heard on reconnect** (Rev264): added
|
|
251
|
-
`_alSpeak("Pypilot operativo")` to
|
|
252
|
-
`_pypilotShowReconnectedToast` so the sailor gets the audible
|
|
253
|
-
confirmation and does not have to look at the screen.
|
|
254
|
-
|
|
255
|
-
**Architecture**
|
|
256
|
-
|
|
257
|
-
- Rejected an active-ping-before-write pattern proposed mid-sprint:
|
|
258
|
-
it is a TOCTOU (time-of-check-to-time-of-use) anti-pattern that
|
|
259
|
-
adds latency to every write without giving a real safety
|
|
260
|
-
guarantee. Kept the passive-reflection approach instead. Design
|
|
261
|
-
discussion preserved in the commit log.
|
|
262
|
-
|
|
263
|
-
### Español
|
|
264
|
-
|
|
265
|
-
**Añadido**
|
|
266
|
-
|
|
267
|
-
- **Ciclo UX completo "Pypilot caído"**: la UI refleja el
|
|
268
|
-
estado real de la conexión de forma pasiva a partir de un
|
|
269
|
-
heartbeat pong. Cuando el socket lleva > 8 s en silencio, el
|
|
270
|
-
diamante del target y el chip TGT desaparecen inmediatamente,
|
|
271
|
-
los controles que afectan al AP se atenúan con la clase
|
|
272
|
-
`.pypilot-offline`, y la regla `pypilot-disconnected` dispara
|
|
273
|
-
con voz en palabras completas ("Pypilot desconectado desde hace
|
|
274
|
-
N segundos") en lugar de abreviaturas. Al reconectar: toast
|
|
275
|
-
verde "Pypilot operativo" + voz + controles activos otra vez.
|
|
276
|
-
- **Gestor de outage en 3 tramos**: al reconectar el visor compara
|
|
277
|
-
la duración de la caída contra el último
|
|
278
|
-
target conocido. < 20 s: no hace nada (probable microcorte).
|
|
279
|
-
20 s – 5 min: banner con Sí / No para restaurar el
|
|
280
|
-
target anterior. > 5 min: nada (demasiado tiempo, el
|
|
281
|
-
navegante querrá enganchar de cero).
|
|
282
|
-
- **Patrón optimistic write-then-throw** con `client.set()`
|
|
283
|
-
devolviendo `boolean`. `apEngage / apDisengage / apSetMode /
|
|
284
|
-
apSetTargetRad / apTack` rechazan ANTES de tocar el estado
|
|
285
|
-
optimista, para que un comando fantasma contra una TinyPilot
|
|
286
|
-
caída no deje la UI "enganchada" esperando un delta que
|
|
287
|
-
no va a llegar.
|
|
288
|
-
- **`_setWithRetry`** (250 ms + 750 ms backoff) alrededor del
|
|
289
|
-
autopilot-provider adapter para blips transitorios del socket.
|
|
290
|
-
- **Watchdog + heartbeat pong** en `pypilot-client.ts`: el getter
|
|
291
|
-
`healthy` combina `socket.connected` con `lastPongMs <= 8 s`.
|
|
292
|
-
El motor de alarmas usa `client.healthy` (no `.connected`) para
|
|
293
|
-
que la red y las alarmas estén de acuerdo sobre la
|
|
294
|
-
vitalidad. El orden de alarmas también se rehizo para
|
|
295
|
-
que `sensor-lost` no salte _antes_ que `pypilot-disconnected`
|
|
296
|
-
cuando cae el socket entero.
|
|
297
|
-
- **Aislamiento multi-pestaña**: las claves de owner van
|
|
298
|
-
ahora en `sessionStorage` (por pestaña) en lugar de
|
|
299
|
-
`localStorage`, para que dos visores abiertos no compitan por
|
|
300
|
-
soltar los focus watches.
|
|
301
|
-
- **Contador con delta con signo** (Rev247) para el HUD del
|
|
302
|
-
countdown de virada: acumula el delta angular CON SIGNO para
|
|
303
|
-
que el jitter del IMU / compass se cancele en torno a cero y el
|
|
304
|
-
contador no acabe en "0° restantes" con el barco todavía
|
|
305
|
-
a 100° del rumbo final. El threshold de 0.5° que
|
|
306
|
-
producía el falso reporte se eliminó por completo.
|
|
307
|
-
- **Auditoría i18n completa** en EN / ES / DE / FR: se
|
|
308
|
-
purgó el español en modales que se ven en cualquier
|
|
309
|
-
idioma (menú Barco, Historial de bordos, Detalle de viaje,
|
|
310
|
-
Compartir viaje, capa Marca de ráfagas, selector barra
|
|
311
|
-
inferior, aria del nav-toggle), se añadieron variantes
|
|
312
|
-
`data-lang`, las strings de la barra inferior pasaron a claves
|
|
313
|
-
i18n y se añadió `data-i18n-title` en los botones
|
|
314
|
-
de virada. Se renombró "Gota Chain" (que "no lo entiende
|
|
315
|
-
ni Claude", palabras de Carlos) a **"Flechas Target y Viento"**
|
|
316
|
-
/ "Target & Wind arrows" en todo lo que se ve fuera del
|
|
317
|
-
código (README, modal Info, título de screenshot
|
|
318
|
-
NPM).
|
|
319
|
-
- **Pase de ortografía española**: `"COMPAS"` →
|
|
320
|
-
`"COMPÁS"` en el label de modo ES, y el bloque
|
|
321
|
-
`<code>compas / gps / viento / real</code>` pasó a la
|
|
322
|
-
string literal `<code>compass / gps / wind / true</code>`
|
|
323
|
-
(son valores del enum de pypilot, no palabras traducibles).
|
|
324
|
-
- **Sección de Instrucciones completas** en el modal Info
|
|
325
|
-
(EN + ES) cubriendo todas las pestañas ahora que Chart /
|
|
326
|
-
Race / Doctor / Piloto Inteligente / Alarmas / Calidad de
|
|
327
|
-
sensores / Grabador de sesiones / Captura de logs / Consola de
|
|
328
|
-
debug / Consola de control remoto / Watchdog están todas
|
|
329
|
-
en su sitio.
|
|
330
|
-
- **Endpoint `/status`** ahora devuelve `healthy: boolean` junto
|
|
331
|
-
con `connected`.
|
|
332
|
-
- **Focus-watch owner map**: `_focusWatches` pasó a ser
|
|
333
|
-
`Map<key, Map<owner, entry>>` para que un owner colgado de una
|
|
334
|
-
pestaña muerta no mantenga vivo un watch.
|
|
335
|
-
|
|
336
|
-
**Corregido**
|
|
337
|
-
|
|
338
|
-
- **Escrituras fantasma con el socket caído**: `client.set()`
|
|
339
|
-
ya no devuelve un éxito silencioso cuando el socket no
|
|
340
|
-
tiene pong vivo. Cada writer de nivel API o bien resuelve tras
|
|
341
|
-
el retry o bien lanza `"pypilot offline: <path>"`. Cierra la
|
|
342
|
-
clase de reportes "la UI dice enganchado pero el barco va recto".
|
|
343
|
-
- **Reconexión lenta tras cortar y encender pypilot**: el
|
|
344
|
-
watchdog baja a 15 s de intervalo con umbral de vivacidad de
|
|
345
|
-
20 s, y el provider reconcilia estado en el delta de reconexión
|
|
346
|
-
para que el visor recoja el modo / target frescos al instante.
|
|
347
|
-
- **Bug de merge en `refreshPypilotValues`**: el cambio de piloto /
|
|
348
|
-
perfil quedaba enmascarado por la heurística de "no
|
|
349
|
-
sobreescribir claves existentes". Los delta handlers de
|
|
350
|
-
`ap.pilot` y `profile` ahora pasan `{replace: true}`.
|
|
351
|
-
- **`gainReady` salía antes de tiempo**: la puerta de
|
|
352
|
-
readiness se abría al llegar cualquier gain de cualquier
|
|
353
|
-
piloto. Ahora está limitada al `state.pilot` activo,
|
|
354
|
-
para que los gains de un piloto stale no cortocircuiten el
|
|
355
|
-
pull de boot del activo.
|
|
356
|
-
- **Pill de virada "ejecutando" sin target**: la pill acababa en
|
|
357
|
-
`null` al cerrar la fase de arming. Ahora hace fallback por
|
|
358
|
-
`_tackPendingFinalTargetRad ?? _countdownPlannedTargetRad ??
|
|
359
|
-
state.target`.
|
|
360
|
-
- **TGT visible con AP enganchado + conexión caída**:
|
|
361
|
-
no llega delta de desenganche cuando pypilot se va, así
|
|
362
|
-
que el target se quedaba clavado. El formateador y
|
|
363
|
-
`renderTargetArrow` ahora respetan `state.pypilotHealthy ===
|
|
364
|
-
false`; además se disparan `scheduleRenderControl()` y
|
|
365
|
-
`renderTargetArrow()` en cada cambio de healthy.
|
|
366
|
-
- **Voz muda al reconectar** (Rev264): se añadió
|
|
367
|
-
`_alSpeak("Pypilot operativo")` en
|
|
368
|
-
`_pypilotShowReconnectedToast` para que el navegante tenga
|
|
369
|
-
confirmación audible sin mirar la pantalla.
|
|
370
|
-
|
|
371
|
-
**Arquitectura**
|
|
372
|
-
|
|
373
|
-
- Se rechazó un patrón de ping-antes-de-escribir
|
|
374
|
-
propuesto a mitad de sprint: es un anti-patrón TOCTOU
|
|
375
|
-
(time-of-check-to-time-of-use) que añade latencia a cada
|
|
376
|
-
escritura sin dar una garantía real de seguridad. Se
|
|
377
|
-
mantuvo la reflexión pasiva. La discusión queda en
|
|
378
|
-
el log de commits para futura referencia.
|
|
379
|
-
|
|
380
|
-
## 2.6.0 — 2026-09-10 — Rev178..Rev180: Trip Report sprint (still experimental)
|
|
381
|
-
|
|
382
|
-
Big feature bundle. Every trip you take (from the moment
|
|
383
|
-
`navigation.state` leaves "moored" until you're moored again) is
|
|
384
|
-
recorded in the background and turned into a shareable report card.
|
|
385
|
-
|
|
386
|
-
### English
|
|
387
|
-
|
|
388
|
-
**Added**
|
|
389
|
-
|
|
390
|
-
- **Trip recorder** (new module `trip-recorder.ts`): auto-starts when
|
|
391
|
-
`signalk-autostate` (or any plugin publishing `navigation.state`)
|
|
392
|
-
moves the vessel off "moored". Closes and computes a summary when
|
|
393
|
-
the vessel is back to "moored". Trips < 60 s or with < 60 samples
|
|
394
|
-
are discarded automatically.
|
|
395
|
-
- **Live-accumulated KPIs** so summary computation is O(1) even on
|
|
396
|
-
Pi 4: distance (haversine), TWS/AWS avg + max, SOG avg + max, heel
|
|
397
|
-
avg + max, tack count, points-of-sail split (upwind / reach /
|
|
398
|
-
downwind), battery voltage min + sag count, mode share, engaged
|
|
399
|
-
percentage. Highlights (peak wind, peak SOG, min voltage) carry
|
|
400
|
-
their timestamps so the map can pin them.
|
|
401
|
-
- **"Viajes" card in Setup** (order 27) with live trip status + list
|
|
402
|
-
of past trips. Each row: date, distance, duration, avg SOG, avg
|
|
403
|
-
TWS, tack count.
|
|
404
|
-
- **Trip detail modal** with a 17-KPI grid + emoji-tagged highlight
|
|
405
|
-
strip (⛵ ráfaga, 🌀 vel max, 🔋 volt bajo).
|
|
406
|
-
- **OpenSeaMap trace on the map**: Leaflet lazy-loaded from CDN on
|
|
407
|
-
first modal open, OSM base + OpenSeaMap seamark overlay, polyline
|
|
408
|
-
coloured by SOG bucket (< 2 / 2-4 / 4-6 / > 6 kn), markers at
|
|
409
|
-
start (green), end (red), peak wind, peak SOG, min voltage, and
|
|
410
|
-
each detected tack. Auto-fit to the trace bounding box.
|
|
411
|
-
- **"Compartir por WhatsApp" button**: renders a portrait 900×1400
|
|
412
|
-
PNG report card (title, 10 KPI cards, mini trace with the same
|
|
413
|
-
colour buckets, endpoints and highlight emojis, footer). Uses the
|
|
414
|
-
Web Share API when available so the sailor picks any target app;
|
|
415
|
-
falls back to a download + prefilled `wa.me?text=` link on
|
|
416
|
-
platforms without file share.
|
|
417
|
-
- **HTTP endpoints**: `/trip-recorder/status`, `/list`,
|
|
418
|
-
`/summary/:id`, `/download/:id`, `DELETE /trip/:id`.
|
|
419
|
-
|
|
420
|
-
**Fixed (Rev177 carry-over)**
|
|
421
|
-
|
|
422
|
-
- Tack countdown never closes: added AWA-sign / heading-rotation
|
|
423
|
-
detection so the maneuver auto-completes in visor even when
|
|
424
|
-
pypilot never publishes `ap.tack.state="none"`.
|
|
425
|
-
- Gust ghost: fade 15 s (was 10), cooldown 15 s (was 20), thresholds
|
|
426
|
-
lowered (jump ≥ 3 kn, ratio ≥ 1.25, shift ≥ 18°). In true-wind
|
|
427
|
-
mode the ghost now keys off TWS/TWA and is drawn in the teal T
|
|
428
|
-
palette instead of the amber A. Fixes the "aparece poco / no
|
|
429
|
-
atiende a rafagas / en modo real deberia mirar real" feedback.
|
|
430
|
-
- `gustStrategy` default flipped from "warn" to "off" so the
|
|
431
|
-
supervisor cannot freeze the target / boost D / temp-heavy the
|
|
432
|
-
pilot without the sailor explicitly opting in. On the last sea
|
|
433
|
-
trial one of these strategies latched and the AP "se quedo
|
|
434
|
-
pillado, yendose orzada sin buscar rumbo".
|
|
435
|
-
- Reload race: after the plugin catalog lands we re-run
|
|
436
|
-
`refreshPypilotValues()` so gain / calibration sliders that
|
|
437
|
-
rendered before the catalog was known reposition themselves at
|
|
438
|
-
the real pypilot values. Fixes "al recargar la pagina muchas
|
|
439
|
-
veces no carga los valores de sliders o de modo".
|
|
440
|
-
|
|
441
|
-
**Known limits (still experimental)**
|
|
442
|
-
|
|
443
|
-
- Trasluchar (jibe): pypilot's tack primitive only crosses the wind
|
|
444
|
-
by proa. A jibe needs a different primitive (aproado-style). Not
|
|
445
|
-
implemented yet.
|
|
446
|
-
- Trip report card renders as a static PNG. The interactive map is
|
|
447
|
-
only visible inside the visor.
|
|
448
|
-
- CDN load of Leaflet needs internet. On a boat with no data link
|
|
449
|
-
the trace panel just says "sin conexion a los tiles del mapa" and
|
|
450
|
-
the modal still shows all the KPIs.
|
|
451
|
-
|
|
452
|
-
## 2.5.2 — 2026-09-10 — Rev176: session-recorder containment
|
|
453
|
-
|
|
454
|
-
Follow-up patch on 2.5.0. After analysing the on-water sessions
|
|
455
|
-
Carlos captured with Rev175 we found a pile of 1-sample JSONL
|
|
456
|
-
files caused by an external HTTP client (likely a KIP dashboard
|
|
457
|
-
tab, an idle visor tab, or a competing pypilot_web instance)
|
|
458
|
-
cycling `POST /engage` -> `POST /disengage` every 5-6 s. Every
|
|
459
|
-
flicker opened and closed a session file. This tranche contains
|
|
460
|
-
the damage and fixes several analysis blind spots.
|
|
461
|
-
|
|
462
|
-
### English
|
|
463
|
-
|
|
464
|
-
**Fixed**
|
|
465
|
-
|
|
466
|
-
- **Engaged debounce (8 s)** in the historian tick. A new
|
|
467
|
-
engage/disengage transition is only propagated to the session
|
|
468
|
-
recorder after the raw value has held for 8 s. This filters
|
|
469
|
-
the rebounds that were opening one JSONL every ~5 s during the
|
|
470
|
-
test window on 2026-09-08.
|
|
471
|
-
- **Bounce diagnostics**: filtered flips are counted and exposed
|
|
472
|
-
through `/session-recorder/status` (`bouncesFiltered`,
|
|
473
|
-
`lastBounceMs`, `lastBounceDetails`), plus a `[bounce]` line
|
|
474
|
-
in `app.debug` so the next culprit can be traced without
|
|
475
|
-
waiting for a repeat.
|
|
476
|
-
- **Discard short sessions on close**: if a session has less
|
|
477
|
-
than 30 samples OR less than 30 s of duration when the AP
|
|
478
|
-
disengages, the JSONL is unlinked instead of being flushed
|
|
479
|
-
and kept. Belt-and-suspenders on top of the debounce.
|
|
480
|
-
- **Retroactive purge**: on plugin start the recorder sweeps
|
|
481
|
-
`nav-sessions/` and deletes every closed file that meets the
|
|
482
|
-
same criterion. The tester's 54-file directory came down to 7
|
|
483
|
-
useful sessions after Rev176 booted.
|
|
484
|
-
- **Manual purge endpoint**: `POST /plugins/signalk-pypilot-newui/session-recorder/purge-short`
|
|
485
|
-
triggers the sweep on demand.
|
|
486
|
-
- **hdgErr per AP mode**: the recorder stored
|
|
487
|
-
`headingCmd - headingActual` regardless of mode, which was
|
|
488
|
-
garbage in `wind` / `true wind` where `headingCmd` is a wind
|
|
489
|
-
angle, not a heading. Now compass-family modes still store the
|
|
490
|
-
heading delta, `wind` mode stores `headingCmd - AWA`, and
|
|
491
|
-
`true wind` mode stores `headingCmd - TWA`. Offline analysers
|
|
492
|
-
finally get a real number for wind modes.
|
|
493
|
-
- **Pi Zero log-capture no longer re-injects the tail on
|
|
494
|
-
restart**: the per-source `lastLineHash` map is now persisted
|
|
495
|
-
to `pizero-log-state.json` and reloaded on plugin start. The
|
|
496
|
-
file used to grow 32x on the tester's setup because every
|
|
497
|
-
`-Restart` deploy reset the in-memory cursor and re-appended
|
|
498
|
-
the entire tail.
|
|
499
|
-
|
|
500
|
-
**Changed**
|
|
501
|
-
|
|
502
|
-
- **Gust ghost arrow recoloured to orange** so it stands out
|
|
503
|
-
from the live amber A arrow when the two land near the same
|
|
504
|
-
angle. The overlay-card preview matches.
|
|
505
|
-
- **Gust ghost detection thresholds lowered** (Rev175 carry-
|
|
506
|
-
over): AWS jump 4 kn / ratio 1.35, AWA shift 20 deg, baseline
|
|
507
|
-
min 2 kn, cooldown 20 s. Tuned against 2 h of real navigation
|
|
508
|
-
data (~18 potential fires for a 14 kn-avg sail).
|
|
509
|
-
|
|
510
|
-
**Investigation notes (for the curious)**
|
|
511
|
-
|
|
512
|
-
The 71-second racimo on 2026-09-08 19:01-02 (Rev166 that day)
|
|
513
|
-
shows the pattern:
|
|
514
|
-
|
|
515
|
-
engage -> PUT target -> PUT mode -> disengage -> engage -> ...
|
|
516
|
-
|
|
517
|
-
repeating every 5-6 s at the SK Autopilot API v2 endpoint. Not
|
|
518
|
-
manual: too regular. Culprit unidentified with the logs at
|
|
519
|
-
hand - the SK journal does not record client IP/UA. Suspects
|
|
520
|
-
still alive:
|
|
521
|
-
|
|
522
|
-
- A custom KIP dashboard widget that toggles engage on a tick.
|
|
523
|
-
- Two open visor tabs where one has a stale state machine and
|
|
524
|
-
re-issues engage on each SSE reconnect.
|
|
525
|
-
- A feedback loop through `signalk-pypilot` mirroring an incoming
|
|
526
|
-
bus delta as an outgoing SK write.
|
|
527
|
-
|
|
528
|
-
pypilot_web on the KIP tablet was cleared as a suspect - the
|
|
529
|
-
captured pypilot log shows its socket.io connections spaced
|
|
530
|
-
minutes apart, not seconds.
|
|
3
|
+
## 2.7.2 — 2026-09-14 — Registry score bump
|
|
4
|
+
|
|
5
|
+
No code change vs 2.7.1. Adds a smoke test suite (Node built-in test
|
|
6
|
+
runner, no extra devDependencies) so `npm test` passes for the Signal K
|
|
7
|
+
Plugin Registry, and clears a `high` `npm audit` finding in a
|
|
8
|
+
transitive dependency. Together these lift the plugin's registry
|
|
9
|
+
score by ~45 points.
|
|
10
|
+
|
|
11
|
+
## 2.7.1 — 2026-09-14
|
|
12
|
+
|
|
13
|
+
Sea-trial release. Big reliability upgrade after intensive on-water
|
|
14
|
+
testing on Tunatunes.
|
|
15
|
+
|
|
16
|
+
### New features
|
|
17
|
+
|
|
18
|
+
- **Trip Recorder** — every outing is auto-recorded via
|
|
19
|
+
`navigation.state`. Setup → Trips shows 17 KPIs, an OpenSeaMap
|
|
20
|
+
trace coloured by SOG with markers on peak gust, peak SOG, min
|
|
21
|
+
voltage and every detected tack, and lets you share the outing as
|
|
22
|
+
a portrait PNG report card or as WhatsApp text.
|
|
23
|
+
- **Reconnect Restore banner** — when the link with pypilot dies
|
|
24
|
+
while the AP is engaged, the visor takes a snapshot of your target
|
|
25
|
+
and mode. If the link is back between 20 s and 5 min later, a
|
|
26
|
+
Yes / No banner offers to re-engage the same target. Success is
|
|
27
|
+
announced only after pypilot actually confirms.
|
|
28
|
+
- **Watchdog with core-alive detection** — the visor now
|
|
29
|
+
distinguishes a live `pypilot_web` with a dead pypilot core. AP
|
|
30
|
+
controls grey out, the "pypilot disconnected for N seconds" voice
|
|
31
|
+
alert fires, and the green "pypilot operational" toast greets you
|
|
32
|
+
when the core is really back.
|
|
33
|
+
- **Faster offline / online detection** — dead-pypilot detection
|
|
34
|
+
improved from ~10-14 s to ~5-6 s; reconnect detection improved
|
|
35
|
+
from ~4-8 s to ~1-3 s.
|
|
36
|
+
- **Persistent Tack history** — every tack stored on the device
|
|
37
|
+
with pre / post TWS, AWA, SOG and recovery time to 95% of pre-tack
|
|
38
|
+
speed. Filter by day range with best retention and fastest
|
|
39
|
+
recovery highlighted.
|
|
40
|
+
- **Gust marker overlay** — leaves a ghost `A` arrow at the peak
|
|
41
|
+
wind speed for 10 s.
|
|
42
|
+
- **Bottom bar rudder-or-heel switch** — the big-number bar on the
|
|
43
|
+
Control tab can show rudder angle or boat heel.
|
|
44
|
+
- **Concentric Target + Wind arrows** — three arrow pieces on the
|
|
45
|
+
rose interlock into a droplet when target ≡ AWA ≡ TWA; open into
|
|
46
|
+
V-notches with a colour tick when they drift. (Feature previously
|
|
47
|
+
called "Gota Chain", renamed for clarity.)
|
|
48
|
+
- **Full instructions inside the Info modal** — new section that
|
|
49
|
+
walks through every tab and gesture, in English and Spanish.
|
|
50
|
+
- **Global `allowWrites` gate** — the plugin's HTTP routes, the
|
|
51
|
+
Autopilot API v2 provider and the KIP action / switch handlers
|
|
52
|
+
all honour the same toggle. A read-only install is really
|
|
53
|
+
read-only from every angle.
|
|
54
|
+
|
|
55
|
+
### Critical bug fixes
|
|
56
|
+
|
|
57
|
+
- **Silent success on offline writes** — writes to a dead pypilot
|
|
58
|
+
socket used to silently report success, so the visor could claim
|
|
59
|
+
the AP was engaged while the boat drifted. Writes now confirm
|
|
60
|
+
end-to-end before the UI accepts them.
|
|
61
|
+
- **Phantom AP re-enable after reconnect** — a stale engage retry
|
|
62
|
+
could re-enable the AP after you had explicitly disengaged. Fixed
|
|
63
|
+
with a generation counter that cancels superseded orders.
|
|
64
|
+
- **False "healthy" with a dead pypilot core** — a live
|
|
65
|
+
`pypilot_web` pong used to keep the "healthy" flag on even when
|
|
66
|
+
pypilot itself was dead. A sticky core-offline flag now blocks
|
|
67
|
+
writes and greys the UI until real evidence from the core arrives.
|
|
68
|
+
- **Restore banner announced "restored" before pypilot confirmed**
|
|
69
|
+
— the visor used to speak success on the HTTP 200 alone, seconds
|
|
70
|
+
before spotting that pypilot never actually engaged.
|
|
71
|
+
- **Spanish leaking into English mode** — several dynamic strings
|
|
72
|
+
(Trip card, Tack log, menus, WhatsApp caption) rendered in Spanish
|
|
73
|
+
regardless of the active language.
|
|
74
|
+
|
|
75
|
+
Many small bugs also fixed across the visor, autopilot provider and
|
|
76
|
+
Signal K integration.
|
|
77
|
+
|
|
78
|
+
## 2.7.0 — 2026-09-14 — Superseded by 2.7.1
|
|
79
|
+
|
|
80
|
+
Same feature set and code as 2.7.1. Release notes were rewritten in
|
|
81
|
+
2.7.1 in user-facing language.
|
|
82
|
+
|
|
83
|
+
## 2.6.0 — 2026-09-10 — Trip Report first cut
|
|
84
|
+
|
|
85
|
+
First cut of the Trip Recorder (auto-record via `navigation.state`,
|
|
86
|
+
17-KPI grid, OpenSeaMap trace, PNG report card, WhatsApp share).
|
|
87
|
+
Gust marker and gust strategy tuning. Reload-race fix so gain and
|
|
88
|
+
calibration sliders always reflect real pypilot values.
|
|
89
|
+
|
|
90
|
+
## 2.5.2 — 2026-09-10 — Session-recorder containment
|
|
91
|
+
|
|
92
|
+
Contains a rebound bug that opened one JSONL file per engage
|
|
93
|
+
flicker: 8 s engaged-debounce, short-session discard on close, plus
|
|
94
|
+
bounce diagnostics exposed on `/session-recorder/status`.
|
|
531
95
|
|
|
532
96
|
## 2.5.1 — 2026-09-09 — README bilingual
|
|
533
97
|
|
|
534
|
-
|
|
535
|
-
now appears in English *and* Spanish so the SignalK App Store
|
|
536
|
-
description communicates the sea-trial-pending status to English
|
|
537
|
-
speakers too. No code changes.
|
|
538
|
-
|
|
539
|
-
## 2.5.0 — 2026-09-09 — Rev154..Rev174
|
|
540
|
-
|
|
541
|
-
> ## ⚠️ Ships with features that have not been tested at sea yet
|
|
542
|
-
>
|
|
543
|
-
> This release brings NEW features that we **could not validate under
|
|
544
|
-
> sail** yet (there was not enough wind the day we cut it). Install
|
|
545
|
-
> it if you fancy helping us test them — and if anything looks off,
|
|
546
|
-
> **tell us**: https://github.com/Aitonos/signalk-pypilot-newui/issues
|
|
547
|
-
>
|
|
548
|
-
> Your feedback is GOLD for tuning the thresholds before we sign
|
|
549
|
-
> these features off as stable for everyone.
|
|
550
|
-
>
|
|
551
|
-
> ## ⚠️ Version con funciones aun sin probar en el mar
|
|
552
|
-
>
|
|
553
|
-
> Esta version trae funciones NUEVAS que **no hemos podido validar
|
|
554
|
-
> navegando** todavia (el dia de sacarla no habia viento).
|
|
555
|
-
> Instalala si te apetece ayudarnos a probarlas — y si algo va raro,
|
|
556
|
-
> **avisa**: https://github.com/Aitonos/signalk-pypilot-newui/issues
|
|
557
|
-
>
|
|
558
|
-
> Tu feedback nos vale ORO para tunear los limites antes de dejar
|
|
559
|
-
> estas funciones a punto para todos.
|
|
560
|
-
>
|
|
561
|
-
> ### ⛵ Que tenemos que probar en el mar (checklist rapida)
|
|
562
|
-
>
|
|
563
|
-
> 1. **Contador de virada** (grande sobre el barco): al pulsar TACK
|
|
564
|
-
> con el AP enganchado, cuenta atras rojo (5-4-3-2-1) y luego pasa
|
|
565
|
-
> a naranja "VIRANDO" mientras el pypilot vira. Tocar el circulo
|
|
566
|
-
> cancela.
|
|
567
|
-
> 2. **Resumen despues de virar** (panel que sale 2 min): compara la
|
|
568
|
-
> velocidad y el angulo antes y despues del bordo. Verde = buena.
|
|
569
|
-
> Amarillo = normal. Rojo = perdida.
|
|
570
|
-
> 3. **Historial de bordos** (deja pulsado el barco -> "Historial"):
|
|
571
|
-
> guarda cada bordo con retencion de velocidad y tiempo de
|
|
572
|
-
> recuperacion. Filtro por dias, resalta el mejor.
|
|
573
|
-
> 4. **Marca de rafagas** (activable en "Cambiar esquinas" ->
|
|
574
|
-
> Overlays): cuando entra una rafaga fuerte, deja una flecha
|
|
575
|
-
> amarilla fantasma con la velocidad del viento durante 10 segundos.
|
|
576
|
-
> 5. **Cerebro auto** (opcional, en la ficha Smart Pilot): si lo
|
|
577
|
-
> activas, cambia el perfil del pypilot segun el viento (suave /
|
|
578
|
-
> normal / duro) y reacciona a rafagas segun la estrategia elegida
|
|
579
|
-
> (avisar / congelar rumbo / subir D / cambiar a perfil duro).
|
|
580
|
-
> 6. **Corta automatica** (opcional): si el timon toca los topes
|
|
581
|
-
> demasiado tiempo, suelta el AP para que retomes tu.
|
|
582
|
-
>
|
|
583
|
-
> **Como nos ayudas**: usalas, y si algo se comporta raro o no te
|
|
584
|
-
> gusta, mandanos: que hiciste, que esperabas, que paso. Con eso
|
|
585
|
-
> tunearemos los limites antes de sacar la 2.5.0 estable.
|
|
586
|
-
|
|
587
|
-
### English (Rev154..Rev174, pending sea-trial confirmation)
|
|
588
|
-
|
|
589
|
-
**Added — supervisor layer ("brain over pypilot")**
|
|
590
|
-
|
|
591
|
-
- **Auto-profile by wind** — the plugin can switch the active pypilot
|
|
592
|
-
profile between light / medium / heavy based on rolling TWS. Bands
|
|
593
|
-
configurable in the visor's Smart Pilot card. Disabled by default.
|
|
594
|
-
Rev164.
|
|
595
|
-
- **Gust strategy** — configurable response when a remarkable AWS jump
|
|
596
|
-
is detected: `off`, `warn`, `freeze-target`, `boost-D`, `temp-heavy`.
|
|
597
|
-
Replaces the Rev165 warn-only detector. Restore-first logic returns
|
|
598
|
-
the pilot to the prior state when the gust window closes. Rev167.
|
|
599
|
-
- **Auto-disengage on lost authority** — if the servo saturates against
|
|
600
|
-
its rudder stops for a sustained window, the AP releases so a manned
|
|
601
|
-
helm regains control. Rev166.
|
|
602
|
-
- **Config surface moved to the visor** — the Smart Pilot card in the
|
|
603
|
-
plugin's own UI now owns every supervisor toggle. Nothing to touch in
|
|
604
|
-
SK Admin. Rev167.
|
|
605
|
-
|
|
606
|
-
**Added — rose UI**
|
|
607
|
-
|
|
608
|
-
- **Tack countdown overlay over the boat sprite** — huge red digit
|
|
609
|
-
during the pre-tack delay, then flips to orange `VIRANDO` + elapsed
|
|
610
|
-
seconds during execution. Click cancels the maneuver. Fresh delay is
|
|
611
|
-
fetched every arm so an edit in Calibration takes effect without a
|
|
612
|
-
page reload. Rev171/172.
|
|
613
|
-
- **Post-tack stats HUD** — for 2 minutes after a completed tack the
|
|
614
|
-
boat sprite glows and a small panel shows TWS / |AWA| / SOG averaged
|
|
615
|
-
30 s before vs. 30 s after (measured t+30..t+60 so the boat has time
|
|
616
|
-
to settle). Verdict is colour-coded by SOG retention. Rev171.
|
|
617
|
-
- **Persistent tack log (long-press on the boat)** — every completed
|
|
618
|
-
tack is stored locally with pre/post averages, SOG retention %, and
|
|
619
|
-
time to recover 95 % of pre-SOG. The action sheet on the boat sprite
|
|
620
|
-
now offers "Cambiar esquinas" (the old corner selector) or
|
|
621
|
-
"Historial de bordos". The log modal filters by day range and
|
|
622
|
-
highlights the best tack by retention and the fastest to recover.
|
|
623
|
-
Rev172.
|
|
624
|
-
- **Gust ghost arrow (opt-in in the corner-selector modal)** — a
|
|
625
|
-
remarkable AWS jump (≥ 6 kn over the 30-s baseline or ≥ 1.55×) or a
|
|
626
|
-
sharp AWA rotation (≥ 30° in 5 s) leaves a translucent A-shaped
|
|
627
|
-
arrow frozen at the gust angle, with the AWS reading printed
|
|
628
|
-
radially outside it, fading to zero over 10 s. Cooldown 30 s and
|
|
629
|
-
single-ghost policy so it never chases the live arrow. Card lives
|
|
630
|
-
alongside the A / T / COG / Current overlay cards. Rev172-174.
|
|
631
|
-
- **Mode selector reads full phrases** — `APARENTE` / `REAL` shown on
|
|
632
|
-
the collapsed button, `VIENTO APARENTE` / `VIENTO REAL` on the open
|
|
633
|
-
dropdown (swapped on pointerdown / blur). Rev172.
|
|
634
|
-
- **T over A on overlap** — when both wind pieces cover the same angle
|
|
635
|
-
the teal T now draws on top of the amber A, so TWA stays readable at
|
|
636
|
-
a glance. Rev172.
|
|
637
|
-
- **Rose corner sub-line resized (Carlos)** — the wind speed under the
|
|
638
|
-
angle in the top corners is now a first-class figure in portrait and
|
|
639
|
-
a compact one in landscape (media-query split). Bottom AWS/TWS chip
|
|
640
|
-
also trimmed so it stops covering half the boat on a portrait phone.
|
|
641
|
-
Rev171-173.
|
|
642
|
-
- **Tack countdown click-to-cancel** — tapping the huge red circle at
|
|
643
|
-
any moment (delay or VIRANDO) sends `ap.tack.state=none`. Guard added
|
|
644
|
-
so TACK does nothing if the AP is not engaged. Rev171.
|
|
645
|
-
|
|
646
|
-
**Changed — internal**
|
|
647
|
-
|
|
648
|
-
- Shared `SERVO_ON_MIN_A` constant across doctor / kpis / servo-health.
|
|
649
|
-
Rev154.
|
|
650
|
-
- Alarm rules extended with `servo-motor-temp`, `servo-load-high`
|
|
651
|
-
(deviation-ratio > 1.65), and `cruise-drift`. Rev155.
|
|
652
|
-
- `doctor.applyAll()` applies only the top-priority suggestion and
|
|
653
|
-
returns `mustRunFreshSession` + `remaining` so the caller can drive a
|
|
654
|
-
next-iteration loop. Rev160.
|
|
655
|
-
- Session recorder JSONL now enforces a 200 MB FIFO cap. Rev158.
|
|
656
|
-
- Servo-health snapshot persists to disk between restarts. Rev158.
|
|
657
|
-
- Hardware-ceiling finding in `doctor` (duty>0.75 & rms>5°) short-
|
|
658
|
-
circuits further advice with a "you have out-tuned the actuator"
|
|
659
|
-
message. Rev163.
|
|
660
|
-
|
|
661
|
-
**Removed**
|
|
662
|
-
|
|
663
|
-
- All "helm is manned" confirmation modals on engage / tack / Doctor
|
|
664
|
-
apply. Confirming every action was noise; the physical presence of
|
|
665
|
-
the helm is a given while at sea. Rev170.
|
|
666
|
-
|
|
667
|
-
## 2.4.1 — 2026-09-08 — Rev146..Rev153
|
|
668
|
-
|
|
669
|
-
Patch release. Fixes + UI polish on top of 2.4.0.
|
|
670
|
-
|
|
671
|
-
### English
|
|
672
|
-
|
|
673
|
-
**Fixed**
|
|
674
|
-
|
|
675
|
-
- **TWS row in Sensor Quality no longer stuck as MISSING** on plain SK
|
|
676
|
-
setups. `environment.wind.speedTrue` (canonical) is rarely populated;
|
|
677
|
-
the canonical row now accepts `.speedOverGround` (what
|
|
678
|
-
`signalk-derived-data` emits) or `.speedOverWater` as alternatives.
|
|
679
|
-
Same treatment for TWA (`.angleTrueWater` / `.angleTrueGround` /
|
|
680
|
-
`.angleTrue`). Rev146-148.
|
|
681
|
-
- **Regression: AP mode selector went blank** after the Rev140 watch
|
|
682
|
-
refactor - `RESERVED_PYPILOT_KEYS` was blocking subscribe too, when
|
|
683
|
-
it should only block re-publish. Restored so the visor keeps
|
|
684
|
-
`ap.enabled/mode/heading_command` in sync. Rev142.
|
|
685
|
-
- **Watch focus was pinning 60+ keys** on `pypilot_web` when the Setup
|
|
686
|
-
launcher was open. Rev149-150: the launcher grid takes NO focus;
|
|
687
|
-
only the Calibration card (fullscreen) bumps the 7 documented
|
|
688
|
-
sliders. Empty focus now triggers explicit release, so the count
|
|
689
|
-
drops back to the ~15 core watches immediately instead of waiting
|
|
690
|
-
for the 60 s TTL. Well under Sean D'Epagnier's 40-path ceiling.
|
|
691
|
-
- **`[current]` prefix in Pi Zero log capture** replaced with the
|
|
692
|
-
parent directory (`[pypilot]`, `[pypilot_web]`, `[pypilot_hat]`) so
|
|
693
|
-
the merged file is actually readable. Rev149.
|
|
694
|
-
|
|
695
|
-
**Changed**
|
|
696
|
-
|
|
697
|
-
- **Rose colour palette (Carlos)**: Target/DIA diamond is now red
|
|
698
|
-
(`--target-red`, matches the AP engage button); AWS/TWS chip below
|
|
699
|
-
the rose is fully tinted amber for apparent, teal for true; corner
|
|
700
|
-
tiles tint value + sub in the matching wind colour; SOG back to
|
|
701
|
-
white; Rev151-152.
|
|
702
|
-
- **Configure-corners modal** — h4 + close button now sticky at the
|
|
703
|
-
top, body scrolls independently. X on the LEFT with the solid red
|
|
704
|
-
`--engaged` style used by the Setup fullscreen cards. Rev151-153.
|
|
705
|
-
- **Mode selector labels re-render on language change**: switching
|
|
706
|
-
language now redraws mode / pilot / profile selects immediately
|
|
707
|
-
instead of waiting for the next backend delta. Rev144.
|
|
708
|
-
|
|
709
|
-
## 2.4.0 — 2026-09-07 — Rev138..Rev145
|
|
710
|
-
|
|
711
|
-
Feature release. The plugin has learnt to behave itself around the
|
|
712
|
-
Pi Zero (following direct advice from Sean D'Epagnier, pypilot author)
|
|
713
|
-
and now speaks the sailor's language instead of pilot-programmer
|
|
714
|
-
jargon.
|
|
715
|
-
|
|
716
|
-
### English
|
|
717
|
-
|
|
718
|
-
**Added**
|
|
719
|
-
|
|
720
|
-
- **Dynamic watch focus (Rev140..Rev141)** — the old policy kept ~170
|
|
721
|
-
pypilot subscriptions pinned to `pypilot_web`, which pressured the
|
|
722
|
-
Pi Zero W and eventually locked its socket buffer. The backend now
|
|
723
|
-
keeps a minimal always-on core (~15 paths, 1-2 Hz) and accepts
|
|
724
|
-
short-lived focus requests from the visor: Tune bumps the gain
|
|
725
|
-
paths only while it is on screen, same for the Calibration
|
|
726
|
-
sliders. TTL expires when the tab closes. New endpoints
|
|
727
|
-
`/watch/focus`, `/watch/release`, `/watch/status`, a live inspector
|
|
728
|
-
in Setup → Remote Control Console, and a `Restart pypilot_web`
|
|
729
|
-
button that runs `sv restart pypilot_web` via SSH.
|
|
730
|
-
- **Navigation session recorder + advice loop (Rev143)** — every
|
|
731
|
-
engaged AP session is now saved as JSONL to
|
|
732
|
-
`~/.signalk/plugin-config-data/signalk-pypilot-newui/nav-sessions/`.
|
|
733
|
-
Users label conditions (wind / sea / motor / point of sail / crew)
|
|
734
|
-
from a modal in Setup → Doctor, share the file via WhatsApp or
|
|
735
|
-
email, receive an "advice" JSON back and upload it - the visor
|
|
736
|
-
renders it as a "Consejos recibidos" card. First step of the
|
|
737
|
-
AI-tuned Doctor roadmap: no AI runs at runtime, learning happens
|
|
738
|
-
off-boat and gets injected as plain heuristics in later Revs.
|
|
739
|
-
- **Pi Zero log capture (Rev138)** — piCore keeps `/var/log` in
|
|
740
|
-
tmpfs, so a hard reset wipes the previous session's logs. New
|
|
741
|
-
opt-in poller SSHes into the Pi Zero on a configurable cadence,
|
|
742
|
-
tails `/var/log/pypilot/*` and appends new lines to a persistent
|
|
743
|
-
daily file on the Pi 5. Toggle + downloader live in the Remote
|
|
744
|
-
Control Console.
|
|
745
|
-
- **Plain-language help for every gain (Rev139)** — every P / I / D
|
|
746
|
-
/ DD / PR / FF slider in Tune and every documented RangeSetting in
|
|
747
|
-
Setup → Calibration now carries a short "what it does" line plus a
|
|
748
|
-
`?` button that expands into "when to raise, when to lower". EN /
|
|
749
|
-
ES / DE / FR. Aligned with Sean's own forum suggestion.
|
|
750
|
-
- **Doctor findings and summary translated (Rev136)** — backend now
|
|
751
|
-
emits i18n keys with args so the whole Doctor panel reads in the
|
|
752
|
-
active language instead of half English / half Spanish.
|
|
753
|
-
- **Alarm engine i18n (Rev135..Rev136)** — the seven built-in rules
|
|
754
|
-
(heading-deviation, unable-to-steer, servo-overcurrent,
|
|
755
|
-
servo-temp-high, low-voltage, sensor-lost, pypilot-disconnected)
|
|
756
|
-
render banners and speak in the active language. The backend still
|
|
757
|
-
ships English strings on `notifications.autopilot.*` for
|
|
758
|
-
KIP / WilhelmSK compatibility.
|
|
759
|
-
- **Mode selector proper i18n + uppercase tabs (Rev142, Rev144)** —
|
|
760
|
-
`compass`, `wind`, `true wind`, `nav` and the plugin's own
|
|
761
|
-
`aproado` render as translated UPPERCASE labels ("COMPAS", "VIENTO
|
|
762
|
-
APARENTE", "APROADO"). Tab labels are UPPERCASE too so accents
|
|
763
|
-
become optional (RAE convention). Language switch now refreshes
|
|
764
|
-
the mode selector and gain help lines immediately.
|
|
765
|
-
- **Doctor - persistent Hide button (Rev135..Rev136)** — the discard
|
|
766
|
-
action stays visible even after a suggestion has been applied,
|
|
767
|
-
the tile chip mirrors the count.
|
|
768
|
-
- **Setup launcher - live status chips (Rev130..Rev135)** — pypilot
|
|
769
|
-
host+port, active language, calibration last-adjust timestamp
|
|
770
|
-
(with a Reset button), count of active SK sentences vs the plugin
|
|
771
|
-
catalogue total, and an SSH-configured pill on Remote Control
|
|
772
|
-
Console. Sensor Quality gains a per-row Ignore / Restore button so
|
|
773
|
-
a sensor absent from the boat (rudder feedback missing, ...)
|
|
774
|
-
stops turning the chip red.
|
|
775
|
-
- **Chart hover freeze + per-band Y axis (Rev129)** — touch or hover
|
|
776
|
-
to freeze the auto-refresh and read the exact value at that point
|
|
777
|
-
for every band. Min / mid / max ticks in the right gutter.
|
|
778
|
-
- **Tune - per-slider ↺ restore + profile-fork prompt (Rev129,
|
|
779
|
-
Rev132..Rev134)** — snap back to the frozen "was:" baseline, or
|
|
780
|
-
save the change in a new `tune-YYYYMMDD-HHMM` fork on first
|
|
781
|
-
unlock, or Cancel and revert.
|
|
782
|
-
- **Nav bar slide-down gesture (Rev129)** — swipe from the top to
|
|
783
|
-
bring the tab bar back, counterpart to the existing slide-up hide.
|
|
784
|
-
|
|
785
|
-
**Changed**
|
|
786
|
-
|
|
787
|
-
- The `RESERVED_PYPILOT_KEYS` set now only blocks publish, not
|
|
788
|
-
subscribe. Rev141 regression fix: `ap.mode`, `ap.enabled`,
|
|
789
|
-
`ap.heading_command` are needed internally to sync with the SK
|
|
790
|
-
Autopilot API v2.
|
|
791
|
-
- All six screenshots refreshed to match the current UI.
|
|
792
|
-
|
|
793
|
-
### Español
|
|
794
|
-
|
|
795
|
-
**Añadido**
|
|
796
|
-
|
|
797
|
-
- **Watch focus dinámico** — el plugin mantiene un núcleo mínimo
|
|
798
|
-
suscrito (~15 keys, 1-2 Hz) y sube el rate solo mientras haya una
|
|
799
|
-
pestaña que necesite ver esos valores. Sigue la recomendación de
|
|
800
|
-
Sean D'Epagnier: pypilot_web se satura si le mandas ~170
|
|
801
|
-
suscripciones constantes. Nuevos endpoints, inspector en vivo y
|
|
802
|
-
botón "Reiniciar pypilot_web" en la consola remota.
|
|
803
|
-
- **Grabador de sesiones + loop de consejos** — cada sesión con el
|
|
804
|
-
AP enganchado se guarda como JSONL. Etiquetas por condiciones
|
|
805
|
-
(viento / mar / propulsión / rumbo / tripulación), botón compartir
|
|
806
|
-
por WhatsApp, y subida del JSON de consejos que se recibe de
|
|
807
|
-
vuelta. Primer paso del "Doctor afinado por IA": la IA no corre
|
|
808
|
-
en tiempo real, aprende offline y sus heurísticas se inyectan
|
|
809
|
-
como código en las próximas Revs.
|
|
810
|
-
- **Captura de logs Pi Zero** — piCore guarda `/var/log` solo en
|
|
811
|
-
RAM, un hard reset borra el historial. Toggle en la consola
|
|
812
|
-
remota que hace SSH cada N segundos y guarda los logs en un
|
|
813
|
-
archivo persistente del Pi 5.
|
|
814
|
-
- **Explicaciones "en cristiano" para cada ganancia** — P / I / D /
|
|
815
|
-
DD / PR / FF más los sliders principales de Calibration llevan
|
|
816
|
-
una línea corta con qué hace y un `?` que expande "cuándo subir,
|
|
817
|
-
cuándo bajar". EN / ES / DE / FR.
|
|
818
|
-
- **Doctor + alarmas en tu idioma** — findings, summary y las siete
|
|
819
|
-
reglas de alarma ahora se traducen en el visor. El backend sigue
|
|
820
|
-
enviando inglés al SK para KIP / WilhelmSK.
|
|
821
|
-
- **Selector de modo traducido en MAYÚSCULAS** — "COMPAS", "VIENTO
|
|
822
|
-
APARENTE", "VIENTO REAL", "APROADO", ... con jerga marinera. Las
|
|
823
|
-
pestañas también en MAYÚSCULAS para que la tilde sea opcional.
|
|
824
|
-
- **Doctor - botón Ocultar siempre visible** — no se atasca la
|
|
825
|
-
lista de sugerencias aunque ya las hayas aplicado.
|
|
826
|
-
- **Setup - chips vivos en cada tile** — host + puerto TinyPilot,
|
|
827
|
-
idioma activo, fecha del último ajuste de calibración, sentencias
|
|
828
|
-
SK activas y SSH configurado.
|
|
829
|
-
- **Sensor Quality con Ignorar / Restaurar por fila** — para
|
|
830
|
-
sensores que no existen en el barco (por ejemplo el timón sin
|
|
831
|
-
feedback).
|
|
832
|
-
- **Chart con freeze al pasar el cursor + escala Y por banda**.
|
|
833
|
-
- **Tune con ↺ por slider + fork de perfil al primer cambio**.
|
|
834
|
-
- **Slide desde arriba para mostrar la barra de pestañas**.
|
|
835
|
-
|
|
836
|
-
**Cambiado**
|
|
837
|
-
|
|
838
|
-
- Regresión Rev141 corregida: `RESERVED_PYPILOT_KEYS` bloquea
|
|
839
|
-
solo publish, no subscribe. El selector de modo del AP vuelve
|
|
840
|
-
a poblarse correctamente.
|
|
841
|
-
- 6 screenshots actualizados a la UI actual.
|
|
842
|
-
|
|
843
|
-
### Deutsch
|
|
844
|
-
|
|
845
|
-
**Neu**
|
|
846
|
-
|
|
847
|
-
- Dynamischer Watch-Fokus, entlastet pypilot_web auf dem Pi Zero.
|
|
848
|
-
- Sitzungs-Rekorder + Ratschlag-Loop (JSONL pro Engage).
|
|
849
|
-
- Pi Zero Log-Capture (persistiert /var/log auf dem Pi 5).
|
|
850
|
-
- Klartext-Hilfe pro Gain-Slider.
|
|
851
|
-
- Doctor + Alarme in aktiver Sprache.
|
|
852
|
-
- Modus-Auswahl uebersetzt in GROSSBUCHSTABEN.
|
|
853
|
-
- Doctor: Verwerfen bleibt sichtbar.
|
|
854
|
-
- Setup-Kacheln zeigen Live-Status.
|
|
855
|
-
- Sensor Quality: Ignorieren pro Zeile.
|
|
856
|
-
- Chart: Hover-Freeze + Y-Achse pro Band.
|
|
857
|
-
- Tune: ↺ pro Slider + Fork-Dialog.
|
|
858
|
-
- Wisch-von-oben blendet Tab-Leiste ein.
|
|
859
|
-
|
|
860
|
-
### Français
|
|
861
|
-
|
|
862
|
-
**Nouveautés**
|
|
863
|
-
|
|
864
|
-
- Focus d'abonnements dynamique, allege pypilot_web sur le Pi Zero.
|
|
865
|
-
- Enregistreur de sessions + boucle de conseils (JSONL par engage).
|
|
866
|
-
- Capture des logs Pi Zero sur le Pi 5.
|
|
867
|
-
- Aide en clair par slider de gain.
|
|
868
|
-
- Doctor et alarmes dans la langue active.
|
|
869
|
-
- Selecteur de mode traduit en MAJUSCULES.
|
|
870
|
-
- Doctor: bouton Masquer toujours visible.
|
|
871
|
-
- Puces de statut vivantes sur chaque tuile Setup.
|
|
872
|
-
- Sensor Quality avec Ignorer / Restaurer par ligne.
|
|
873
|
-
- Chart: figeage au survol + graduation Y par bande.
|
|
874
|
-
- Tune: ↺ par slider + modal de fork de profil.
|
|
875
|
-
- Glissement du haut vers le bas pour reafficher la barre d'onglets.
|
|
876
|
-
|
|
877
|
-
## 2.3.0 — 2026-08-31 — Rev130..Rev137
|
|
878
|
-
|
|
879
|
-
Feature batch on top of 2.2.x. Themes: make the visor speak the user's
|
|
880
|
-
language end-to-end (Doctor findings, alarm banners and TTS voice
|
|
881
|
-
included), turn the Setup launcher into an at-a-glance dashboard,
|
|
882
|
-
give Tune the same profile-fork discipline the Doctor already had,
|
|
883
|
-
and make Sensor Quality something the skipper can silence for
|
|
884
|
-
sensors that aren't on this boat.
|
|
885
|
-
|
|
886
|
-
### English
|
|
887
|
-
|
|
888
|
-
**Added**
|
|
889
|
-
|
|
890
|
-
- **Chart tab — interactive hover** (Rev129) — freeze the auto-refresh
|
|
891
|
-
and read the exact value of every band at any point in the history
|
|
892
|
-
window by hovering the graph. Y-axis ticks (min / mid / max) now
|
|
893
|
-
sit inside the right gutter for each band.
|
|
894
|
-
- **Tune tab — per-slider restore + profile fork prompt** (Rev129,
|
|
895
|
-
Rev132..Rev134) — every gain slider gets a ↺ button that snaps
|
|
896
|
-
back to the frozen baseline captured when you unlocked the panel.
|
|
897
|
-
On the first change of an unlock session a modal asks whether to
|
|
898
|
-
keep the tweaks in the current profile, save them in a new
|
|
899
|
-
`tune-YYYYMMDD-HHMM` fork (mirroring the Doctor pattern), or
|
|
900
|
-
Cancel and revert the change entirely.
|
|
901
|
-
- **Setup launcher — live status chips on every tile** (Rev130..Rev135)
|
|
902
|
-
— Pypilot Connection shows `host:port`, Language shows the active
|
|
903
|
-
locale, Calibration shows the timestamp of the last slider
|
|
904
|
-
adjustment (with a `Reset historial` button on the card), Signal K
|
|
905
|
-
Sentences shows the count of published SK paths out of the plugin
|
|
906
|
-
catalog total, and Remote Control Console reports whether SSH
|
|
907
|
-
creds are stored.
|
|
908
|
-
- **Sensor Quality — per-row Ignore / Restore** (Rev134..Rev135) —
|
|
909
|
-
the chip now also counts "missing" sensors (a watched path that
|
|
910
|
-
has never emitted a delta) into the failure tally, and each row
|
|
911
|
-
gains an Ignore / Restore button so a sensor you don't have on
|
|
912
|
-
this boat (rudder without a rudder feedback, temp probe absent,
|
|
913
|
-
...) stops turning the chip red. Persisted per-browser.
|
|
914
|
-
- **Nav bar slide-down gesture** (Rev129) — the counterpart to the
|
|
915
|
-
existing slide-up hide; drag from the top of the visor to bring
|
|
916
|
-
the tab bar back.
|
|
917
|
-
- **Doctor — Hide button always visible + i18n findings**
|
|
918
|
-
(Rev135..Rev136) — the Descartar / Ocultar button stays visible
|
|
919
|
-
even after a suggestion has been applied so you can clear stale
|
|
920
|
-
advice from the list. Hidden suggestions also drop off the tile
|
|
921
|
-
chip's counter so the card goes back to `sano` once you've cleared
|
|
922
|
-
everything. Backend now emits i18n keys + args for findings and
|
|
923
|
-
summary so the whole Doctor panel reads in the active language.
|
|
924
|
-
- **Alarm engine i18n** (Rev135..Rev136) — the seven built-in alarm
|
|
925
|
-
rules (heading-deviation, unable-to-steer, servo-overcurrent,
|
|
926
|
-
servo-temp-high, low-voltage, sensor-lost, pypilot-disconnected)
|
|
927
|
-
now render banners and speak the message in the active language
|
|
928
|
-
(EN / ES / DE / FR). The backend still publishes the English
|
|
929
|
-
notification message on `notifications.autopilot.*` for
|
|
930
|
-
KIP / WilhelmSK compatibility.
|
|
931
|
-
- **Info tab — English classic-UI link fix** (Rev129) — the
|
|
932
|
-
hardcoded Spanish string "Interfaz clasica pypilot" that leaked
|
|
933
|
-
into every language moved to a proper i18n key with `{host}` /
|
|
934
|
-
`{port}` interpolation.
|
|
935
|
-
- **Remote Control Console — TinyPilot defaults** (Rev136) — the
|
|
936
|
-
tile no longer wears its emergency red frame; the SSH user field
|
|
937
|
-
is pre-filled with the TinyPilot default (`tc`) and a hint spells
|
|
938
|
-
out that the default password is `tc` too, so the setup is a
|
|
939
|
-
two-click job on a stock TinyPilot.
|
|
940
|
-
- **Better DE / FR coverage** (Rev134..Rev136) — Setup tile titles,
|
|
941
|
-
calibration strings, Tune fork modal, chip labels, Doctor summary
|
|
942
|
-
/ findings and alarm messages now translate in Deutsch and
|
|
943
|
-
Français instead of falling back to English.
|
|
944
|
-
|
|
945
|
-
**Changed**
|
|
946
|
-
|
|
947
|
-
- **All six screenshots refreshed** to match the current UI
|
|
948
|
-
(Control rose with the Gota Chain arrow layout, Chart Trip Stats,
|
|
949
|
-
Tune with per-slider reset, Setup launcher chips, Race timer,
|
|
950
|
-
Info panel).
|
|
951
|
-
|
|
952
|
-
### Español
|
|
953
|
-
|
|
954
|
-
**Añadido**
|
|
955
|
-
|
|
956
|
-
- **Chart — cursor sobre gráficas** — al pasar el dedo o el ratón
|
|
957
|
-
sobre una gráfica se congela el refresh y aparece una línea
|
|
958
|
-
vertical + tooltip con `-X.Xs` y el valor de cada banda en ese
|
|
959
|
-
punto. Escala Y (min / mid / max) por banda en el margen derecho.
|
|
960
|
-
- **Tune — botón ↺ por slider + prompt de perfil** — cada gain trae
|
|
961
|
-
un ↺ que vuelve al valor previo (el que había al desbloquear). El
|
|
962
|
-
primer cambio tras unlock lanza un modal preguntando si guardar
|
|
963
|
-
en el perfil actual, crear un nuevo `tune-YYYYMMDD-HHMM` (mismo
|
|
964
|
-
patrón que Doctor) o cancelar y revertir.
|
|
965
|
-
- **Setup — chips vivos en cada tile** — TinyPilot con host:port,
|
|
966
|
-
idioma actual, fecha del último ajuste de calibración (con botón
|
|
967
|
-
Reset historial), contador de sentencias SK publicadas frente al
|
|
968
|
-
total del catálogo del plugin, y aviso de SSH configurado en
|
|
969
|
-
Remote Control Console.
|
|
970
|
-
- **Sensor Quality — Ignorar / Restaurar por fila** — los sensores
|
|
971
|
-
que nunca han reportado también cuentan en el ✕, y cada fila con
|
|
972
|
-
problema tiene ahora un botón Ignorar (persistente en el
|
|
973
|
-
navegador) para no volver a teñir el chip por un sensor que no
|
|
974
|
-
hay en el barco.
|
|
975
|
-
- **Slide desde arriba para mostrar la barra de pestañas** — vuelta
|
|
976
|
-
atrás del slide hacia arriba que ya escondía la nav.
|
|
977
|
-
- **Doctor — botón Ocultar siempre + findings traducidos** — se
|
|
978
|
-
puede vaciar la lista de sugerencias aunque ya las hubieras
|
|
979
|
-
aplicado, y el chip del tile vuelve a "sano" cuando no queda
|
|
980
|
-
ninguna. Backend emite ahora claves i18n para findings y summary.
|
|
981
|
-
- **Alarmas en tu idioma** — las siete reglas (desvío de rumbo,
|
|
982
|
-
autoridad, servo, temperatura, tensión, sensor perdido,
|
|
983
|
-
desconexión pypilot) se muestran y se hablan en el idioma activo.
|
|
984
|
-
Al SK sigue viajando el mensaje en inglés para compatibilidad con
|
|
985
|
-
KIP / WilhelmSK.
|
|
986
|
-
- **Info EN sin fugas al ES** — el "Interfaz clásica pypilot" que
|
|
987
|
-
se colaba en cualquier idioma pasó a clave i18n.
|
|
988
|
-
- **Remote Console con defaults TinyPilot** — sin borde rojo,
|
|
989
|
-
usuario `tc` pre-cargado y aviso de que la contraseña por defecto
|
|
990
|
-
también es `tc`.
|
|
991
|
-
- **Mejor cobertura DE / FR** en todos los strings visibles del
|
|
992
|
-
Setup, Tune, Doctor y alarmas.
|
|
993
|
-
|
|
994
|
-
**Cambiado**
|
|
995
|
-
|
|
996
|
-
- **6 screenshots** actualizados a la UI actual.
|
|
997
|
-
|
|
998
|
-
### Deutsch
|
|
999
|
-
|
|
1000
|
-
**Neu**
|
|
1001
|
-
|
|
1002
|
-
- Chart mit Hover-Freeze und Y-Achse pro Band.
|
|
1003
|
-
- Tune-Slider mit ↺ und Profil-Fork-Dialog (Cancel setzt zurueck).
|
|
1004
|
-
- Setup-Kacheln zeigen Live-Status (Host, Sprache,
|
|
1005
|
-
Kalibrierdatum, aktive SK-Saetze, SSH konfiguriert).
|
|
1006
|
-
- Sensor Quality mit "missing" im Chip-Zaehler und einer
|
|
1007
|
-
Ignore / Restore-Taste pro Zeile.
|
|
1008
|
-
- Slide von oben zeigt die Tab-Leiste wieder.
|
|
1009
|
-
- Doctor: Ausblenden-Taste bleibt sichtbar, Findings und Summary
|
|
1010
|
-
jetzt uebersetzt.
|
|
1011
|
-
- Alarm-Meldungen und Sprachausgabe in der aktiven Sprache.
|
|
1012
|
-
- Remote-Konsole ohne roten Rahmen; `tc` als Standard-Login.
|
|
1013
|
-
- Erweiterte DE-Uebersetzungen.
|
|
1014
|
-
|
|
1015
|
-
### Français
|
|
1016
|
-
|
|
1017
|
-
**Nouveautés**
|
|
1018
|
-
|
|
1019
|
-
- Onglet Chart avec figeage au survol et graduation Y par bande.
|
|
1020
|
-
- Onglet Tune avec bouton ↺ par slider et modal de fork de profil
|
|
1021
|
-
(Annuler revient a la valeur d'origine).
|
|
1022
|
-
- Grille Setup avec puces d'etat vivantes (hote, langue, dernier
|
|
1023
|
-
ajustement de calibration, phrases SK actives, SSH configure).
|
|
1024
|
-
- Sensor Quality avec "missing" dans le compteur et un bouton
|
|
1025
|
-
Ignorer / Restaurer par ligne.
|
|
1026
|
-
- Glissement du haut vers le bas pour reafficher la barre
|
|
1027
|
-
d'onglets.
|
|
1028
|
-
- Doctor: bouton Masquer toujours visible, findings et resume
|
|
1029
|
-
traduits.
|
|
1030
|
-
- Alarmes et voix TTS dans la langue active.
|
|
1031
|
-
- Console distante sans cadre rouge; `tc` par defaut.
|
|
1032
|
-
- Traductions FR etendues.
|
|
1033
|
-
|
|
1034
|
-
## 2.2.1 — 2026-08-31 — Rev128
|
|
1035
|
-
|
|
1036
|
-
Docs-only patch release.
|
|
1037
|
-
|
|
1038
|
-
- **README** — embedded the four App Store screenshots as absolute
|
|
1039
|
-
`raw.githubusercontent.com` URLs so they render both on the NPM
|
|
1040
|
-
website (which only surfaces the README, not `signalk.screenshots[]`)
|
|
1041
|
-
and inside any other viewer that follows the README markdown. The
|
|
1042
|
-
registry serves the README frozen at publish time, so this bump is
|
|
1043
|
-
the only way to get the updated README to `npmjs.com/package/signalk-pypilot-newui`.
|
|
1044
|
-
|
|
1045
|
-
## 2.2.0 — 2026-08-31 — Rev88..Rev127
|
|
1046
|
-
|
|
1047
|
-
Forty in-session Revs of navigation-oriented features on top of the
|
|
1048
|
-
2.1.0 visual foundation. Themes: turn the plugin into an intelligence
|
|
1049
|
-
layer over pypilot (historian → KPIs → alarms → Doctor → pre-departure
|
|
1050
|
-
check), give sail-raising its own AP mode ("Aproado"), and rebuild the
|
|
1051
|
-
Setup tab as an app-launcher grid of fullscreen tiles.
|
|
1052
|
-
|
|
1053
|
-
### English
|
|
1054
|
-
|
|
1055
|
-
**Added**
|
|
1056
|
-
|
|
1057
|
-
- **Aproado pseudo-mode** (Rev87-92) — a new "raise the sails"
|
|
1058
|
-
autopilot mode not in pypilot upstream. Pick BY BOW / BY STERN
|
|
1059
|
-
via a 5 s modal, the plugin switches pypilot to wind mode with
|
|
1060
|
-
target 0° (head to wind), and a floating HUD over the boat shows
|
|
1061
|
-
elapsed time, straight-line distance from the start and the
|
|
1062
|
-
compass heading captured at activation. SALIR restores the
|
|
1063
|
-
previous mode + target + engaged state. The BY STERN branch
|
|
1064
|
-
forces a stern-through swing by walking a chain of intermediate
|
|
1065
|
-
targets 60° apart so pypilot cannot shortcut through the bow.
|
|
1066
|
-
- **Telemetry historian + Chart tab** (Rev93-96) — RAM ring buffer
|
|
1067
|
-
at 1 Hz for the last 30 min (backend, Pi 5 friendly). New Chart
|
|
1068
|
-
tab shows nine Trip Stats cards (AP engaged time, distance,
|
|
1069
|
-
energy, mean/RMS/p95 heading error, servo runtime, tacks/gybes,
|
|
1070
|
-
peak servo A) all fed live via SK paths, plus a canvas history
|
|
1071
|
-
with 30 s / 2 min / 10 min windows and per-path chips.
|
|
1072
|
-
- **Sensor Quality panel** (Rev97-98) — age / observed Hz / jitter /
|
|
1073
|
-
source for every critical SK path the AP depends on, with a
|
|
1074
|
-
green / amber / red pill. Endpoint `/quality` and a poll while
|
|
1075
|
-
Setup is visible.
|
|
1076
|
-
- **Servo Health card** (Rev99) — baseline current learned from
|
|
1077
|
-
the first ~10 min of engaged navigation, then a live deviation
|
|
1078
|
-
ratio flags "elevated" (>1.20×) or "high" (>1.65×) — early
|
|
1079
|
-
warning for a hard rudder, fouling, or a stiffened linkage. Six
|
|
1080
|
-
new SK paths under `steering.autopilot.pypilot.servo.health.*`.
|
|
1081
|
-
- **Alarm engine** (Rev100-101) — seven built-in rules (heading
|
|
1082
|
-
deviation, unable to steer, servo overcurrent / temp, low
|
|
1083
|
-
voltage, sensor lost, pypilot disconnected) publishing
|
|
1084
|
-
canonical SK notifications `notifications.autopilot.*`. Sticky
|
|
1085
|
-
banner in the visor with ACK + close, WebAudio beeps +
|
|
1086
|
-
speech-synthesis of the message, and a full config panel in
|
|
1087
|
-
Setup (enable / mute / status per rule).
|
|
1088
|
-
- **Pre-departure check** (Rev102) — a single verdict card
|
|
1089
|
-
(READY / READY-WITH-CAVEATS / DO-NOT-ENGAGE) that aggregates
|
|
1090
|
-
connectivity, sensor quality, servo health and voltage into one
|
|
1091
|
-
answer before you leave the dock.
|
|
1092
|
-
- **Pypilot Doctor** (Rev103-104, Rev120-121) — press DIAGNOSE,
|
|
1093
|
-
the plugin records 2-3 min with the AP engaged, runs heuristic
|
|
1094
|
-
rules on the heading error stream (bias / oscillation / low
|
|
1095
|
-
authority) and proposes P / I / D adjustments with a plain
|
|
1096
|
-
explanation of why and what to expect. Nothing is applied
|
|
1097
|
-
automatically — each suggestion has Apply and Discard buttons.
|
|
1098
|
-
Rev120: the first Apply of a session forks the current pypilot
|
|
1099
|
-
profile into a new `doctor-YYYYMMDD-HHMM` profile so the
|
|
1100
|
-
previous gains stay one profile-select away.
|
|
1101
|
-
- **Setup as a launcher grid** (Rev105-119, 124) — every setup
|
|
1102
|
-
block is now a square tile in a 2 / 3 / 4-column grid. Tap
|
|
1103
|
-
opens fullscreen with a small X to close and ESC support.
|
|
1104
|
-
Body scroll is locked while a tile is fullscreen. Live summary
|
|
1105
|
-
pill on every tile so the state reads at a glance without
|
|
1106
|
-
expanding. Connection consolidated (status + LAN scan + manual
|
|
1107
|
-
host + Autopilot Provider in one card). "Emergency" renamed to
|
|
1108
|
-
"Remote Control Console".
|
|
1109
|
-
- **Interactive SSH console** (Rev113-115) — free-form command
|
|
1110
|
-
input with on-screen arrow buttons for mobile history
|
|
1111
|
-
navigation, accumulative output textarea, clipboard fallback
|
|
1112
|
-
for HTTP LAN, and 14 preset buttons with plain human labels
|
|
1113
|
-
(Memory / IP table / WiFi / Temperature / Who is connected /
|
|
1114
|
-
...). BusyBox / piCore-safe fallbacks for every command.
|
|
1115
|
-
- **Full RangeSetting sliders in Calibration** (Rev116-119) —
|
|
1116
|
-
every pypilot `RangeSetting` grouped by category (rudder /
|
|
1117
|
-
servo / imu / ap / other) with the same look as the Tune tab,
|
|
1118
|
-
a lock checkbox with the padlock emoji, a frozen "before:"
|
|
1119
|
-
baseline that never moves as you drag, and a per-slider ↺
|
|
1120
|
-
restore button that snaps back to the baseline.
|
|
1121
|
-
- **Nudge steps moved inside Calibration** (Rev124) — one card
|
|
1122
|
-
less in the launcher grid; heading trim buttons live where
|
|
1123
|
-
they belong conceptually.
|
|
1124
|
-
|
|
1125
|
-
**Changed**
|
|
1126
|
-
|
|
1127
|
-
- **Gota Chain shapes SWAP** (Rev122-126) — after several iterations
|
|
1128
|
-
with Carlos on Tunatunes: the AMBER "A" arrow (apparent wind) is
|
|
1129
|
-
now the LARGE piece (its tip reaches deep into the rose), and
|
|
1130
|
-
the TEAL "T" arrow (true wind) is the SMALL outer one. Colors
|
|
1131
|
-
and letters kept their canonical meaning; only the SVG paths
|
|
1132
|
-
moved so the amber piece is visually the dominant one.
|
|
1133
|
-
- **Alarm summary semantics** (Rev107-108) — "activa" (fired) was
|
|
1134
|
-
ambiguous with "activada" (enabled). New wording separates
|
|
1135
|
-
`firing / sonando` (fired now) from `watching / vigilando`
|
|
1136
|
-
(enabled and healthy). Summary always shows both counts.
|
|
1137
|
-
- **i18n audit** (Rev105, Rev112, Rev121) — every hard-coded
|
|
1138
|
-
English string in the ES bundle purged ("engagear" → "activar",
|
|
1139
|
-
KIP paths table fully translated, alarm messages), backend
|
|
1140
|
-
suggestion reason / effect exposed as i18n keys + args so the
|
|
1141
|
-
frontend renders in the user's language.
|
|
1142
|
-
- **Sensor Quality thresholds** (Rev98) — dropped `minHz` from the
|
|
1143
|
-
defaults; the 1 Hz sampler capped observed Hz, so the threshold
|
|
1144
|
-
produced spurious "degraded" flags. Freshness (`age`) is now
|
|
1145
|
-
the only signal that penalises status.
|
|
1146
|
-
|
|
1147
|
-
**Fixed**
|
|
1148
|
-
|
|
1149
|
-
- **Fullscreen tile portal** (Rev110-111) — Setup fullscreen tiles
|
|
1150
|
-
are now portaled to `<body>` so the `.tab-panel` transform
|
|
1151
|
-
(used by the tab animation) cannot break `position: fixed`.
|
|
1152
|
-
Fullscreen always covers the viewport now, no matter which
|
|
1153
|
-
card was scrolled into.
|
|
1154
|
-
- **Copy button on HTTP** (Rev114) — `navigator.clipboard` is a
|
|
1155
|
-
secure-context API; on plain http://192.168.x.y it silently
|
|
1156
|
-
no-ops. Compat helper falls back to `document.execCommand("copy")`.
|
|
1157
|
-
- **Doctor `elapsedSec`** (Rev104) — was counting past the target
|
|
1158
|
-
duration once the session completed. Now freezes at the target.
|
|
1159
|
-
- **Sliders baseline eaten by refresh** (Rev117-118) — the
|
|
1160
|
-
Calibration "before:" value used to reset to the just-edited
|
|
1161
|
-
number on every `/values` poll. Now captured once per name and
|
|
1162
|
-
kept frozen across renders.
|
|
1163
|
-
- **Aproado restore** (Rev90) — mode / target / engaged restore on
|
|
1164
|
-
SALIR was skipping steps after one failure. Now each step is
|
|
1165
|
-
guarded independently and logged in the console.
|
|
1166
|
-
- **Sensor Quality parsing** (Rev94) — `navigation.attitude` is a
|
|
1167
|
-
composite `{pitch, roll, yaw}` object, not a scalar path.
|
|
1168
|
-
Custom subfield reader added for heel.
|
|
1169
|
-
- Cosmetic Firefox warnings (`::-moz-focus-inner`, comment-nested
|
|
1170
|
-
`*/`) purged (Rev95-106).
|
|
1171
|
-
|
|
1172
|
-
### Español
|
|
1173
|
-
|
|
1174
|
-
**Nuevo**
|
|
1175
|
-
|
|
1176
|
-
- **Modo Aproado** (Rev87-92): pseudo-modo AP para subir velas.
|
|
1177
|
-
Elige POR PROA / POR POPA en un modal de 5 s, el plugin pasa
|
|
1178
|
-
pypilot a modo viento con objetivo 0° (proa al viento), y un
|
|
1179
|
-
HUD flotante sobre el barco muestra tiempo transcurrido,
|
|
1180
|
-
distancia lineal desde el arranque y el rumbo compás capturado
|
|
1181
|
-
al activar. SALIR restaura modo + objetivo + engaged previos.
|
|
1182
|
-
POR POPA fuerza el swing por popa con una cadena de objetivos
|
|
1183
|
-
intermedios cada 60° para que pypilot no atajaje por proa.
|
|
1184
|
-
- **Historian de telemetría + pestaña Gráfica** (Rev93-96):
|
|
1185
|
-
buffer circular en RAM a 1 Hz durante 30 min (backend, Pi 5).
|
|
1186
|
-
Nueva pestaña Gráfica con 9 tarjetas de estadísticas de sesión
|
|
1187
|
-
(tiempo activo, distancia, energía, error medio / RMS / p95,
|
|
1188
|
-
servo activo, viradas / trasluchadas, pico servo A) y canvas
|
|
1189
|
-
con ventanas 30 s / 2 min / 10 min.
|
|
1190
|
-
- **Panel Calidad de sensores** (Rev97-98): edad / Hz / jitter /
|
|
1191
|
-
fuente por cada ruta SK crítica con semáforo verde / ámbar /
|
|
1192
|
-
rojo.
|
|
1193
|
-
- **Tarjeta Salud del servo** (Rev99): baseline aprendido de los
|
|
1194
|
-
primeros ~10 min de navegación activa, luego ratio de
|
|
1195
|
-
desviación marca "elevated" (>1.20×) o "high" (>1.65×) —
|
|
1196
|
-
alerta temprana de timón duro, incrustaciones o rozamientos.
|
|
1197
|
-
- **Motor de alarmas** (Rev100-101): 7 reglas built-in
|
|
1198
|
-
(desviación de rumbo, incapaz de gobernar, sobrecorriente
|
|
1199
|
-
servo, temperatura servo, batería baja, sensor perdido,
|
|
1200
|
-
pypilot desconectado) publicando notifications SK canónicas.
|
|
1201
|
-
Banner sticky en el visor con ACK y cierre X, beeps WebAudio
|
|
1202
|
-
+ speechSynthesis del mensaje, panel de configuración en
|
|
1203
|
-
Setup (enable / mute / estado por regla).
|
|
1204
|
-
- **Comprobación del piloto** (Rev102): tarjeta única con
|
|
1205
|
-
veredicto (LISTO / LISTO CON RESERVAS / NO ACTIVAR) que
|
|
1206
|
-
agrega conectividad, calidad de sensores, salud del servo y
|
|
1207
|
-
voltaje.
|
|
1208
|
-
- **Asesoramiento y diagnóstico** (Rev103-104, Rev120-121):
|
|
1209
|
-
botón DIAGNOSTICAR, el plugin graba 2-3 min con el AP activo,
|
|
1210
|
-
aplica reglas heurísticas (sesgo / oscilación / autoridad) y
|
|
1211
|
-
propone ajustes P / I / D con explicación clara del porqué y
|
|
1212
|
-
del efecto esperado. Nada se aplica automáticamente — cada
|
|
1213
|
-
sugerencia tiene botones Aplicar y Descartar. Rev120: el
|
|
1214
|
-
primer Aplicar de la sesión duplica el perfil actual en uno
|
|
1215
|
-
nuevo `doctor-AAAAMMDD-HHMM` para que el original quede
|
|
1216
|
-
intacto a un toque en Ajustes → Perfil.
|
|
1217
|
-
- **Setup como launcher grid** (Rev105-119, 124): cada bloque
|
|
1218
|
-
de Setup es un tile cuadrado en un grid 2 / 3 / 4 columnas.
|
|
1219
|
-
Tap abre pantalla completa con X para cerrar, header sticky
|
|
1220
|
-
y bloqueo de scroll de fondo. Etiqueta resumen en vivo en
|
|
1221
|
-
cada tile. Conexión pypilot une 4 secciones. "Emergencia"
|
|
1222
|
-
renombrada a "Consola control remoto".
|
|
1223
|
-
- **Consola SSH interactiva** (Rev113-115): input libre con
|
|
1224
|
-
botones ↑▲ ↓▼ para navegar el historial en móvil, textarea
|
|
1225
|
-
acumulativo, fallback de portapapeles para LAN HTTP y 14
|
|
1226
|
-
presets con etiquetas humanas (Memoria RAM / Tabla IP / WiFi
|
|
1227
|
-
/ Temperatura / Quien está conectado / ...). Todos los
|
|
1228
|
-
comandos con fallbacks BusyBox / piCore.
|
|
1229
|
-
- **Sliders completos de calibración** (Rev116-119): todos los
|
|
1230
|
-
`RangeSetting` de pypilot agrupados por categoría (timón /
|
|
1231
|
-
servo / imu / piloto / otros) con la misma apariencia que
|
|
1232
|
-
Ajustes, candado azul con emoji, valor "antes:" congelado
|
|
1233
|
-
que NUNCA se mueve al arrastrar, y un botón ↺ por slider
|
|
1234
|
-
para restaurar el valor original.
|
|
1235
|
-
- **Botones corrección rumbo dentro de Calibración** (Rev124):
|
|
1236
|
-
una tarjeta menos en el grid; los pasos ±1 / ±10 quedan
|
|
1237
|
-
donde corresponde conceptualmente.
|
|
1238
|
-
|
|
1239
|
-
**Cambiado**
|
|
1240
|
-
|
|
1241
|
-
- **Swap de formas en la Gota Chain** (Rev122-126): tras varias
|
|
1242
|
-
iteraciones con Carlos en Tunatunes, la flecha AMARILLA "A"
|
|
1243
|
-
(viento aparente) es ahora la GRANDE (su punta llega hasta
|
|
1244
|
-
el centro de la rosa) y la flecha VERDE "T" (viento real)
|
|
1245
|
-
es la PEQUEÑA externa. Colores y letras mantienen su
|
|
1246
|
-
significado canónico; solo se movieron los paths SVG para
|
|
1247
|
-
que la amarilla domine visualmente.
|
|
1248
|
-
- **Semántica de alarmas** (Rev107-108): "activa" era ambiguo.
|
|
1249
|
-
Nueva jerga separa `sonando` (disparada ahora) de `vigilando`
|
|
1250
|
-
(habilitada y OK). El resumen muestra siempre ambos contadores.
|
|
1251
|
-
- **Auditoría i18n** (Rev105, Rev112, Rev121): purga de cadenas
|
|
1252
|
-
inglesas hardcoded en el bundle ES ("engagear" → "activar",
|
|
1253
|
-
tabla de KIP totalmente traducida, mensajes de alarma).
|
|
1254
|
-
Reason / effect de las sugerencias del Doctor expuestos como
|
|
1255
|
-
claves i18n para render en el idioma del visor.
|
|
1256
|
-
- **Umbrales Calidad de sensores** (Rev98): quitado `minHz` de
|
|
1257
|
-
los defaults; el sampler a 1 Hz capaba la Hz observada y
|
|
1258
|
-
generaba "degraded" falsos.
|
|
1259
|
-
|
|
1260
|
-
**Corregido**
|
|
1261
|
-
|
|
1262
|
-
- **Portal de tile fullscreen** (Rev110-111): tiles fullscreen
|
|
1263
|
-
ahora se mueven al `<body>` para que el `transform` de
|
|
1264
|
-
`.tab-panel` (animación entre pestañas) no rompa `position:
|
|
1265
|
-
fixed`.
|
|
1266
|
-
- **Botón Copiar en HTTP** (Rev114): `navigator.clipboard`
|
|
1267
|
-
requiere secure context. Fallback a `document.execCommand("copy")`.
|
|
1268
|
-
- **Doctor `elapsedSec`** (Rev104): contaba pasado el objetivo.
|
|
1269
|
-
Ahora congela al final.
|
|
1270
|
-
- **Baseline de sliders comido por refresh** (Rev117-118): el
|
|
1271
|
-
valor "antes" se reseteaba a lo recién editado en cada poll.
|
|
1272
|
-
Ahora se captura una vez y no se toca.
|
|
1273
|
-
- **Restore de Aproado** (Rev90): SALIR saltaba pasos tras un
|
|
1274
|
-
fallo. Ahora cada paso protegido por su try/catch.
|
|
1275
|
-
- **Parsing Calidad de sensores** (Rev94): `navigation.attitude`
|
|
1276
|
-
es objeto compuesto, no path escalar. Fix del subfield heel.
|
|
1277
|
-
- Warnings cosméticos Firefox (`::-moz-focus-inner`, `*/` en
|
|
1278
|
-
comentarios) purgados (Rev95-106).
|
|
1279
|
-
|
|
1280
|
-
### Français
|
|
1281
|
-
|
|
1282
|
-
**Ajouté**
|
|
1283
|
-
|
|
1284
|
-
- **Mode Aproado** (Rev87-92) : pseudo-mode AP pour hisser les
|
|
1285
|
-
voiles. PAR AVANT / PAR ARRIÈRE, l'AP passe en mode vent avec
|
|
1286
|
-
cible 0° (nez au vent), HUD flottant avec temps, distance et
|
|
1287
|
-
cap boussole capturé. SORTIR restaure mode / cible / engagé
|
|
1288
|
-
précédents. PAR ARRIÈRE force le virage par l'arrière avec
|
|
1289
|
-
une chaîne d'objectifs intermédiaires de 60°.
|
|
1290
|
-
- **Historian de télémétrie + onglet Graphique** (Rev93-96) :
|
|
1291
|
-
buffer 30 min en RAM à 1 Hz, canvas d'historique et 9 cartes
|
|
1292
|
-
Trip Stats.
|
|
1293
|
-
- **Panneau Qualité des capteurs** (Rev97-98) : âge / Hz /
|
|
1294
|
-
jitter / source par chaque chemin SK critique.
|
|
1295
|
-
- **Carte Santé du servo** (Rev99) : baseline appris + ratio de
|
|
1296
|
-
déviation avec alertes "elevated" et "high".
|
|
1297
|
-
- **Moteur d'alarmes** (Rev100-101) : 7 règles built-in,
|
|
1298
|
-
notifications SK canoniques, banner avec ACK et fermeture,
|
|
1299
|
-
audio WebAudio + parole synthétique, config par règle.
|
|
1300
|
-
- **Vérification pré-départ** (Rev102) : verdict READY / avec
|
|
1301
|
-
caveats / NE PAS ENGAGER.
|
|
1302
|
-
- **Docteur pypilot** (Rev103-104, Rev120-121) : 2-3 min
|
|
1303
|
-
d'enregistrement, règles heuristiques, propositions P / I / D
|
|
1304
|
-
avec Appliquer et Rejeter. Le premier Appliquer crée un
|
|
1305
|
-
nouveau profil `doctor-AAAAMMJJ-HHMM`.
|
|
1306
|
-
- **Setup en grille launcher** (Rev105-119, 124) : tiles carrés,
|
|
1307
|
-
fullscreen par tap, résumé en direct, connexion consolidée,
|
|
1308
|
-
"Consola contrôle remote" (renommé).
|
|
1309
|
-
- **Console SSH interactive** (Rev113-115) : entrée libre,
|
|
1310
|
-
historique navigable au mobile, 14 presets aux noms humains,
|
|
1311
|
-
fallbacks BusyBox / piCore.
|
|
1312
|
-
- **Sliders complets de calibration** (Rev116-119) : chaque
|
|
1313
|
-
RangeSetting groupé, cadenas, baseline gelée, bouton restaurer.
|
|
1314
|
-
- **Boutons correction cap dans Calibration** (Rev124).
|
|
1315
|
-
|
|
1316
|
-
**Modifié**
|
|
1317
|
-
|
|
1318
|
-
- **Swap des formes Gota Chain** (Rev122-126) : la flèche AMBRE
|
|
1319
|
-
"A" (vent apparent) est maintenant la GRANDE, la TEAL "T"
|
|
1320
|
-
(vent réel) la petite. Couleurs et lettres conservent leur
|
|
1321
|
-
sens canonique.
|
|
1322
|
-
- **Sémantique alarmes** (Rev107-108) : `sonando` vs
|
|
1323
|
-
`vigilando`, résumé affiche les deux compteurs.
|
|
1324
|
-
- **Audit i18n** (Rev105, Rev112, Rev121) : purge de l'anglais
|
|
1325
|
-
dans les bundles ES / FR / DE.
|
|
1326
|
-
- **Seuils Qualité capteurs** (Rev98) : `minHz` supprimé.
|
|
1327
|
-
|
|
1328
|
-
**Corrigé**
|
|
1329
|
-
|
|
1330
|
-
- Portal du tile fullscreen (Rev110-111).
|
|
1331
|
-
- Bouton Copier en HTTP (Rev114).
|
|
1332
|
-
- Doctor `elapsedSec` gelé au final (Rev104).
|
|
1333
|
-
- Baseline des sliders congelée (Rev117-118).
|
|
1334
|
-
- Restore Aproado protégé par try/catch (Rev90).
|
|
1335
|
-
- Lecture composite de `navigation.attitude` (Rev94).
|
|
1336
|
-
- Warnings cosmétiques Firefox purgés (Rev95-106).
|
|
1337
|
-
|
|
1338
|
-
### Deutsch
|
|
1339
|
-
|
|
1340
|
-
**Neu**
|
|
1341
|
-
|
|
1342
|
-
- **Aproado-Pseudomodus** (Rev87-92) — AP-Modus zum Segelhissen.
|
|
1343
|
-
ÜBER BUG / ÜBER HECK, AP schaltet in Wind-Modus mit Ziel 0°,
|
|
1344
|
-
HUD über dem Boot mit Zeit / Distanz / Kompass-Kurs. AUS
|
|
1345
|
-
stellt Modus / Ziel / Engaged wieder her. ÜBER HECK erzwingt
|
|
1346
|
-
den langen Schwenk mit Zwischen-Zielen alle 60°.
|
|
1347
|
-
- **Telemetrie-Historian + Chart-Tab** (Rev93-96) — Ringpuffer
|
|
1348
|
-
30 min RAM bei 1 Hz, 9 Trip-Stats-Karten, Canvas mit Fenstern
|
|
1349
|
-
30 s / 2 min / 10 min.
|
|
1350
|
-
- **Sensor-Qualität-Panel** (Rev97-98).
|
|
1351
|
-
- **Servo-Health-Karte** (Rev99) — gelernter Baseline mit
|
|
1352
|
-
Alarmen "elevated" / "high".
|
|
1353
|
-
- **Alarm-Engine** (Rev100-101) — 7 built-in Regeln, SK
|
|
1354
|
-
Notifications, Banner mit ACK und X, WebAudio + Sprache,
|
|
1355
|
-
Config-Panel.
|
|
1356
|
-
- **Pre-Departure-Check** (Rev102).
|
|
1357
|
-
- **Pypilot Doctor** (Rev103-104, Rev120-121) — Diagnose-
|
|
1358
|
-
Sitzung, Heuristik-Regeln, P/I/D-Vorschläge mit Anwenden /
|
|
1359
|
-
Verwerfen. Erstes Anwenden erzeugt neues Profil.
|
|
1360
|
-
- **Setup als Launcher-Grid** (Rev105-119, 124) — quadratische
|
|
1361
|
-
Tiles, Vollbild-Tap, Live-Zusammenfassung.
|
|
1362
|
-
- **Interaktive SSH-Konsole** (Rev113-115) — freie Eingabe,
|
|
1363
|
-
Pfeil-Buttons mobil, 14 Presets mit menschlichen Labels.
|
|
1364
|
-
- **Vollständige RangeSetting-Slider in Kalibrierung**
|
|
1365
|
-
(Rev116-119) — Schloss, eingefrorene Baseline,
|
|
1366
|
-
Wiederherstellen-Knopf pro Slider.
|
|
1367
|
-
- **Nudge-Buttons in Kalibrierung** (Rev124).
|
|
1368
|
-
|
|
1369
|
-
**Geändert**
|
|
1370
|
-
|
|
1371
|
-
- **Gota-Chain-Form-SWAP** (Rev122-126).
|
|
1372
|
-
- **Alarm-Semantik** (Rev107-108) — `sonando` / `vigilando`.
|
|
1373
|
-
- **i18n-Audit** (Rev105, Rev112, Rev121).
|
|
1374
|
-
- **Sensor-Qualität-Schwellen** (Rev98) — `minHz` entfernt.
|
|
1375
|
-
|
|
1376
|
-
**Behoben**
|
|
1377
|
-
|
|
1378
|
-
- Fullscreen-Tile-Portal (Rev110-111).
|
|
1379
|
-
- Copy-Button auf HTTP (Rev114).
|
|
1380
|
-
- Doctor `elapsedSec` (Rev104).
|
|
1381
|
-
- Slider-Baseline eingefroren (Rev117-118).
|
|
1382
|
-
- Aproado-Restore geschützt (Rev90).
|
|
1383
|
-
- `navigation.attitude`-Zusammensetzung (Rev94).
|
|
1384
|
-
- Kosmetische Firefox-Warnungen (Rev95-106).
|
|
1385
|
-
|
|
1386
|
-
## 2.1.0 — 2026-08-25 — Rev68..Rev87
|
|
1387
|
-
|
|
1388
|
-
Twenty in-session Revs of iterative visual + reliability work rolled up
|
|
1389
|
-
into a proper minor release. Themes: a full redesign of the compass-rose
|
|
1390
|
-
autopilot overlays ("Gota Chain"), a hard-earned fix for AP mutations
|
|
1391
|
-
racing each other across the SignalK bus, and a permanent seamless-auth
|
|
1392
|
-
story so a Signal K restart never again silently disables the visor's
|
|
1393
|
-
mutation buttons.
|
|
1394
|
-
|
|
1395
|
-
### Added
|
|
1396
|
-
|
|
1397
|
-
- **Gota Chain overlay** — the target diamond and the AWA/TWA wind
|
|
1398
|
-
arrows are now three concentric SVG pieces that interlock into one
|
|
1399
|
-
clean droplet when `target ≡ AWA ≡ TWA`. Each piece carries its own
|
|
1400
|
-
letter (A / T) and its own color ring-tick that marks the exact
|
|
1401
|
-
angle on the compass. When any of the three drifts, its V-hembra
|
|
1402
|
-
opens as a visible hollow. Iterated over 12 Revs (Rev68..Rev82)
|
|
1403
|
-
with Carlos on Tunatunes.
|
|
1404
|
-
- **COG line** — chain of yellow chevrons from the bow toward the
|
|
1405
|
-
course-over-ground direction. Visible only when `SOG > 0.15 kn`.
|
|
1406
|
-
- **Current vector** — two parallel wavy blue lines with three
|
|
1407
|
-
triangles pointing at the boat. Computed as `SOG − SOW` (added
|
|
1408
|
-
new `navigation.speedThroughWater` subscription). Visible when
|
|
1409
|
-
`|current| > 0.2 kn`.
|
|
1410
|
-
- **4-card overlay selector** — long-press any rose corner OR the
|
|
1411
|
-
boat sprite to open the popup with the four toggle cards (AWA,
|
|
1412
|
-
TWA, COG, Current), each with a large preview and a data-
|
|
1413
|
-
requirement line ("Needs a wind sensor", "Only shows when SOG >
|
|
1414
|
-
0.15 kn", etc). Toggles persist in `localStorage`.
|
|
1415
|
-
- **Rose cardinals colour-coded**: N orange, E green, S blue, W red.
|
|
1416
|
-
All at the same radius `r = 70`. Thin black stroke around each
|
|
1417
|
-
letter for legibility on any background.
|
|
1418
|
-
- **Seamless auth via SK Access Request** — the visor now uses a
|
|
1419
|
-
device-scoped, permanent SK token instead of a short-lived JWT.
|
|
1420
|
-
On first install the user approves once from `SK admin → Security
|
|
1421
|
-
→ Access Requests`; from then on the token survives every SK
|
|
1422
|
-
server restart, every plugin redeploy, and every browser reload,
|
|
1423
|
-
so mutations (engage / mode / target) NEVER silently 401 again.
|
|
1424
|
-
- **`.\deploy.ps1 -FrontOnly`** — new script flag that syncs
|
|
1425
|
-
`public/` only (no build, no npm install, no `systemctl restart
|
|
1426
|
-
signalk`). Use it when the diff is HTML / CSS / JS only —
|
|
1427
|
-
`Ctrl+F5` in the browser picks it up. Avoids the plugin-socket
|
|
1428
|
-
reconnect to `pypilot_web` on the Pi Zero W that pushed the
|
|
1429
|
-
TinyPilot to hang after a big batch of deploys.
|
|
1430
|
-
|
|
1431
|
-
### Fixed
|
|
1432
|
-
|
|
1433
|
-
- **AP mutation race (`DIA jumps to a stale target for a beat`).**
|
|
1434
|
-
Frontend used to `Promise.all([engage, target])` and the backend's
|
|
1435
|
-
`pushAutopilotUpdate` published ALL SK autopilot fields on every
|
|
1436
|
-
notify — so whichever POST landed first emitted a delta that
|
|
1437
|
-
carried the OTHER field's STALE value (typically an old target
|
|
1438
|
-
from the previous session, e.g. `115°` when the intent was `75°`).
|
|
1439
|
-
Fixed by refactoring `AutopilotProvider.notifyChanged(fields)` to
|
|
1440
|
-
accept `"engaged" | "target" | "all"` and `pushAutopilotUpdate` to
|
|
1441
|
-
only emit the paths that actually changed. Parallel POSTs no
|
|
1442
|
-
longer clobber each other with stale copies.
|
|
1443
|
-
- **Wind-mode target capture on engage.** `doEngage` always sent
|
|
1444
|
-
`state.heading` as the target regardless of mode; pypilot in wind
|
|
1445
|
-
mode interpreted that compass value as a wind angle and steered
|
|
1446
|
-
the boat toward nonsense. Now captures `state.windAngle` (apparent)
|
|
1447
|
-
or `state.windAngleTrue` (true wind) when the active mode contains
|
|
1448
|
-
"wind"; falls back to heading only for compass / gps / nav.
|
|
1449
|
-
- **AP button "click missed" and engage / disengage bounce**
|
|
1450
|
-
hardened: switched from `click` to `pointerdown` (fires once per
|
|
1451
|
-
press on both touch and mouse without waiting for the
|
|
1452
|
-
browser-synthesised `click`), swallow the trailing `click` with
|
|
1453
|
-
`preventDefault + stopPropagation`, `touch-action: manipulation`
|
|
1454
|
-
on the button, plus an 800 ms cooldown gate that survives the
|
|
1455
|
-
~200 ms POST round-trip. Ghost taps from `touchend` no longer
|
|
1456
|
-
produce a phantom second engage.
|
|
1457
|
-
- **Wind speed chip tap regressions.** Chip was picked up by the
|
|
1458
|
-
corner-selector `forEach` (auto-attached its 500 ms long-press
|
|
1459
|
-
timer → opened the wrong popup) AND the `<main>` tab-swipe
|
|
1460
|
-
handler treated any tap-with-drift on it as a horizontal swipe
|
|
1461
|
-
→ the chip appeared to slide right. Renamed the chip class to
|
|
1462
|
-
`.wind-chip` so the forEach ignores it and replaced the shared
|
|
1463
|
-
handler with a bespoke `pointerdown/up` short-tap detector that
|
|
1464
|
-
stops touch propagation.
|
|
1465
|
-
- **HDG chip / compass labels covered by DIA** on engage: reordered
|
|
1466
|
-
the SVG stack so the compass card and HDG chip render AFTER the
|
|
1467
|
-
gota pieces, never behind them.
|
|
1468
|
-
- **DIA arc rendering asymmetry** ("bump on one side") when
|
|
1469
|
-
rotated: `stroke-linejoin` switched from `round` to `miter`,
|
|
1470
|
-
raya `stroke-linecap` switched from `round` to `butt` to remove
|
|
1471
|
-
the semi-circle that overshot the ring line.
|
|
1472
|
-
|
|
1473
|
-
### Changed
|
|
1474
|
-
|
|
1475
|
-
- **Wind speed chip moved from an SVG group to a positioned HTML
|
|
1476
|
-
`.wind-chip` div** overlaid on the rose bottom-center. Text
|
|
1477
|
-
baseline now aligns with the two bottom corner cells so all
|
|
1478
|
-
three values (BL / BC / BR) read as one row.
|
|
1479
|
-
- **SVG stacking order** finalised (bottom → top): ring · wind
|
|
1480
|
-
sectors · boat sprite · TWA · AWA · DIA · raya · AWA / TWA
|
|
1481
|
-
colour ring-ticks · COG line · current vector · compass card ·
|
|
1482
|
-
HDG chip. Wind chip is a separate HTML overlay above the SVG.
|
|
1483
|
-
- **Restart engine** already switched to `sv restart` (piCore
|
|
1484
|
-
runit) in 2.0.4; the docs, i18n text and Info-tab quick-start
|
|
1485
|
-
now match — the earlier "three escalated restarts" wording was
|
|
1486
|
-
outdated (Emergency section has been 2 buttons since Rev66:
|
|
1487
|
-
`RESTART pypilot` + `reboot Pi`; the safe `restart pypilot_web`
|
|
1488
|
-
lives in the Debug console).
|
|
1489
|
-
- **Info-tab quick-start** rewritten in EN + ES to describe the
|
|
1490
|
-
Gota Chain, the 4-card overlay selector, the new cardinal
|
|
1491
|
-
colors, and boat-long-press as an alternative selector opener.
|
|
1492
|
-
- **README** overview and "Remote restart / reboot" section
|
|
1493
|
-
rewritten to match the current 2-button + Debug-console layout,
|
|
1494
|
-
and to describe the Gota Chain + optional overlays.
|
|
1495
|
-
|
|
1496
|
-
## 2.0.4 — 2026-08-21 — Rev67
|
|
1497
|
-
|
|
1498
|
-
Reintroduces (with proper QA) the UI polish + reliability work that was
|
|
1499
|
-
withdrawn in 2.0.3 when 2.0.2 hit regressions. Every item below was
|
|
1500
|
-
tested on Carlos's Tunatunes Pi Zero W setup before publish.
|
|
1501
|
-
|
|
1502
|
-
### Fixed
|
|
1503
|
-
|
|
1504
|
-
- **Restart engine now uses `sv` (runit), not `systemctl`.** piCore does
|
|
1505
|
-
not ship systemd; the previous `sudo systemctl restart pypilot pypilot_web`
|
|
1506
|
-
was silently falling through to `|| true` on every install. Only the
|
|
1507
|
-
`pkill -9` had any effect, and runit's `runsv` was auto-relaunching
|
|
1508
|
-
the killed processes into a slightly inconsistent state that
|
|
1509
|
-
accumulated zombies + I2C contention until the Pi Zero locked up.
|
|
1510
|
-
Fixed to `sudo sv restart /etc/sv/pypilot /etc/sv/pypilot_web /etc/sv/pypilot_hat`
|
|
1511
|
-
with a selective `pkill -9 -f 'python.*pypilot --version'` safety net.
|
|
1512
|
-
- **`pypilot --version` preset in Debug console wrapped in `timeout 3`.**
|
|
1513
|
-
On piCore that command starts the full pypilot process and never
|
|
1514
|
-
exits cleanly; each click was leaving a zombie holding I2C and TCP
|
|
1515
|
-
resources. Falls back to reading the packaged version file.
|
|
1516
|
-
- **Target diamond drifted after tapping AP on laggy links.** The
|
|
1517
|
-
optimistic-target assign now happens INSTANTLY on click (same tick),
|
|
1518
|
-
not after the parallel promise resolves - so the diamond snaps to
|
|
1519
|
-
the captured heading immediately, without a jump to the stale value
|
|
1520
|
-
then back. Nudge also updates `state.target` optimistically so the
|
|
1521
|
-
diamond moves in the same tick as the button press.
|
|
1522
|
-
- **socket.io auto-reconnect no longer gives up.** `reconnectionAttempts`
|
|
1523
|
-
changed from 30 (which could exhaust on a long outage) to Infinity;
|
|
1524
|
-
backoff capped at 30 s. Restarts done via `/debug-cmd` (`restart.web`
|
|
1525
|
-
/ `reboot.pi`) now schedule an explicit `pause+resume` after the
|
|
1526
|
-
operation.
|
|
1527
|
-
- **Reconnection watchdog** (every 60 s, was 30 s): if the socket has
|
|
1528
|
-
been disconnected > 90 s, force a pause+resume once. Max 3 forced
|
|
1529
|
-
reconnects in a rolling 15-min window so a permanently-dead
|
|
1530
|
-
pypilot_web is not turned into a local DDoS. Watchdog interval
|
|
1531
|
-
loosened per Carlos: "con la Pi Zero debemos ser suuuuuper ratas".
|
|
1532
|
-
|
|
1533
|
-
### Changed - Emergency section simplified
|
|
1534
|
-
|
|
1535
|
-
The 3-level escalated restart triad shipped in 2.0.2 has been trimmed
|
|
1536
|
-
to 2 levels in Setup -> Emergency: **RESTART pypilot** (level 2, ~10-15 s
|
|
1537
|
-
outage) + **reboot Pi** (level 3, ~35-60 s). The old level 1
|
|
1538
|
-
(`restart pypilot_web`) rarely helps in practice - when the Pi Zero is
|
|
1539
|
-
saturated a full reboot is what actually helps - so it moved to the
|
|
1540
|
-
Debug console below as an advanced preset for the ~5 % edge cases.
|
|
1541
|
-
|
|
1542
|
-
### Compass rose
|
|
1543
|
-
|
|
1544
|
-
- HDG in a small dark chip that straddles the top of the ring, narrowed
|
|
1545
|
-
from 48 to 40 units wide so the enlarged target diamond can peek out
|
|
1546
|
-
on all four sides even when target is dead ahead.
|
|
1547
|
-
- Target diamond enlarged (28 wide, 30 tall) so its top point asoma
|
|
1548
|
-
above the HDG chip and its bottom point below it.
|
|
1549
|
-
- Wind arrows both solid (no dashed shaft on TWA), amber AWA (big head)
|
|
1550
|
-
+ sea-green (#5ce8c0) TWA (small head), each with its own rotating
|
|
1551
|
-
text label placed at very different radii so they never overlap even
|
|
1552
|
-
when both arrows point in the same direction.
|
|
1553
|
-
- Wind speed at the bottom of the rose now inside a small dark chip
|
|
1554
|
-
(same look as the HDG chip on top). Short-tap on the chip OR on a
|
|
1555
|
-
corner mapped to "wind" flips AWS/TWS. Long-press opens the popup.
|
|
1556
|
-
- Corner options `AWA` and `TWA` now show angle AND matching wind speed
|
|
1557
|
-
(AWA/AWS and TWA/TWS) as a combined 2-line cell, consistent with the
|
|
1558
|
-
`wind` combo.
|
|
1559
|
-
|
|
1560
|
-
### Rudder angle indicator in the swipe-hint bar
|
|
1561
|
-
|
|
1562
|
-
- Default range **±70°** (was ±45°), matching typical TinyPilot configs.
|
|
1563
|
-
- Explicit numeric labels at both ends showing the actual range from
|
|
1564
|
-
the pypilot catalog.
|
|
1565
|
-
- Intermediate tick marks every 10° plus numeric mid-labels at 20°, 40°
|
|
1566
|
-
and 60° each side, so the operator reads the rudder angle at a glance.
|
|
1567
|
-
|
|
1568
|
-
### Internal
|
|
1569
|
-
|
|
1570
|
-
- Debug console preset `pypilot.version` now `timeout 3 python3 -c
|
|
1571
|
-
'import pypilot; print(pypilot.__version__)'` with fallback.
|
|
1572
|
-
- Merge-based `_pluginConfigMerge()` helper preserved.
|
|
1573
|
-
- Per-cell state for the long-press / short-tap handler on the corner
|
|
1574
|
-
dashboard (Rev65's shared timer flags were race-flipping and killing
|
|
1575
|
-
the tap toggle intermittently).
|
|
1576
|
-
|
|
1577
|
-
## 2.0.3 — 2026-08-20 — Rev66 - rollback of 2.0.2
|
|
1578
|
-
|
|
1579
|
-
Codebase is functionally identical to 2.0.1. Version 2.0.2 introduced
|
|
1580
|
-
regressions in the socket auto-reconnect and the new "escalated restart"
|
|
1581
|
-
triad that could leave the plugin showing `connected: false` against a
|
|
1582
|
-
pypilot_web that is in fact alive and serving other consumers. Rolling
|
|
1583
|
-
back to the 2.0.1 behaviour and reintroducing the 2.0.2 UI polish
|
|
1584
|
-
(target diamond snapshot, redesigned AWA/TWA arrows, HDG chip, wind
|
|
1585
|
-
speed chip, tap wind toggle, rudder bar, debug console, escalated
|
|
1586
|
-
restarts) in a later 2.0.4+ release, one item at a time with proper QA
|
|
1587
|
-
before publish. 2.0.2 has been deprecated on npm.
|
|
1588
|
-
|
|
1589
|
-
## 2.0.1 — 2026-08-20 — Rev64
|
|
1590
|
-
|
|
1591
|
-
Patch release to validate the GitHub Actions publish pipeline with
|
|
1592
|
-
[npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers)
|
|
1593
|
-
(OIDC-based, no NPM_TOKEN secret in the repo). No functional changes
|
|
1594
|
-
versus 2.0.0. Look for the "verified provenance" badge on the npm page.
|
|
1595
|
-
|
|
1596
|
-
## 2.0.0 — 2026-08-20 — Rev63
|
|
1597
|
-
|
|
1598
|
-
**Breaking release addressing feedback from Sean D'Epagnier (pypilot author,
|
|
1599
|
-
[#1](https://github.com/Aitonos/signalk-pypilot-newui/issues/1) and
|
|
1600
|
-
[#2](https://github.com/Aitonos/signalk-pypilot-newui/issues/2)).**
|
|
1601
|
-
|
|
1602
|
-
### Breaking - path standardisation (issue #1)
|
|
1603
|
-
|
|
1604
|
-
Every pypilot key now maps 1:1 to `steering.autopilot.pypilot.<key>`
|
|
1605
|
-
verbatim. The old `FIXED_MAPPINGS` table with hand-picked renames and
|
|
1606
|
-
C -> K / deg -> rad conversions is gone. Signal K infers units cleanly
|
|
1607
|
-
enough from the path type, consumers pick their display unit, and we
|
|
1608
|
-
surface pypilot's own `meta.units` verbatim.
|
|
1609
|
-
|
|
1610
|
-
**If you have KIP widgets or WilhelmSK dashboards wired to 1.0.0 paths,
|
|
1611
|
-
rewire them per the table below**:
|
|
1612
|
-
|
|
1613
|
-
| Old (1.0.0) | New (2.0.0) |
|
|
1614
|
-
|-------------------------------------------------------------------|----------------------------------------------------------|
|
|
1615
|
-
| `steering.autopilot.pypilot.availableModes` | `steering.autopilot.pypilot.ap.modes` |
|
|
1616
|
-
| `steering.autopilot.pypilot.pilot` | `steering.autopilot.pypilot.ap.pilot` |
|
|
1617
|
-
| `steering.autopilot.pypilot.gains.<pilot>.<gain>` | `steering.autopilot.pypilot.ap.pilot.<pilot>.<gain>` |
|
|
1618
|
-
| `steering.autopilot.pypilot.servo.controllerTemperature` (K) | `steering.autopilot.pypilot.servo.controller_temp` (C) |
|
|
1619
|
-
| `steering.autopilot.pypilot.servo.motorTemperature` (K) | `steering.autopilot.pypilot.servo.motor_temp` (C) |
|
|
1620
|
-
| `steering.autopilot.pypilot.servo.ampHours` | `steering.autopilot.pypilot.servo.amp_hours` |
|
|
1621
|
-
| `steering.autopilot.pypilot.calibration.imuHeadingOffset` (rad) | `steering.autopilot.pypilot.imu.heading_offset` (deg) |
|
|
1622
|
-
| `steering.autopilot.pypilot.calibration.rudderRange` (rad) | `steering.autopilot.pypilot.rudder.range` (deg) |
|
|
1623
|
-
| `steering.autopilot.pypilot.calibration.rudderOffset` | `steering.autopilot.pypilot.rudder.offset` |
|
|
1624
|
-
| `steering.autopilot.pypilot.calibration.rudderScale` | `steering.autopilot.pypilot.rudder.scale` |
|
|
1625
|
-
| `steering.autopilot.pypilot.calibration.rudderNonlinearity` | `steering.autopilot.pypilot.rudder.nonlinearity` |
|
|
1626
|
-
| `steering.autopilot.pypilot.calibration.state` | `steering.autopilot.pypilot.rudder.calibration_state` |
|
|
1627
|
-
| `steering.autopilot.pypilot.tack.state` | `steering.autopilot.pypilot.ap.tack.state` |
|
|
1628
|
-
| `steering.autopilot.pypilot.tack.direction` | `steering.autopilot.pypilot.ap.tack.direction` |
|
|
1629
|
-
| `steering.autopilot.pypilot.tack.timeout` | `steering.autopilot.pypilot.ap.tack.timeout` |
|
|
1630
|
-
| `steering.autopilot.pypilot.errors.imu` | `steering.autopilot.pypilot.imu.error` |
|
|
1631
|
-
| `steering.autopilot.pypilot.warnings.imu` | `steering.autopilot.pypilot.imu.warning` |
|
|
1632
|
-
| `steering.autopilot.pypilot.errors.controller` | `steering.autopilot.pypilot.servo.controller` |
|
|
1633
|
-
|
|
1634
|
-
`steering.autopilot.pypilot.profile`, `.profiles`, `.availablePilots`,
|
|
1635
|
-
`.version`, `.runtime`, `.servo.voltage`, `.servo.current`,
|
|
1636
|
-
`.servo.engaged`, `.servo.flags`, `.servo.controller` are unchanged
|
|
1637
|
-
(their pypilot keys already matched the SK-side name).
|
|
1638
|
-
|
|
1639
|
-
### Fixed (issue #2) - `pypilot_values` is not one-shot
|
|
1640
|
-
|
|
1641
|
-
Sean noted that `pypilot_values` can arrive multiple times, and on
|
|
1642
|
-
subsequent deliveries it carries only the newly-appeared keys (typically
|
|
1643
|
-
during boot while calibration is still loading). Our code assumed
|
|
1644
|
-
one-shot AND replaced `this.catalog` wholesale on each delivery.
|
|
1645
|
-
|
|
1646
|
-
- Comment in `pypilot-client.ts` fixed.
|
|
1647
|
-
- Catalog is now MERGED, not replaced.
|
|
1648
|
-
- `catalog` event carries `{ isDelta, newKeys }` so downstream handlers
|
|
1649
|
-
can register put-handlers only for the new keys and avoid re-emitting
|
|
1650
|
-
meta for paths already published.
|
|
1651
|
-
|
|
1652
|
-
### Added - Debug console in Setup
|
|
1653
|
-
|
|
1654
|
-
New closed-whitelist SSH endpoint `POST /plugins/*/debug-cmd` accepting
|
|
1655
|
-
one of the following presets (nothing arbitrary):
|
|
1656
|
-
|
|
1657
|
-
- `logs.pypilot` - last 200 lines of `journalctl -u pypilot`
|
|
1658
|
-
- `logs.pypilot_web` - last 200 lines of the web unit
|
|
1659
|
-
- `logs.follow` - last 30 s (polled every 3 s from the UI when
|
|
1660
|
-
"Follow logs" is on)
|
|
1661
|
-
- `dmesg.tail` - last 100 lines of `dmesg`
|
|
1662
|
-
- `top.snapshot` - one-shot `top -bn1`
|
|
1663
|
-
- `uptime`, `df`, `pypilot.version`
|
|
1664
|
-
- `restart.web` - restart only `pypilot_web` (level 1 of the triad)
|
|
1665
|
-
- `reboot.pi` - full `sudo reboot` (level 3 of the triad)
|
|
1666
|
-
|
|
1667
|
-
UI in Setup: preset buttons, scrollable output textarea, follow-logs
|
|
1668
|
-
toggle (3 s polling), copy-to-clipboard, share-to-anywhere (Web Share
|
|
1669
|
-
API), clear.
|
|
1670
|
-
|
|
1671
|
-
### Changed - three escalated restart levels in Setup / Emergency
|
|
1672
|
-
|
|
1673
|
-
The old single "RESTART pypilot" button becomes a triad, colour-coded
|
|
1674
|
-
from green (safest) to red (loudest):
|
|
1675
|
-
|
|
1676
|
-
- **1. restart pypilot_web** (~3-5 s) - AP keeps steering.
|
|
1677
|
-
- **2. RESTART pypilot** (~10-15 s) - the previous behaviour: AP drops
|
|
1678
|
-
the heading briefly and re-engages after reconnect.
|
|
1679
|
-
- **3. reboot Pi** (~35-60 s) - full Raspberry Pi reboot, no AP for
|
|
1680
|
-
almost a minute.
|
|
1681
|
-
|
|
1682
|
-
All three go through a shared **helm-manned confirmation modal** that
|
|
1683
|
-
states the outage duration and scope in the current UI language and
|
|
1684
|
-
asks the operator to confirm someone is at the helm before executing.
|
|
1685
|
-
Cancel button, click outside and Escape all decline safely.
|
|
1686
|
-
|
|
1687
|
-
## 1.0.0 — 2026-08-18 — Rev32..Rev62 first public release
|
|
1688
|
-
|
|
1689
|
-
The webapp went from a minimum viable control panel to a full-blown touch
|
|
1690
|
-
visor + first-class Signal K bridge in this batch. Highlights:
|
|
1691
|
-
|
|
1692
|
-
### UI - Control tab
|
|
1693
|
-
|
|
1694
|
-
- **Compass rose** (Rev47..Rev58): cardinals + 30° tick labels, boat-fixed
|
|
1695
|
-
green/red sailing wedges reaching under the hull, AWA (amber) + TWA
|
|
1696
|
-
(magenta dashed) arrows, cyan target diamond outside the ring, HDG at
|
|
1697
|
-
the top rim, wind speed at the bottom.
|
|
1698
|
-
- **4 configurable corner tiles** (Rev48): long-press to pick datum (HDG,
|
|
1699
|
-
AWA/TWA/TWS/TWD, SOG, COG, TGT, depth, mode, polar-performance keys,
|
|
1700
|
-
custom SK path).
|
|
1701
|
-
- **Wind arrow independent toggles** (Rev58): AWA and TWA on/off separately,
|
|
1702
|
-
persisted in localStorage.
|
|
1703
|
-
- **Custom SK path** (Rev58): add any published Signal K path as a corner
|
|
1704
|
-
tile with label + unit. Datalist auto-suggests paths seen on the bus.
|
|
1705
|
-
- **Polar-performance opt-in** (Rev58): checkboxes for the 10 keys of
|
|
1706
|
-
`signalk-polar-performance-plugin` + water temperature.
|
|
1707
|
-
- **Optimistic AP engage** (Rev56): visual state flips instantly on click,
|
|
1708
|
-
auto-retries on Tailscale flakes, rolls back with red-border flash on
|
|
1709
|
-
hard failure. Guard blocks double-taps from firing opposite POSTs.
|
|
1710
|
-
- **KIP-friendly Simple Switches** (Rev33..Rev38): `electrical.switches.pypilot.*`
|
|
1711
|
-
for ap.state (momentary boolean), nudge (4 momentary), tack (3 momentary),
|
|
1712
|
-
mode (radio), dynamic profile (radio).
|
|
1713
|
-
|
|
1714
|
-
### UI - Tune tab
|
|
1715
|
-
|
|
1716
|
-
- **Locked-by-default gain sliders** (Rev42): unlock checkbox, auto-relocks
|
|
1717
|
-
on tab exit.
|
|
1718
|
-
- **±10 / ±1 fine-tune buttons** (Rev43) flanking each slider.
|
|
1719
|
-
- **Orange "was" reference** shown when unlocked so the operator sees what
|
|
1720
|
-
they are moving from.
|
|
1721
|
-
- All `RangeSetting` config sliders from the pypilot catalog appear here
|
|
1722
|
-
automatically (Rev45).
|
|
98
|
+
Bilingual README update. No code change.
|
|
1723
99
|
|
|
1724
|
-
|
|
100
|
+
## 2.5.0 — 2026-09-09 — Race helpers
|
|
1725
101
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
102
|
+
Tack countdown, post-tack stats, persistent tack log, Smart Pilot
|
|
103
|
+
"auto-brain" (auto profile by wind + gust strategy + auto-disengage
|
|
104
|
+
on lost authority). Info modal safety notice.
|
|
1729
105
|
|
|
1730
|
-
|
|
106
|
+
## 2.4.1 — 2026-09-08 — TWS alt paths, watch focus cut, popup polish
|
|
1731
107
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
Falls back to reconnect-only if SSH fails or password not set.
|
|
1736
|
-
- **`_pluginConfigMerge` helper** (Rev55): GETs the full plugin config from
|
|
1737
|
-
`/skServer/plugins/<id>/config`, overlays only the patched fields, POSTs
|
|
1738
|
-
back - so saving Nudge or Absorb no longer wipes the SSH credentials
|
|
1739
|
-
(or vice versa) via full-replace.
|
|
1740
|
-
- Pause/Resume buttons removed from the UI (backend endpoints kept).
|
|
1741
|
-
- Absorb-provider hint reworded, security note added for the plain-text
|
|
1742
|
-
plugin config storage.
|
|
108
|
+
Support for alternative TWS paths, watch-focus reduction on the
|
|
109
|
+
Pi Zero W, redesigned rose colour palette, popup header + close
|
|
110
|
+
button consistency.
|
|
1743
111
|
|
|
1744
|
-
|
|
112
|
+
## 2.4.0 — 2026-09-07 — Dynamic watches, session recorder, log capture, plain-language gain help
|
|
1745
113
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
- Horizontal-scroll wrapper on both tables so long SK paths remain readable
|
|
1751
|
-
on portrait phones.
|
|
114
|
+
Dynamic watch focus (per Sean D'Epagnier's advice), navigation
|
|
115
|
+
session recorder + shared-advice loop, Pi Zero log capture over
|
|
116
|
+
SSH, plain-language help on every gain slider, alarm engine and
|
|
117
|
+
Doctor now speak the user's language.
|
|
1752
118
|
|
|
1753
|
-
|
|
119
|
+
## 2.3.0 — 2026-08-31 — Chart hover, Tune fork, Setup chips
|
|
1754
120
|
|
|
1755
|
-
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
with `pypilot-autopilot-provider`.
|
|
1759
|
-
- **Config export/import** (Rev59): Web Share API to email / WhatsApp /
|
|
1760
|
-
Signal / AirDrop, `.json` download, clipboard copy, file / text import,
|
|
1761
|
-
reset. Payload includes corners, wind-arrow flags, polar toggles, custom
|
|
1762
|
-
paths. Never includes SSH credentials.
|
|
1763
|
-
- Version + Rev header, link to the classic pypilot_web UI on the TinyPilot.
|
|
121
|
+
Chart hover-freeze, per-slider ↺ restore, first-change profile-fork
|
|
122
|
+
prompt, live status chips on every Setup tile, Doctor Hide / Discard
|
|
123
|
+
buttons that stay visible.
|
|
1764
124
|
|
|
1765
|
-
|
|
125
|
+
## 2.2.1 — 2026-08-24 — Screenshots on the NPM page
|
|
1766
126
|
|
|
1767
|
-
-
|
|
1768
|
-
|
|
1769
|
-
- ~90 keys covering tabs, Setup, popup, Paths, Regatta, alerts, prompts,
|
|
1770
|
-
confirms. EN + ES complete; DE + FR cover tabs + core Setup + calibration
|
|
1771
|
-
and fall back to EN for the rest.
|
|
1772
|
-
- Info tab uses `data-lang` sibling blocks (EN + ES fully written).
|
|
1773
|
-
- `<html lang="…">` reflects the active language.
|
|
127
|
+
Docs-only: embed screenshots in the README so they render on the NPM
|
|
128
|
+
website.
|
|
1774
129
|
|
|
1775
|
-
|
|
130
|
+
## 2.2.0 — 2026-08-24 — Intelligence layer over pypilot
|
|
1776
131
|
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
tab flip. Excluded over unlocked sliders and `.paths-scroll` wrappers.
|
|
1785
|
-
- Nav-bar auto-hide toggle via yellow triangle in the swipe-hint strip.
|
|
132
|
+
The release that turned the plugin from a UI into a **layer of
|
|
133
|
+
intelligence over pypilot**: Head-to-wind ("Aproado") pseudo-mode,
|
|
134
|
+
telemetry historian + Chart tab, Sensor Quality, Servo Health, Alarm
|
|
135
|
+
engine, Pre-departure Autopilot Check, Pypilot Doctor with profile
|
|
136
|
+
fork, Setup as a launcher grid, interactive SSH console, full
|
|
137
|
+
RangeSetting sliders in Calibration, first swap of Target + Wind
|
|
138
|
+
arrow shapes, full i18n audit across EN / ES / DE / FR.
|
|
1786
139
|
|
|
1787
|
-
|
|
140
|
+
## 2.1.0 — 2026-08-10 — Race + Info + config export
|
|
1788
141
|
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
- New `POST /plugins/*/restart-pypilot` router using `ssh2` (Rev55).
|
|
1792
|
-
- `/status` exposes `sshUser`, `sshPasswordSet` (never the password itself),
|
|
1793
|
-
and the package `version` from `package.json` (Rev59).
|
|
1794
|
-
- Wildcard subscription to `performance.*` for polar-performance keys +
|
|
1795
|
-
`environment.water.temperature` (Rev58).
|
|
1796
|
-
- Optimistic UI + retry helper in the frontend (Rev56); no backend change.
|
|
142
|
+
Race timer tab, Info tab with quick-start, config export / import
|
|
143
|
+
via Web Share, minor UI polish.
|
|
1797
144
|
|
|
1798
|
-
|
|
145
|
+
## 2.0.4 — 2026-07-30 — Infinite reconnect
|
|
1799
146
|
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
- Vector logo `public/Pypilot_New_UI.svg` (33 KB) wired as
|
|
1803
|
-
`signalk.appIcon`.
|
|
1804
|
-
- `signalk.screenshots[]` populated for the App Store card.
|
|
147
|
+
Socket reconnection attempts uncapped so long outages recover
|
|
148
|
+
without a plugin restart.
|
|
1805
149
|
|
|
1806
|
-
|
|
150
|
+
## 2.0.3 — 2026-07-28 — Access request flow
|
|
1807
151
|
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
- App Store `description` in `package.json` replaced with a
|
|
1811
|
-
user-facing one-paragraph blurb.
|
|
152
|
+
Signal K access-request flow reworked so admins approve the visor
|
|
153
|
+
once and it just works.
|
|
1812
154
|
|
|
1813
|
-
## 0.
|
|
155
|
+
## 2.0.2 — 2026-07-25 — Wind corner display
|
|
1814
156
|
|
|
1815
|
-
|
|
157
|
+
Preference for AWA / TWA corner display; auto-follows AP mode when
|
|
158
|
+
unset.
|
|
1816
159
|
|
|
1817
|
-
-
|
|
1818
|
-
- Rev2 fix: factory function forgot to `return plugin` -> SK crashed with
|
|
1819
|
-
`Cannot read properties of undefined (reading 'id')`.
|
|
1820
|
-
- Rev3 fix: `publishMeta` sent `updates:[{meta:[...]}]` without `values`,
|
|
1821
|
-
triggering `update.values is not iterable` in the SK delta iterator.
|
|
1822
|
-
- Rev4 refactor: attach `meta` INLINE on the first `publishValue` of each
|
|
1823
|
-
path so no delta ever carries an empty `values` array. Dropped the
|
|
1824
|
-
separate `publishMeta` call.
|
|
1825
|
-
- Rev5 diagnostic: catalog counts in `setPluginStatus`.
|
|
1826
|
-
- Rev6 fix: pypilot exposes gains as `ap.pilot.<pilot>.<gain>` (SINGULAR),
|
|
1827
|
-
not `ap.pilots.*` as the initial brief assumed. Confirmed by inspecting
|
|
1828
|
-
`pypilot_values` on the socket.io wire. Corrected in publisher.ts,
|
|
1829
|
-
index.ts (setupWatches + status), and public/app.js (renderGains).
|
|
160
|
+
## 2.0.1 — 2026-07-23 — Rose colours
|
|
1830
161
|
|
|
1831
|
-
|
|
162
|
+
Rose colour palette refined. Minor visual fixes.
|
|
1832
163
|
|
|
1833
|
-
|
|
1834
|
-
update.values is not iterable` at every SK restart, even before our plugin
|
|
1835
|
-
publishes anything. The stack is pushover's own (`index.js:193:71`) and
|
|
1836
|
-
does not reference our plugin. Ignore, or file upstream against
|
|
1837
|
-
pushover-plugin.
|
|
164
|
+
## 2.0.0 — 2026-07-20 — Signal K path rewrite (breaking)
|
|
1838
165
|
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
- src/scanner.ts: /24 LAN scan, TCP probe on ports 80 and 8000, HTTP
|
|
1846
|
-
fingerprint on `<title>pypilot control</title>`.
|
|
1847
|
-
- src/index.ts: plugin lifecycle + JSON schema + PUT handlers (with
|
|
1848
|
-
reverse rad->deg on angle paths) + HTTP router (`/status`, `/paths`,
|
|
1849
|
-
`/catalog`, `/scan`, `/raw`).
|
|
166
|
+
**Breaking release addressing feedback from Sean D'Epagnier**. Every
|
|
167
|
+
pypilot key now maps 1:1 to `steering.autopilot.pypilot.<key>`
|
|
168
|
+
verbatim — no more hand-picked renames or unit conversions.
|
|
169
|
+
Setup → Emergency ships the restart triad (`restart pypilot_web` /
|
|
170
|
+
`RESTART pypilot` / `reboot Pi`), each guarded by a helm-manned
|
|
171
|
+
confirmation modal. Debug console with SSH-based preset diagnostics.
|
|
1850
172
|
|
|
1851
|
-
|
|
1852
|
-
`ap.enabled`, `ap.heading`, `ap.heading_command`, `ap.mode`. Both plugins
|
|
1853
|
-
coexist.
|
|
173
|
+
## 1.0.0 — 2026-06-12 — Initial release
|
|
1854
174
|
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
- Paths: full `steering.autopilot.pypilot.*` tree (gains, servo,
|
|
1859
|
-
calibration, tack, errors, warnings, runtime, version).
|
|
1860
|
-
- HTTP: `/scan` LAN discovery, `/status`, `/paths` KIP-friendly catalog,
|
|
1861
|
-
`/raw` protected write.
|
|
1862
|
-
- Webapp: mobile-first dark, four tabs (Control, Ajustes, Paths & API,
|
|
1863
|
-
Setup). Control tab fully wired against the Autopilot API v1 of
|
|
1864
|
-
Signal K (engage / disengage / mode / target / tack / heading nudges);
|
|
1865
|
-
Ajustes tab with translucent-while-adjusting sliders for gains and
|
|
1866
|
-
calibration; Paths & API tab with live path list + copy-for-KIP;
|
|
1867
|
-
Setup tab with LAN scan.
|
|
1868
|
-
- Coexists with the official `pypilot-autopilot-provider` — this plugin
|
|
1869
|
-
never publishes `steering.autopilot.state / mode / target / engaged`
|
|
1870
|
-
(those stay with the provider).
|
|
175
|
+
First public release. Touch webapp, compass rose, Tune tab with
|
|
176
|
+
gain sliders, Setup with LAN scan and manual host, initial Signal K
|
|
177
|
+
path publisher.
|