signalk-pypilot-newui 2.5.1 → 2.7.1

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 CHANGED
@@ -1,1341 +1,169 @@
1
1
  # Changelog
2
2
 
3
- ## 2.5.1 — 2026-09-09 — README bilingual
4
-
5
- Docs-only patch. The EXPERIMENTAL banner in README and CHANGELOG
6
- now appears in English *and* Spanish so the SignalK App Store
7
- description communicates the sea-trial-pending status to English
8
- speakers too. No code changes.
9
-
10
- ## 2.5.0 — 2026-09-09 — Rev154..Rev174
11
-
12
- > ## ⚠️ Ships with features that have not been tested at sea yet
13
- >
14
- > This release brings NEW features that we **could not validate under
15
- > sail** yet (there was not enough wind the day we cut it). Install
16
- > it if you fancy helping us test them — and if anything looks off,
17
- > **tell us**: https://github.com/Aitonos/signalk-pypilot-newui/issues
18
- >
19
- > Your feedback is GOLD for tuning the thresholds before we sign
20
- > these features off as stable for everyone.
21
- >
22
- > ## ⚠️ Version con funciones aun sin probar en el mar
23
- >
24
- > Esta version trae funciones NUEVAS que **no hemos podido validar
25
- > navegando** todavia (el dia de sacarla no habia viento).
26
- > Instalala si te apetece ayudarnos a probarlas — y si algo va raro,
27
- > **avisa**: https://github.com/Aitonos/signalk-pypilot-newui/issues
28
- >
29
- > Tu feedback nos vale ORO para tunear los limites antes de dejar
30
- > estas funciones a punto para todos.
31
- >
32
- > ### ⛵ Que tenemos que probar en el mar (checklist rapida)
33
- >
34
- > 1. **Contador de virada** (grande sobre el barco): al pulsar TACK
35
- > con el AP enganchado, cuenta atras rojo (5-4-3-2-1) y luego pasa
36
- > a naranja "VIRANDO" mientras el pypilot vira. Tocar el circulo
37
- > cancela.
38
- > 2. **Resumen despues de virar** (panel que sale 2 min): compara la
39
- > velocidad y el angulo antes y despues del bordo. Verde = buena.
40
- > Amarillo = normal. Rojo = perdida.
41
- > 3. **Historial de bordos** (deja pulsado el barco -> "Historial"):
42
- > guarda cada bordo con retencion de velocidad y tiempo de
43
- > recuperacion. Filtro por dias, resalta el mejor.
44
- > 4. **Marca de rafagas** (activable en "Cambiar esquinas" ->
45
- > Overlays): cuando entra una rafaga fuerte, deja una flecha
46
- > amarilla fantasma con la velocidad del viento durante 10 segundos.
47
- > 5. **Cerebro auto** (opcional, en la ficha Smart Pilot): si lo
48
- > activas, cambia el perfil del pypilot segun el viento (suave /
49
- > normal / duro) y reacciona a rafagas segun la estrategia elegida
50
- > (avisar / congelar rumbo / subir D / cambiar a perfil duro).
51
- > 6. **Corta automatica** (opcional): si el timon toca los topes
52
- > demasiado tiempo, suelta el AP para que retomes tu.
53
- >
54
- > **Como nos ayudas**: usalas, y si algo se comporta raro o no te
55
- > gusta, mandanos: que hiciste, que esperabas, que paso. Con eso
56
- > tunearemos los limites antes de sacar la 2.5.0 estable.
57
-
58
- ### English (Rev154..Rev174, pending sea-trial confirmation)
59
-
60
- **Added — supervisor layer ("brain over pypilot")**
61
-
62
- - **Auto-profile by wind** — the plugin can switch the active pypilot
63
- profile between light / medium / heavy based on rolling TWS. Bands
64
- configurable in the visor's Smart Pilot card. Disabled by default.
65
- Rev164.
66
- - **Gust strategy** — configurable response when a remarkable AWS jump
67
- is detected: `off`, `warn`, `freeze-target`, `boost-D`, `temp-heavy`.
68
- Replaces the Rev165 warn-only detector. Restore-first logic returns
69
- the pilot to the prior state when the gust window closes. Rev167.
70
- - **Auto-disengage on lost authority** — if the servo saturates against
71
- its rudder stops for a sustained window, the AP releases so a manned
72
- helm regains control. Rev166.
73
- - **Config surface moved to the visor** — the Smart Pilot card in the
74
- plugin's own UI now owns every supervisor toggle. Nothing to touch in
75
- SK Admin. Rev167.
76
-
77
- **Added — rose UI**
78
-
79
- - **Tack countdown overlay over the boat sprite** — huge red digit
80
- during the pre-tack delay, then flips to orange `VIRANDO` + elapsed
81
- seconds during execution. Click cancels the maneuver. Fresh delay is
82
- fetched every arm so an edit in Calibration takes effect without a
83
- page reload. Rev171/172.
84
- - **Post-tack stats HUD** — for 2 minutes after a completed tack the
85
- boat sprite glows and a small panel shows TWS / |AWA| / SOG averaged
86
- 30 s before vs. 30 s after (measured t+30..t+60 so the boat has time
87
- to settle). Verdict is colour-coded by SOG retention. Rev171.
88
- - **Persistent tack log (long-press on the boat)** — every completed
89
- tack is stored locally with pre/post averages, SOG retention %, and
90
- time to recover 95 % of pre-SOG. The action sheet on the boat sprite
91
- now offers "Cambiar esquinas" (the old corner selector) or
92
- "Historial de bordos". The log modal filters by day range and
93
- highlights the best tack by retention and the fastest to recover.
94
- Rev172.
95
- - **Gust ghost arrow (opt-in in the corner-selector modal)** — a
96
- remarkable AWS jump (≥ 6 kn over the 30-s baseline or ≥ 1.55×) or a
97
- sharp AWA rotation (≥ 30° in 5 s) leaves a translucent A-shaped
98
- arrow frozen at the gust angle, with the AWS reading printed
99
- radially outside it, fading to zero over 10 s. Cooldown 30 s and
100
- single-ghost policy so it never chases the live arrow. Card lives
101
- alongside the A / T / COG / Current overlay cards. Rev172-174.
102
- - **Mode selector reads full phrases** — `APARENTE` / `REAL` shown on
103
- the collapsed button, `VIENTO APARENTE` / `VIENTO REAL` on the open
104
- dropdown (swapped on pointerdown / blur). Rev172.
105
- - **T over A on overlap** — when both wind pieces cover the same angle
106
- the teal T now draws on top of the amber A, so TWA stays readable at
107
- a glance. Rev172.
108
- - **Rose corner sub-line resized (Carlos)** — the wind speed under the
109
- angle in the top corners is now a first-class figure in portrait and
110
- a compact one in landscape (media-query split). Bottom AWS/TWS chip
111
- also trimmed so it stops covering half the boat on a portrait phone.
112
- Rev171-173.
113
- - **Tack countdown click-to-cancel** — tapping the huge red circle at
114
- any moment (delay or VIRANDO) sends `ap.tack.state=none`. Guard added
115
- so TACK does nothing if the AP is not engaged. Rev171.
116
-
117
- **Changed — internal**
118
-
119
- - Shared `SERVO_ON_MIN_A` constant across doctor / kpis / servo-health.
120
- Rev154.
121
- - Alarm rules extended with `servo-motor-temp`, `servo-load-high`
122
- (deviation-ratio > 1.65), and `cruise-drift`. Rev155.
123
- - `doctor.applyAll()` applies only the top-priority suggestion and
124
- returns `mustRunFreshSession` + `remaining` so the caller can drive a
125
- next-iteration loop. Rev160.
126
- - Session recorder JSONL now enforces a 200 MB FIFO cap. Rev158.
127
- - Servo-health snapshot persists to disk between restarts. Rev158.
128
- - Hardware-ceiling finding in `doctor` (duty>0.75 & rms>5°) short-
129
- circuits further advice with a "you have out-tuned the actuator"
130
- message. Rev163.
131
-
132
- **Removed**
133
-
134
- - All "helm is manned" confirmation modals on engage / tack / Doctor
135
- apply. Confirming every action was noise; the physical presence of
136
- the helm is a given while at sea. Rev170.
137
-
138
- ## 2.4.1 — 2026-09-08 — Rev146..Rev153
139
-
140
- Patch release. Fixes + UI polish on top of 2.4.0.
141
-
142
- ### English
143
-
144
- **Fixed**
145
-
146
- - **TWS row in Sensor Quality no longer stuck as MISSING** on plain SK
147
- setups. `environment.wind.speedTrue` (canonical) is rarely populated;
148
- the canonical row now accepts `.speedOverGround` (what
149
- `signalk-derived-data` emits) or `.speedOverWater` as alternatives.
150
- Same treatment for TWA (`.angleTrueWater` / `.angleTrueGround` /
151
- `.angleTrue`). Rev146-148.
152
- - **Regression: AP mode selector went blank** after the Rev140 watch
153
- refactor - `RESERVED_PYPILOT_KEYS` was blocking subscribe too, when
154
- it should only block re-publish. Restored so the visor keeps
155
- `ap.enabled/mode/heading_command` in sync. Rev142.
156
- - **Watch focus was pinning 60+ keys** on `pypilot_web` when the Setup
157
- launcher was open. Rev149-150: the launcher grid takes NO focus;
158
- only the Calibration card (fullscreen) bumps the 7 documented
159
- sliders. Empty focus now triggers explicit release, so the count
160
- drops back to the ~15 core watches immediately instead of waiting
161
- for the 60 s TTL. Well under Sean D'Epagnier's 40-path ceiling.
162
- - **`[current]` prefix in Pi Zero log capture** replaced with the
163
- parent directory (`[pypilot]`, `[pypilot_web]`, `[pypilot_hat]`) so
164
- the merged file is actually readable. Rev149.
165
-
166
- **Changed**
167
-
168
- - **Rose colour palette (Carlos)**: Target/DIA diamond is now red
169
- (`--target-red`, matches the AP engage button); AWS/TWS chip below
170
- the rose is fully tinted amber for apparent, teal for true; corner
171
- tiles tint value + sub in the matching wind colour; SOG back to
172
- white; Rev151-152.
173
- - **Configure-corners modal** — h4 + close button now sticky at the
174
- top, body scrolls independently. X on the LEFT with the solid red
175
- `--engaged` style used by the Setup fullscreen cards. Rev151-153.
176
- - **Mode selector labels re-render on language change**: switching
177
- language now redraws mode / pilot / profile selects immediately
178
- instead of waiting for the next backend delta. Rev144.
179
-
180
- ## 2.4.0 — 2026-09-07 — Rev138..Rev145
181
-
182
- Feature release. The plugin has learnt to behave itself around the
183
- Pi Zero (following direct advice from Sean D'Epagnier, pypilot author)
184
- and now speaks the sailor's language instead of pilot-programmer
185
- jargon.
186
-
187
- ### English
188
-
189
- **Added**
190
-
191
- - **Dynamic watch focus (Rev140..Rev141)** — the old policy kept ~170
192
- pypilot subscriptions pinned to `pypilot_web`, which pressured the
193
- Pi Zero W and eventually locked its socket buffer. The backend now
194
- keeps a minimal always-on core (~15 paths, 1-2 Hz) and accepts
195
- short-lived focus requests from the visor: Tune bumps the gain
196
- paths only while it is on screen, same for the Calibration
197
- sliders. TTL expires when the tab closes. New endpoints
198
- `/watch/focus`, `/watch/release`, `/watch/status`, a live inspector
199
- in Setup → Remote Control Console, and a `Restart pypilot_web`
200
- button that runs `sv restart pypilot_web` via SSH.
201
- - **Navigation session recorder + advice loop (Rev143)** — every
202
- engaged AP session is now saved as JSONL to
203
- `~/.signalk/plugin-config-data/signalk-pypilot-newui/nav-sessions/`.
204
- Users label conditions (wind / sea / motor / point of sail / crew)
205
- from a modal in Setup → Doctor, share the file via WhatsApp or
206
- email, receive an "advice" JSON back and upload it - the visor
207
- renders it as a "Consejos recibidos" card. First step of the
208
- AI-tuned Doctor roadmap: no AI runs at runtime, learning happens
209
- off-boat and gets injected as plain heuristics in later Revs.
210
- - **Pi Zero log capture (Rev138)** — piCore keeps `/var/log` in
211
- tmpfs, so a hard reset wipes the previous session's logs. New
212
- opt-in poller SSHes into the Pi Zero on a configurable cadence,
213
- tails `/var/log/pypilot/*` and appends new lines to a persistent
214
- daily file on the Pi 5. Toggle + downloader live in the Remote
215
- Control Console.
216
- - **Plain-language help for every gain (Rev139)** — every P / I / D
217
- / DD / PR / FF slider in Tune and every documented RangeSetting in
218
- Setup → Calibration now carries a short "what it does" line plus a
219
- `?` button that expands into "when to raise, when to lower". EN /
220
- ES / DE / FR. Aligned with Sean's own forum suggestion.
221
- - **Doctor findings and summary translated (Rev136)** — backend now
222
- emits i18n keys with args so the whole Doctor panel reads in the
223
- active language instead of half English / half Spanish.
224
- - **Alarm engine i18n (Rev135..Rev136)** — the seven built-in rules
225
- (heading-deviation, unable-to-steer, servo-overcurrent,
226
- servo-temp-high, low-voltage, sensor-lost, pypilot-disconnected)
227
- render banners and speak in the active language. The backend still
228
- ships English strings on `notifications.autopilot.*` for
229
- KIP / WilhelmSK compatibility.
230
- - **Mode selector proper i18n + uppercase tabs (Rev142, Rev144)** —
231
- `compass`, `wind`, `true wind`, `nav` and the plugin's own
232
- `aproado` render as translated UPPERCASE labels ("COMPAS", "VIENTO
233
- APARENTE", "APROADO"). Tab labels are UPPERCASE too so accents
234
- become optional (RAE convention). Language switch now refreshes
235
- the mode selector and gain help lines immediately.
236
- - **Doctor - persistent Hide button (Rev135..Rev136)** — the discard
237
- action stays visible even after a suggestion has been applied,
238
- the tile chip mirrors the count.
239
- - **Setup launcher - live status chips (Rev130..Rev135)** — pypilot
240
- host+port, active language, calibration last-adjust timestamp
241
- (with a Reset button), count of active SK sentences vs the plugin
242
- catalogue total, and an SSH-configured pill on Remote Control
243
- Console. Sensor Quality gains a per-row Ignore / Restore button so
244
- a sensor absent from the boat (rudder feedback missing, ...)
245
- stops turning the chip red.
246
- - **Chart hover freeze + per-band Y axis (Rev129)** — touch or hover
247
- to freeze the auto-refresh and read the exact value at that point
248
- for every band. Min / mid / max ticks in the right gutter.
249
- - **Tune - per-slider ↺ restore + profile-fork prompt (Rev129,
250
- Rev132..Rev134)** — snap back to the frozen "was:" baseline, or
251
- save the change in a new `tune-YYYYMMDD-HHMM` fork on first
252
- unlock, or Cancel and revert.
253
- - **Nav bar slide-down gesture (Rev129)** — swipe from the top to
254
- bring the tab bar back, counterpart to the existing slide-up hide.
255
-
256
- **Changed**
257
-
258
- - The `RESERVED_PYPILOT_KEYS` set now only blocks publish, not
259
- subscribe. Rev141 regression fix: `ap.mode`, `ap.enabled`,
260
- `ap.heading_command` are needed internally to sync with the SK
261
- Autopilot API v2.
262
- - All six screenshots refreshed to match the current UI.
263
-
264
- ### Español
265
-
266
- **Añadido**
267
-
268
- - **Watch focus dinámico** — el plugin mantiene un núcleo mínimo
269
- suscrito (~15 keys, 1-2 Hz) y sube el rate solo mientras haya una
270
- pestaña que necesite ver esos valores. Sigue la recomendación de
271
- Sean D'Epagnier: pypilot_web se satura si le mandas ~170
272
- suscripciones constantes. Nuevos endpoints, inspector en vivo y
273
- botón "Reiniciar pypilot_web" en la consola remota.
274
- - **Grabador de sesiones + loop de consejos** — cada sesión con el
275
- AP enganchado se guarda como JSONL. Etiquetas por condiciones
276
- (viento / mar / propulsión / rumbo / tripulación), botón compartir
277
- por WhatsApp, y subida del JSON de consejos que se recibe de
278
- vuelta. Primer paso del "Doctor afinado por IA": la IA no corre
279
- en tiempo real, aprende offline y sus heurísticas se inyectan
280
- como código en las próximas Revs.
281
- - **Captura de logs Pi Zero** — piCore guarda `/var/log` solo en
282
- RAM, un hard reset borra el historial. Toggle en la consola
283
- remota que hace SSH cada N segundos y guarda los logs en un
284
- archivo persistente del Pi 5.
285
- - **Explicaciones "en cristiano" para cada ganancia** — P / I / D /
286
- DD / PR / FF más los sliders principales de Calibration llevan
287
- una línea corta con qué hace y un `?` que expande "cuándo subir,
288
- cuándo bajar". EN / ES / DE / FR.
289
- - **Doctor + alarmas en tu idioma** — findings, summary y las siete
290
- reglas de alarma ahora se traducen en el visor. El backend sigue
291
- enviando inglés al SK para KIP / WilhelmSK.
292
- - **Selector de modo traducido en MAYÚSCULAS** — "COMPAS", "VIENTO
293
- APARENTE", "VIENTO REAL", "APROADO", ... con jerga marinera. Las
294
- pestañas también en MAYÚSCULAS para que la tilde sea opcional.
295
- - **Doctor - botón Ocultar siempre visible** — no se atasca la
296
- lista de sugerencias aunque ya las hayas aplicado.
297
- - **Setup - chips vivos en cada tile** — host + puerto TinyPilot,
298
- idioma activo, fecha del último ajuste de calibración, sentencias
299
- SK activas y SSH configurado.
300
- - **Sensor Quality con Ignorar / Restaurar por fila** — para
301
- sensores que no existen en el barco (por ejemplo el timón sin
302
- feedback).
303
- - **Chart con freeze al pasar el cursor + escala Y por banda**.
304
- - **Tune con ↺ por slider + fork de perfil al primer cambio**.
305
- - **Slide desde arriba para mostrar la barra de pestañas**.
306
-
307
- **Cambiado**
308
-
309
- - Regresión Rev141 corregida: `RESERVED_PYPILOT_KEYS` bloquea
310
- solo publish, no subscribe. El selector de modo del AP vuelve
311
- a poblarse correctamente.
312
- - 6 screenshots actualizados a la UI actual.
313
-
314
- ### Deutsch
315
-
316
- **Neu**
317
-
318
- - Dynamischer Watch-Fokus, entlastet pypilot_web auf dem Pi Zero.
319
- - Sitzungs-Rekorder + Ratschlag-Loop (JSONL pro Engage).
320
- - Pi Zero Log-Capture (persistiert /var/log auf dem Pi 5).
321
- - Klartext-Hilfe pro Gain-Slider.
322
- - Doctor + Alarme in aktiver Sprache.
323
- - Modus-Auswahl uebersetzt in GROSSBUCHSTABEN.
324
- - Doctor: Verwerfen bleibt sichtbar.
325
- - Setup-Kacheln zeigen Live-Status.
326
- - Sensor Quality: Ignorieren pro Zeile.
327
- - Chart: Hover-Freeze + Y-Achse pro Band.
328
- - Tune: ↺ pro Slider + Fork-Dialog.
329
- - Wisch-von-oben blendet Tab-Leiste ein.
330
-
331
- ### Français
332
-
333
- **Nouveautés**
334
-
335
- - Focus d'abonnements dynamique, allege pypilot_web sur le Pi Zero.
336
- - Enregistreur de sessions + boucle de conseils (JSONL par engage).
337
- - Capture des logs Pi Zero sur le Pi 5.
338
- - Aide en clair par slider de gain.
339
- - Doctor et alarmes dans la langue active.
340
- - Selecteur de mode traduit en MAJUSCULES.
341
- - Doctor: bouton Masquer toujours visible.
342
- - Puces de statut vivantes sur chaque tuile Setup.
343
- - Sensor Quality avec Ignorer / Restaurer par ligne.
344
- - Chart: figeage au survol + graduation Y par bande.
345
- - Tune: ↺ par slider + modal de fork de profil.
346
- - Glissement du haut vers le bas pour reafficher la barre d'onglets.
347
-
348
- ## 2.3.0 — 2026-08-31 — Rev130..Rev137
349
-
350
- Feature batch on top of 2.2.x. Themes: make the visor speak the user's
351
- language end-to-end (Doctor findings, alarm banners and TTS voice
352
- included), turn the Setup launcher into an at-a-glance dashboard,
353
- give Tune the same profile-fork discipline the Doctor already had,
354
- and make Sensor Quality something the skipper can silence for
355
- sensors that aren't on this boat.
356
-
357
- ### English
358
-
359
- **Added**
360
-
361
- - **Chart tab — interactive hover** (Rev129) — freeze the auto-refresh
362
- and read the exact value of every band at any point in the history
363
- window by hovering the graph. Y-axis ticks (min / mid / max) now
364
- sit inside the right gutter for each band.
365
- - **Tune tab — per-slider restore + profile fork prompt** (Rev129,
366
- Rev132..Rev134) — every gain slider gets a ↺ button that snaps
367
- back to the frozen baseline captured when you unlocked the panel.
368
- On the first change of an unlock session a modal asks whether to
369
- keep the tweaks in the current profile, save them in a new
370
- `tune-YYYYMMDD-HHMM` fork (mirroring the Doctor pattern), or
371
- Cancel and revert the change entirely.
372
- - **Setup launcher — live status chips on every tile** (Rev130..Rev135)
373
- — Pypilot Connection shows `host:port`, Language shows the active
374
- locale, Calibration shows the timestamp of the last slider
375
- adjustment (with a `Reset historial` button on the card), Signal K
376
- Sentences shows the count of published SK paths out of the plugin
377
- catalog total, and Remote Control Console reports whether SSH
378
- creds are stored.
379
- - **Sensor Quality — per-row Ignore / Restore** (Rev134..Rev135) —
380
- the chip now also counts "missing" sensors (a watched path that
381
- has never emitted a delta) into the failure tally, and each row
382
- gains an Ignore / Restore button so a sensor you don't have on
383
- this boat (rudder without a rudder feedback, temp probe absent,
384
- ...) stops turning the chip red. Persisted per-browser.
385
- - **Nav bar slide-down gesture** (Rev129) — the counterpart to the
386
- existing slide-up hide; drag from the top of the visor to bring
387
- the tab bar back.
388
- - **Doctor — Hide button always visible + i18n findings**
389
- (Rev135..Rev136) — the Descartar / Ocultar button stays visible
390
- even after a suggestion has been applied so you can clear stale
391
- advice from the list. Hidden suggestions also drop off the tile
392
- chip's counter so the card goes back to `sano` once you've cleared
393
- everything. Backend now emits i18n keys + args for findings and
394
- summary so the whole Doctor panel reads in the active language.
395
- - **Alarm engine i18n** (Rev135..Rev136) — the seven built-in alarm
396
- rules (heading-deviation, unable-to-steer, servo-overcurrent,
397
- servo-temp-high, low-voltage, sensor-lost, pypilot-disconnected)
398
- now render banners and speak the message in the active language
399
- (EN / ES / DE / FR). The backend still publishes the English
400
- notification message on `notifications.autopilot.*` for
401
- KIP / WilhelmSK compatibility.
402
- - **Info tab — English classic-UI link fix** (Rev129) — the
403
- hardcoded Spanish string "Interfaz clasica pypilot" that leaked
404
- into every language moved to a proper i18n key with `{host}` /
405
- `{port}` interpolation.
406
- - **Remote Control Console — TinyPilot defaults** (Rev136) — the
407
- tile no longer wears its emergency red frame; the SSH user field
408
- is pre-filled with the TinyPilot default (`tc`) and a hint spells
409
- out that the default password is `tc` too, so the setup is a
410
- two-click job on a stock TinyPilot.
411
- - **Better DE / FR coverage** (Rev134..Rev136) — Setup tile titles,
412
- calibration strings, Tune fork modal, chip labels, Doctor summary
413
- / findings and alarm messages now translate in Deutsch and
414
- Français instead of falling back to English.
415
-
416
- **Changed**
417
-
418
- - **All six screenshots refreshed** to match the current UI
419
- (Control rose with the Gota Chain arrow layout, Chart Trip Stats,
420
- Tune with per-slider reset, Setup launcher chips, Race timer,
421
- Info panel).
422
-
423
- ### Español
424
-
425
- **Añadido**
426
-
427
- - **Chart — cursor sobre gráficas** — al pasar el dedo o el ratón
428
- sobre una gráfica se congela el refresh y aparece una línea
429
- vertical + tooltip con `-X.Xs` y el valor de cada banda en ese
430
- punto. Escala Y (min / mid / max) por banda en el margen derecho.
431
- - **Tune — botón ↺ por slider + prompt de perfil** — cada gain trae
432
- un ↺ que vuelve al valor previo (el que había al desbloquear). El
433
- primer cambio tras unlock lanza un modal preguntando si guardar
434
- en el perfil actual, crear un nuevo `tune-YYYYMMDD-HHMM` (mismo
435
- patrón que Doctor) o cancelar y revertir.
436
- - **Setup — chips vivos en cada tile** — TinyPilot con host:port,
437
- idioma actual, fecha del último ajuste de calibración (con botón
438
- Reset historial), contador de sentencias SK publicadas frente al
439
- total del catálogo del plugin, y aviso de SSH configurado en
440
- Remote Control Console.
441
- - **Sensor Quality — Ignorar / Restaurar por fila** — los sensores
442
- que nunca han reportado también cuentan en el ✕, y cada fila con
443
- problema tiene ahora un botón Ignorar (persistente en el
444
- navegador) para no volver a teñir el chip por un sensor que no
445
- hay en el barco.
446
- - **Slide desde arriba para mostrar la barra de pestañas** — vuelta
447
- atrás del slide hacia arriba que ya escondía la nav.
448
- - **Doctor — botón Ocultar siempre + findings traducidos** — se
449
- puede vaciar la lista de sugerencias aunque ya las hubieras
450
- aplicado, y el chip del tile vuelve a "sano" cuando no queda
451
- ninguna. Backend emite ahora claves i18n para findings y summary.
452
- - **Alarmas en tu idioma** — las siete reglas (desvío de rumbo,
453
- autoridad, servo, temperatura, tensión, sensor perdido,
454
- desconexión pypilot) se muestran y se hablan en el idioma activo.
455
- Al SK sigue viajando el mensaje en inglés para compatibilidad con
456
- KIP / WilhelmSK.
457
- - **Info EN sin fugas al ES** — el "Interfaz clásica pypilot" que
458
- se colaba en cualquier idioma pasó a clave i18n.
459
- - **Remote Console con defaults TinyPilot** — sin borde rojo,
460
- usuario `tc` pre-cargado y aviso de que la contraseña por defecto
461
- también es `tc`.
462
- - **Mejor cobertura DE / FR** en todos los strings visibles del
463
- Setup, Tune, Doctor y alarmas.
464
-
465
- **Cambiado**
466
-
467
- - **6 screenshots** actualizados a la UI actual.
468
-
469
- ### Deutsch
470
-
471
- **Neu**
472
-
473
- - Chart mit Hover-Freeze und Y-Achse pro Band.
474
- - Tune-Slider mit ↺ und Profil-Fork-Dialog (Cancel setzt zurueck).
475
- - Setup-Kacheln zeigen Live-Status (Host, Sprache,
476
- Kalibrierdatum, aktive SK-Saetze, SSH konfiguriert).
477
- - Sensor Quality mit "missing" im Chip-Zaehler und einer
478
- Ignore / Restore-Taste pro Zeile.
479
- - Slide von oben zeigt die Tab-Leiste wieder.
480
- - Doctor: Ausblenden-Taste bleibt sichtbar, Findings und Summary
481
- jetzt uebersetzt.
482
- - Alarm-Meldungen und Sprachausgabe in der aktiven Sprache.
483
- - Remote-Konsole ohne roten Rahmen; `tc` als Standard-Login.
484
- - Erweiterte DE-Uebersetzungen.
485
-
486
- ### Français
487
-
488
- **Nouveautés**
489
-
490
- - Onglet Chart avec figeage au survol et graduation Y par bande.
491
- - Onglet Tune avec bouton ↺ par slider et modal de fork de profil
492
- (Annuler revient a la valeur d'origine).
493
- - Grille Setup avec puces d'etat vivantes (hote, langue, dernier
494
- ajustement de calibration, phrases SK actives, SSH configure).
495
- - Sensor Quality avec "missing" dans le compteur et un bouton
496
- Ignorer / Restaurer par ligne.
497
- - Glissement du haut vers le bas pour reafficher la barre
498
- d'onglets.
499
- - Doctor: bouton Masquer toujours visible, findings et resume
500
- traduits.
501
- - Alarmes et voix TTS dans la langue active.
502
- - Console distante sans cadre rouge; `tc` par defaut.
503
- - Traductions FR etendues.
504
-
505
- ## 2.2.1 — 2026-08-31 — Rev128
506
-
507
- Docs-only patch release.
508
-
509
- - **README** — embedded the four App Store screenshots as absolute
510
- `raw.githubusercontent.com` URLs so they render both on the NPM
511
- website (which only surfaces the README, not `signalk.screenshots[]`)
512
- and inside any other viewer that follows the README markdown. The
513
- registry serves the README frozen at publish time, so this bump is
514
- the only way to get the updated README to `npmjs.com/package/signalk-pypilot-newui`.
515
-
516
- ## 2.2.0 — 2026-08-31 — Rev88..Rev127
517
-
518
- Forty in-session Revs of navigation-oriented features on top of the
519
- 2.1.0 visual foundation. Themes: turn the plugin into an intelligence
520
- layer over pypilot (historian → KPIs → alarms → Doctor → pre-departure
521
- check), give sail-raising its own AP mode ("Aproado"), and rebuild the
522
- Setup tab as an app-launcher grid of fullscreen tiles.
523
-
524
- ### English
525
-
526
- **Added**
527
-
528
- - **Aproado pseudo-mode** (Rev87-92) — a new "raise the sails"
529
- autopilot mode not in pypilot upstream. Pick BY BOW / BY STERN
530
- via a 5 s modal, the plugin switches pypilot to wind mode with
531
- target 0° (head to wind), and a floating HUD over the boat shows
532
- elapsed time, straight-line distance from the start and the
533
- compass heading captured at activation. SALIR restores the
534
- previous mode + target + engaged state. The BY STERN branch
535
- forces a stern-through swing by walking a chain of intermediate
536
- targets 60° apart so pypilot cannot shortcut through the bow.
537
- - **Telemetry historian + Chart tab** (Rev93-96) — RAM ring buffer
538
- at 1 Hz for the last 30 min (backend, Pi 5 friendly). New Chart
539
- tab shows nine Trip Stats cards (AP engaged time, distance,
540
- energy, mean/RMS/p95 heading error, servo runtime, tacks/gybes,
541
- peak servo A) all fed live via SK paths, plus a canvas history
542
- with 30 s / 2 min / 10 min windows and per-path chips.
543
- - **Sensor Quality panel** (Rev97-98) — age / observed Hz / jitter /
544
- source for every critical SK path the AP depends on, with a
545
- green / amber / red pill. Endpoint `/quality` and a poll while
546
- Setup is visible.
547
- - **Servo Health card** (Rev99) — baseline current learned from
548
- the first ~10 min of engaged navigation, then a live deviation
549
- ratio flags "elevated" (>1.20×) or "high" (>1.65×) — early
550
- warning for a hard rudder, fouling, or a stiffened linkage. Six
551
- new SK paths under `steering.autopilot.pypilot.servo.health.*`.
552
- - **Alarm engine** (Rev100-101) — seven built-in rules (heading
553
- deviation, unable to steer, servo overcurrent / temp, low
554
- voltage, sensor lost, pypilot disconnected) publishing
555
- canonical SK notifications `notifications.autopilot.*`. Sticky
556
- banner in the visor with ACK + close, WebAudio beeps +
557
- speech-synthesis of the message, and a full config panel in
558
- Setup (enable / mute / status per rule).
559
- - **Pre-departure check** (Rev102) — a single verdict card
560
- (READY / READY-WITH-CAVEATS / DO-NOT-ENGAGE) that aggregates
561
- connectivity, sensor quality, servo health and voltage into one
562
- answer before you leave the dock.
563
- - **Pypilot Doctor** (Rev103-104, Rev120-121) — press DIAGNOSE,
564
- the plugin records 2-3 min with the AP engaged, runs heuristic
565
- rules on the heading error stream (bias / oscillation / low
566
- authority) and proposes P / I / D adjustments with a plain
567
- explanation of why and what to expect. Nothing is applied
568
- automatically — each suggestion has Apply and Discard buttons.
569
- Rev120: the first Apply of a session forks the current pypilot
570
- profile into a new `doctor-YYYYMMDD-HHMM` profile so the
571
- previous gains stay one profile-select away.
572
- - **Setup as a launcher grid** (Rev105-119, 124) — every setup
573
- block is now a square tile in a 2 / 3 / 4-column grid. Tap
574
- opens fullscreen with a small X to close and ESC support.
575
- Body scroll is locked while a tile is fullscreen. Live summary
576
- pill on every tile so the state reads at a glance without
577
- expanding. Connection consolidated (status + LAN scan + manual
578
- host + Autopilot Provider in one card). "Emergency" renamed to
579
- "Remote Control Console".
580
- - **Interactive SSH console** (Rev113-115) — free-form command
581
- input with on-screen arrow buttons for mobile history
582
- navigation, accumulative output textarea, clipboard fallback
583
- for HTTP LAN, and 14 preset buttons with plain human labels
584
- (Memory / IP table / WiFi / Temperature / Who is connected /
585
- ...). BusyBox / piCore-safe fallbacks for every command.
586
- - **Full RangeSetting sliders in Calibration** (Rev116-119) —
587
- every pypilot `RangeSetting` grouped by category (rudder /
588
- servo / imu / ap / other) with the same look as the Tune tab,
589
- a lock checkbox with the padlock emoji, a frozen "before:"
590
- baseline that never moves as you drag, and a per-slider ↺
591
- restore button that snaps back to the baseline.
592
- - **Nudge steps moved inside Calibration** (Rev124) — one card
593
- less in the launcher grid; heading trim buttons live where
594
- they belong conceptually.
595
-
596
- **Changed**
597
-
598
- - **Gota Chain shapes SWAP** (Rev122-126) — after several iterations
599
- with Carlos on Tunatunes: the AMBER "A" arrow (apparent wind) is
600
- now the LARGE piece (its tip reaches deep into the rose), and
601
- the TEAL "T" arrow (true wind) is the SMALL outer one. Colors
602
- and letters kept their canonical meaning; only the SVG paths
603
- moved so the amber piece is visually the dominant one.
604
- - **Alarm summary semantics** (Rev107-108) — "activa" (fired) was
605
- ambiguous with "activada" (enabled). New wording separates
606
- `firing / sonando` (fired now) from `watching / vigilando`
607
- (enabled and healthy). Summary always shows both counts.
608
- - **i18n audit** (Rev105, Rev112, Rev121) — every hard-coded
609
- English string in the ES bundle purged ("engagear" → "activar",
610
- KIP paths table fully translated, alarm messages), backend
611
- suggestion reason / effect exposed as i18n keys + args so the
612
- frontend renders in the user's language.
613
- - **Sensor Quality thresholds** (Rev98) — dropped `minHz` from the
614
- defaults; the 1 Hz sampler capped observed Hz, so the threshold
615
- produced spurious "degraded" flags. Freshness (`age`) is now
616
- the only signal that penalises status.
617
-
618
- **Fixed**
619
-
620
- - **Fullscreen tile portal** (Rev110-111) — Setup fullscreen tiles
621
- are now portaled to `<body>` so the `.tab-panel` transform
622
- (used by the tab animation) cannot break `position: fixed`.
623
- Fullscreen always covers the viewport now, no matter which
624
- card was scrolled into.
625
- - **Copy button on HTTP** (Rev114) — `navigator.clipboard` is a
626
- secure-context API; on plain http://192.168.x.y it silently
627
- no-ops. Compat helper falls back to `document.execCommand("copy")`.
628
- - **Doctor `elapsedSec`** (Rev104) — was counting past the target
629
- duration once the session completed. Now freezes at the target.
630
- - **Sliders baseline eaten by refresh** (Rev117-118) — the
631
- Calibration "before:" value used to reset to the just-edited
632
- number on every `/values` poll. Now captured once per name and
633
- kept frozen across renders.
634
- - **Aproado restore** (Rev90) — mode / target / engaged restore on
635
- SALIR was skipping steps after one failure. Now each step is
636
- guarded independently and logged in the console.
637
- - **Sensor Quality parsing** (Rev94) — `navigation.attitude` is a
638
- composite `{pitch, roll, yaw}` object, not a scalar path.
639
- Custom subfield reader added for heel.
640
- - Cosmetic Firefox warnings (`::-moz-focus-inner`, comment-nested
641
- `*/`) purged (Rev95-106).
3
+ ## 2.7.1 — 2026-09-14
4
+
5
+ Sea-trial release. Big reliability upgrade after intensive on-water
6
+ testing on Tunatunes.
7
+
8
+ ### New features
9
+
10
+ - **Trip Recorder** — every outing is auto-recorded via
11
+ `navigation.state`. Setup → Trips shows 17 KPIs, an OpenSeaMap
12
+ trace coloured by SOG with markers on peak gust, peak SOG, min
13
+ voltage and every detected tack, and lets you share the outing as
14
+ a portrait PNG report card or as WhatsApp text.
15
+ - **Reconnect Restore banner** — when the link with pypilot dies
16
+ while the AP is engaged, the visor takes a snapshot of your target
17
+ and mode. If the link is back between 20 s and 5 min later, a
18
+ Yes / No banner offers to re-engage the same target. Success is
19
+ announced only after pypilot actually confirms.
20
+ - **Watchdog with core-alive detection** — the visor now
21
+ distinguishes a live `pypilot_web` with a dead pypilot core. AP
22
+ controls grey out, the "pypilot disconnected for N seconds" voice
23
+ alert fires, and the green "pypilot operational" toast greets you
24
+ when the core is really back.
25
+ - **Faster offline / online detection** — dead-pypilot detection
26
+ improved from ~10-14 s to ~5-6 s; reconnect detection improved
27
+ from ~4-8 s to ~1-3 s.
28
+ - **Persistent Tack history** — every tack stored on the device
29
+ with pre / post TWS, AWA, SOG and recovery time to 95% of pre-tack
30
+ speed. Filter by day range with best retention and fastest
31
+ recovery highlighted.
32
+ - **Gust marker overlay** — leaves a ghost `A` arrow at the peak
33
+ wind speed for 10 s.
34
+ - **Bottom bar rudder-or-heel switch** — the big-number bar on the
35
+ Control tab can show rudder angle or boat heel.
36
+ - **Concentric Target + Wind arrows** — three arrow pieces on the
37
+ rose interlock into a droplet when target ≡ AWA ≡ TWA; open into
38
+ V-notches with a colour tick when they drift. (Feature previously
39
+ called "Gota Chain", renamed for clarity.)
40
+ - **Full instructions inside the Info modal** — new section that
41
+ walks through every tab and gesture, in English and Spanish.
42
+ - **Global `allowWrites` gate** — the plugin's HTTP routes, the
43
+ Autopilot API v2 provider and the KIP action / switch handlers
44
+ all honour the same toggle. A read-only install is really
45
+ read-only from every angle.
46
+
47
+ ### Critical bug fixes
48
+
49
+ - **Silent success on offline writes** — writes to a dead pypilot
50
+ socket used to silently report success, so the visor could claim
51
+ the AP was engaged while the boat drifted. Writes now confirm
52
+ end-to-end before the UI accepts them.
53
+ - **Phantom AP re-enable after reconnect** — a stale engage retry
54
+ could re-enable the AP after you had explicitly disengaged. Fixed
55
+ with a generation counter that cancels superseded orders.
56
+ - **False "healthy" with a dead pypilot core** — a live
57
+ `pypilot_web` pong used to keep the "healthy" flag on even when
58
+ pypilot itself was dead. A sticky core-offline flag now blocks
59
+ writes and greys the UI until real evidence from the core arrives.
60
+ - **Restore banner announced "restored" before pypilot confirmed**
61
+ — the visor used to speak success on the HTTP 200 alone, seconds
62
+ before spotting that pypilot never actually engaged.
63
+ - **Spanish leaking into English mode** — several dynamic strings
64
+ (Trip card, Tack log, menus, WhatsApp caption) rendered in Spanish
65
+ regardless of the active language.
66
+
67
+ Many small bugs also fixed across the visor, autopilot provider and
68
+ Signal K integration.
69
+
70
+ ## 2.7.0 — 2026-09-14 — Superseded by 2.7.1
71
+
72
+ Same feature set and code as 2.7.1. Release notes were rewritten in
73
+ 2.7.1 in user-facing language.
74
+
75
+ ## 2.6.0 — 2026-09-10 — Trip Report first cut
76
+
77
+ First cut of the Trip Recorder (auto-record via `navigation.state`,
78
+ 17-KPI grid, OpenSeaMap trace, PNG report card, WhatsApp share).
79
+ Gust marker and gust strategy tuning. Reload-race fix so gain and
80
+ calibration sliders always reflect real pypilot values.
81
+
82
+ ## 2.5.2 — 2026-09-10 — Session-recorder containment
83
+
84
+ Contains a rebound bug that opened one JSONL file per engage
85
+ flicker: 8 s engaged-debounce, short-session discard on close, plus
86
+ bounce diagnostics exposed on `/session-recorder/status`.
642
87
 
643
- ### Español
644
-
645
- **Nuevo**
646
-
647
- - **Modo Aproado** (Rev87-92): pseudo-modo AP para subir velas.
648
- Elige POR PROA / POR POPA en un modal de 5 s, el plugin pasa
649
- pypilot a modo viento con objetivo 0° (proa al viento), y un
650
- HUD flotante sobre el barco muestra tiempo transcurrido,
651
- distancia lineal desde el arranque y el rumbo compás capturado
652
- al activar. SALIR restaura modo + objetivo + engaged previos.
653
- POR POPA fuerza el swing por popa con una cadena de objetivos
654
- intermedios cada 60° para que pypilot no atajaje por proa.
655
- - **Historian de telemetría + pestaña Gráfica** (Rev93-96):
656
- buffer circular en RAM a 1 Hz durante 30 min (backend, Pi 5).
657
- Nueva pestaña Gráfica con 9 tarjetas de estadísticas de sesión
658
- (tiempo activo, distancia, energía, error medio / RMS / p95,
659
- servo activo, viradas / trasluchadas, pico servo A) y canvas
660
- con ventanas 30 s / 2 min / 10 min.
661
- - **Panel Calidad de sensores** (Rev97-98): edad / Hz / jitter /
662
- fuente por cada ruta SK crítica con semáforo verde / ámbar /
663
- rojo.
664
- - **Tarjeta Salud del servo** (Rev99): baseline aprendido de los
665
- primeros ~10 min de navegación activa, luego ratio de
666
- desviación marca "elevated" (>1.20×) o "high" (>1.65×) —
667
- alerta temprana de timón duro, incrustaciones o rozamientos.
668
- - **Motor de alarmas** (Rev100-101): 7 reglas built-in
669
- (desviación de rumbo, incapaz de gobernar, sobrecorriente
670
- servo, temperatura servo, batería baja, sensor perdido,
671
- pypilot desconectado) publicando notifications SK canónicas.
672
- Banner sticky en el visor con ACK y cierre X, beeps WebAudio
673
- + speechSynthesis del mensaje, panel de configuración en
674
- Setup (enable / mute / estado por regla).
675
- - **Comprobación del piloto** (Rev102): tarjeta única con
676
- veredicto (LISTO / LISTO CON RESERVAS / NO ACTIVAR) que
677
- agrega conectividad, calidad de sensores, salud del servo y
678
- voltaje.
679
- - **Asesoramiento y diagnóstico** (Rev103-104, Rev120-121):
680
- botón DIAGNOSTICAR, el plugin graba 2-3 min con el AP activo,
681
- aplica reglas heurísticas (sesgo / oscilación / autoridad) y
682
- propone ajustes P / I / D con explicación clara del porqué y
683
- del efecto esperado. Nada se aplica automáticamente — cada
684
- sugerencia tiene botones Aplicar y Descartar. Rev120: el
685
- primer Aplicar de la sesión duplica el perfil actual en uno
686
- nuevo `doctor-AAAAMMDD-HHMM` para que el original quede
687
- intacto a un toque en Ajustes → Perfil.
688
- - **Setup como launcher grid** (Rev105-119, 124): cada bloque
689
- de Setup es un tile cuadrado en un grid 2 / 3 / 4 columnas.
690
- Tap abre pantalla completa con X para cerrar, header sticky
691
- y bloqueo de scroll de fondo. Etiqueta resumen en vivo en
692
- cada tile. Conexión pypilot une 4 secciones. "Emergencia"
693
- renombrada a "Consola control remoto".
694
- - **Consola SSH interactiva** (Rev113-115): input libre con
695
- botones ↑▲ ↓▼ para navegar el historial en móvil, textarea
696
- acumulativo, fallback de portapapeles para LAN HTTP y 14
697
- presets con etiquetas humanas (Memoria RAM / Tabla IP / WiFi
698
- / Temperatura / Quien está conectado / ...). Todos los
699
- comandos con fallbacks BusyBox / piCore.
700
- - **Sliders completos de calibración** (Rev116-119): todos los
701
- `RangeSetting` de pypilot agrupados por categoría (timón /
702
- servo / imu / piloto / otros) con la misma apariencia que
703
- Ajustes, candado azul con emoji, valor "antes:" congelado
704
- que NUNCA se mueve al arrastrar, y un botón ↺ por slider
705
- para restaurar el valor original.
706
- - **Botones corrección rumbo dentro de Calibración** (Rev124):
707
- una tarjeta menos en el grid; los pasos ±1 / ±10 quedan
708
- donde corresponde conceptualmente.
709
-
710
- **Cambiado**
711
-
712
- - **Swap de formas en la Gota Chain** (Rev122-126): tras varias
713
- iteraciones con Carlos en Tunatunes, la flecha AMARILLA "A"
714
- (viento aparente) es ahora la GRANDE (su punta llega hasta
715
- el centro de la rosa) y la flecha VERDE "T" (viento real)
716
- es la PEQUEÑA externa. Colores y letras mantienen su
717
- significado canónico; solo se movieron los paths SVG para
718
- que la amarilla domine visualmente.
719
- - **Semántica de alarmas** (Rev107-108): "activa" era ambiguo.
720
- Nueva jerga separa `sonando` (disparada ahora) de `vigilando`
721
- (habilitada y OK). El resumen muestra siempre ambos contadores.
722
- - **Auditoría i18n** (Rev105, Rev112, Rev121): purga de cadenas
723
- inglesas hardcoded en el bundle ES ("engagear" → "activar",
724
- tabla de KIP totalmente traducida, mensajes de alarma).
725
- Reason / effect de las sugerencias del Doctor expuestos como
726
- claves i18n para render en el idioma del visor.
727
- - **Umbrales Calidad de sensores** (Rev98): quitado `minHz` de
728
- los defaults; el sampler a 1 Hz capaba la Hz observada y
729
- generaba "degraded" falsos.
730
-
731
- **Corregido**
732
-
733
- - **Portal de tile fullscreen** (Rev110-111): tiles fullscreen
734
- ahora se mueven al `<body>` para que el `transform` de
735
- `.tab-panel` (animación entre pestañas) no rompa `position:
736
- fixed`.
737
- - **Botón Copiar en HTTP** (Rev114): `navigator.clipboard`
738
- requiere secure context. Fallback a `document.execCommand("copy")`.
739
- - **Doctor `elapsedSec`** (Rev104): contaba pasado el objetivo.
740
- Ahora congela al final.
741
- - **Baseline de sliders comido por refresh** (Rev117-118): el
742
- valor "antes" se reseteaba a lo recién editado en cada poll.
743
- Ahora se captura una vez y no se toca.
744
- - **Restore de Aproado** (Rev90): SALIR saltaba pasos tras un
745
- fallo. Ahora cada paso protegido por su try/catch.
746
- - **Parsing Calidad de sensores** (Rev94): `navigation.attitude`
747
- es objeto compuesto, no path escalar. Fix del subfield heel.
748
- - Warnings cosméticos Firefox (`::-moz-focus-inner`, `*/` en
749
- comentarios) purgados (Rev95-106).
750
-
751
- ### Français
752
-
753
- **Ajouté**
754
-
755
- - **Mode Aproado** (Rev87-92) : pseudo-mode AP pour hisser les
756
- voiles. PAR AVANT / PAR ARRIÈRE, l'AP passe en mode vent avec
757
- cible 0° (nez au vent), HUD flottant avec temps, distance et
758
- cap boussole capturé. SORTIR restaure mode / cible / engagé
759
- précédents. PAR ARRIÈRE force le virage par l'arrière avec
760
- une chaîne d'objectifs intermédiaires de 60°.
761
- - **Historian de télémétrie + onglet Graphique** (Rev93-96) :
762
- buffer 30 min en RAM à 1 Hz, canvas d'historique et 9 cartes
763
- Trip Stats.
764
- - **Panneau Qualité des capteurs** (Rev97-98) : âge / Hz /
765
- jitter / source par chaque chemin SK critique.
766
- - **Carte Santé du servo** (Rev99) : baseline appris + ratio de
767
- déviation avec alertes "elevated" et "high".
768
- - **Moteur d'alarmes** (Rev100-101) : 7 règles built-in,
769
- notifications SK canoniques, banner avec ACK et fermeture,
770
- audio WebAudio + parole synthétique, config par règle.
771
- - **Vérification pré-départ** (Rev102) : verdict READY / avec
772
- caveats / NE PAS ENGAGER.
773
- - **Docteur pypilot** (Rev103-104, Rev120-121) : 2-3 min
774
- d'enregistrement, règles heuristiques, propositions P / I / D
775
- avec Appliquer et Rejeter. Le premier Appliquer crée un
776
- nouveau profil `doctor-AAAAMMJJ-HHMM`.
777
- - **Setup en grille launcher** (Rev105-119, 124) : tiles carrés,
778
- fullscreen par tap, résumé en direct, connexion consolidée,
779
- "Consola contrôle remote" (renommé).
780
- - **Console SSH interactive** (Rev113-115) : entrée libre,
781
- historique navigable au mobile, 14 presets aux noms humains,
782
- fallbacks BusyBox / piCore.
783
- - **Sliders complets de calibration** (Rev116-119) : chaque
784
- RangeSetting groupé, cadenas, baseline gelée, bouton restaurer.
785
- - **Boutons correction cap dans Calibration** (Rev124).
786
-
787
- **Modifié**
788
-
789
- - **Swap des formes Gota Chain** (Rev122-126) : la flèche AMBRE
790
- "A" (vent apparent) est maintenant la GRANDE, la TEAL "T"
791
- (vent réel) la petite. Couleurs et lettres conservent leur
792
- sens canonique.
793
- - **Sémantique alarmes** (Rev107-108) : `sonando` vs
794
- `vigilando`, résumé affiche les deux compteurs.
795
- - **Audit i18n** (Rev105, Rev112, Rev121) : purge de l'anglais
796
- dans les bundles ES / FR / DE.
797
- - **Seuils Qualité capteurs** (Rev98) : `minHz` supprimé.
798
-
799
- **Corrigé**
800
-
801
- - Portal du tile fullscreen (Rev110-111).
802
- - Bouton Copier en HTTP (Rev114).
803
- - Doctor `elapsedSec` gelé au final (Rev104).
804
- - Baseline des sliders congelée (Rev117-118).
805
- - Restore Aproado protégé par try/catch (Rev90).
806
- - Lecture composite de `navigation.attitude` (Rev94).
807
- - Warnings cosmétiques Firefox purgés (Rev95-106).
808
-
809
- ### Deutsch
810
-
811
- **Neu**
812
-
813
- - **Aproado-Pseudomodus** (Rev87-92) — AP-Modus zum Segelhissen.
814
- ÜBER BUG / ÜBER HECK, AP schaltet in Wind-Modus mit Ziel 0°,
815
- HUD über dem Boot mit Zeit / Distanz / Kompass-Kurs. AUS
816
- stellt Modus / Ziel / Engaged wieder her. ÜBER HECK erzwingt
817
- den langen Schwenk mit Zwischen-Zielen alle 60°.
818
- - **Telemetrie-Historian + Chart-Tab** (Rev93-96) — Ringpuffer
819
- 30 min RAM bei 1 Hz, 9 Trip-Stats-Karten, Canvas mit Fenstern
820
- 30 s / 2 min / 10 min.
821
- - **Sensor-Qualität-Panel** (Rev97-98).
822
- - **Servo-Health-Karte** (Rev99) — gelernter Baseline mit
823
- Alarmen "elevated" / "high".
824
- - **Alarm-Engine** (Rev100-101) — 7 built-in Regeln, SK
825
- Notifications, Banner mit ACK und X, WebAudio + Sprache,
826
- Config-Panel.
827
- - **Pre-Departure-Check** (Rev102).
828
- - **Pypilot Doctor** (Rev103-104, Rev120-121) — Diagnose-
829
- Sitzung, Heuristik-Regeln, P/I/D-Vorschläge mit Anwenden /
830
- Verwerfen. Erstes Anwenden erzeugt neues Profil.
831
- - **Setup als Launcher-Grid** (Rev105-119, 124) — quadratische
832
- Tiles, Vollbild-Tap, Live-Zusammenfassung.
833
- - **Interaktive SSH-Konsole** (Rev113-115) — freie Eingabe,
834
- Pfeil-Buttons mobil, 14 Presets mit menschlichen Labels.
835
- - **Vollständige RangeSetting-Slider in Kalibrierung**
836
- (Rev116-119) — Schloss, eingefrorene Baseline,
837
- Wiederherstellen-Knopf pro Slider.
838
- - **Nudge-Buttons in Kalibrierung** (Rev124).
839
-
840
- **Geändert**
841
-
842
- - **Gota-Chain-Form-SWAP** (Rev122-126).
843
- - **Alarm-Semantik** (Rev107-108) — `sonando` / `vigilando`.
844
- - **i18n-Audit** (Rev105, Rev112, Rev121).
845
- - **Sensor-Qualität-Schwellen** (Rev98) — `minHz` entfernt.
846
-
847
- **Behoben**
848
-
849
- - Fullscreen-Tile-Portal (Rev110-111).
850
- - Copy-Button auf HTTP (Rev114).
851
- - Doctor `elapsedSec` (Rev104).
852
- - Slider-Baseline eingefroren (Rev117-118).
853
- - Aproado-Restore geschützt (Rev90).
854
- - `navigation.attitude`-Zusammensetzung (Rev94).
855
- - Kosmetische Firefox-Warnungen (Rev95-106).
856
-
857
- ## 2.1.0 — 2026-08-25 — Rev68..Rev87
858
-
859
- Twenty in-session Revs of iterative visual + reliability work rolled up
860
- into a proper minor release. Themes: a full redesign of the compass-rose
861
- autopilot overlays ("Gota Chain"), a hard-earned fix for AP mutations
862
- racing each other across the SignalK bus, and a permanent seamless-auth
863
- story so a Signal K restart never again silently disables the visor's
864
- mutation buttons.
865
-
866
- ### Added
867
-
868
- - **Gota Chain overlay** — the target diamond and the AWA/TWA wind
869
- arrows are now three concentric SVG pieces that interlock into one
870
- clean droplet when `target ≡ AWA ≡ TWA`. Each piece carries its own
871
- letter (A / T) and its own color ring-tick that marks the exact
872
- angle on the compass. When any of the three drifts, its V-hembra
873
- opens as a visible hollow. Iterated over 12 Revs (Rev68..Rev82)
874
- with Carlos on Tunatunes.
875
- - **COG line** — chain of yellow chevrons from the bow toward the
876
- course-over-ground direction. Visible only when `SOG > 0.15 kn`.
877
- - **Current vector** — two parallel wavy blue lines with three
878
- triangles pointing at the boat. Computed as `SOG − SOW` (added
879
- new `navigation.speedThroughWater` subscription). Visible when
880
- `|current| > 0.2 kn`.
881
- - **4-card overlay selector** — long-press any rose corner OR the
882
- boat sprite to open the popup with the four toggle cards (AWA,
883
- TWA, COG, Current), each with a large preview and a data-
884
- requirement line ("Needs a wind sensor", "Only shows when SOG >
885
- 0.15 kn", etc). Toggles persist in `localStorage`.
886
- - **Rose cardinals colour-coded**: N orange, E green, S blue, W red.
887
- All at the same radius `r = 70`. Thin black stroke around each
888
- letter for legibility on any background.
889
- - **Seamless auth via SK Access Request** — the visor now uses a
890
- device-scoped, permanent SK token instead of a short-lived JWT.
891
- On first install the user approves once from `SK admin → Security
892
- → Access Requests`; from then on the token survives every SK
893
- server restart, every plugin redeploy, and every browser reload,
894
- so mutations (engage / mode / target) NEVER silently 401 again.
895
- - **`.\deploy.ps1 -FrontOnly`** — new script flag that syncs
896
- `public/` only (no build, no npm install, no `systemctl restart
897
- signalk`). Use it when the diff is HTML / CSS / JS only —
898
- `Ctrl+F5` in the browser picks it up. Avoids the plugin-socket
899
- reconnect to `pypilot_web` on the Pi Zero W that pushed the
900
- TinyPilot to hang after a big batch of deploys.
901
-
902
- ### Fixed
903
-
904
- - **AP mutation race (`DIA jumps to a stale target for a beat`).**
905
- Frontend used to `Promise.all([engage, target])` and the backend's
906
- `pushAutopilotUpdate` published ALL SK autopilot fields on every
907
- notify — so whichever POST landed first emitted a delta that
908
- carried the OTHER field's STALE value (typically an old target
909
- from the previous session, e.g. `115°` when the intent was `75°`).
910
- Fixed by refactoring `AutopilotProvider.notifyChanged(fields)` to
911
- accept `"engaged" | "target" | "all"` and `pushAutopilotUpdate` to
912
- only emit the paths that actually changed. Parallel POSTs no
913
- longer clobber each other with stale copies.
914
- - **Wind-mode target capture on engage.** `doEngage` always sent
915
- `state.heading` as the target regardless of mode; pypilot in wind
916
- mode interpreted that compass value as a wind angle and steered
917
- the boat toward nonsense. Now captures `state.windAngle` (apparent)
918
- or `state.windAngleTrue` (true wind) when the active mode contains
919
- "wind"; falls back to heading only for compass / gps / nav.
920
- - **AP button "click missed" and engage / disengage bounce**
921
- hardened: switched from `click` to `pointerdown` (fires once per
922
- press on both touch and mouse without waiting for the
923
- browser-synthesised `click`), swallow the trailing `click` with
924
- `preventDefault + stopPropagation`, `touch-action: manipulation`
925
- on the button, plus an 800 ms cooldown gate that survives the
926
- ~200 ms POST round-trip. Ghost taps from `touchend` no longer
927
- produce a phantom second engage.
928
- - **Wind speed chip tap regressions.** Chip was picked up by the
929
- corner-selector `forEach` (auto-attached its 500 ms long-press
930
- timer → opened the wrong popup) AND the `<main>` tab-swipe
931
- handler treated any tap-with-drift on it as a horizontal swipe
932
- → the chip appeared to slide right. Renamed the chip class to
933
- `.wind-chip` so the forEach ignores it and replaced the shared
934
- handler with a bespoke `pointerdown/up` short-tap detector that
935
- stops touch propagation.
936
- - **HDG chip / compass labels covered by DIA** on engage: reordered
937
- the SVG stack so the compass card and HDG chip render AFTER the
938
- gota pieces, never behind them.
939
- - **DIA arc rendering asymmetry** ("bump on one side") when
940
- rotated: `stroke-linejoin` switched from `round` to `miter`,
941
- raya `stroke-linecap` switched from `round` to `butt` to remove
942
- the semi-circle that overshot the ring line.
943
-
944
- ### Changed
945
-
946
- - **Wind speed chip moved from an SVG group to a positioned HTML
947
- `.wind-chip` div** overlaid on the rose bottom-center. Text
948
- baseline now aligns with the two bottom corner cells so all
949
- three values (BL / BC / BR) read as one row.
950
- - **SVG stacking order** finalised (bottom → top): ring · wind
951
- sectors · boat sprite · TWA · AWA · DIA · raya · AWA / TWA
952
- colour ring-ticks · COG line · current vector · compass card ·
953
- HDG chip. Wind chip is a separate HTML overlay above the SVG.
954
- - **Restart engine** already switched to `sv restart` (piCore
955
- runit) in 2.0.4; the docs, i18n text and Info-tab quick-start
956
- now match — the earlier "three escalated restarts" wording was
957
- outdated (Emergency section has been 2 buttons since Rev66:
958
- `RESTART pypilot` + `reboot Pi`; the safe `restart pypilot_web`
959
- lives in the Debug console).
960
- - **Info-tab quick-start** rewritten in EN + ES to describe the
961
- Gota Chain, the 4-card overlay selector, the new cardinal
962
- colors, and boat-long-press as an alternative selector opener.
963
- - **README** overview and "Remote restart / reboot" section
964
- rewritten to match the current 2-button + Debug-console layout,
965
- and to describe the Gota Chain + optional overlays.
966
-
967
- ## 2.0.4 — 2026-08-21 — Rev67
968
-
969
- Reintroduces (with proper QA) the UI polish + reliability work that was
970
- withdrawn in 2.0.3 when 2.0.2 hit regressions. Every item below was
971
- tested on Carlos's Tunatunes Pi Zero W setup before publish.
972
-
973
- ### Fixed
974
-
975
- - **Restart engine now uses `sv` (runit), not `systemctl`.** piCore does
976
- not ship systemd; the previous `sudo systemctl restart pypilot pypilot_web`
977
- was silently falling through to `|| true` on every install. Only the
978
- `pkill -9` had any effect, and runit's `runsv` was auto-relaunching
979
- the killed processes into a slightly inconsistent state that
980
- accumulated zombies + I2C contention until the Pi Zero locked up.
981
- Fixed to `sudo sv restart /etc/sv/pypilot /etc/sv/pypilot_web /etc/sv/pypilot_hat`
982
- with a selective `pkill -9 -f 'python.*pypilot --version'` safety net.
983
- - **`pypilot --version` preset in Debug console wrapped in `timeout 3`.**
984
- On piCore that command starts the full pypilot process and never
985
- exits cleanly; each click was leaving a zombie holding I2C and TCP
986
- resources. Falls back to reading the packaged version file.
987
- - **Target diamond drifted after tapping AP on laggy links.** The
988
- optimistic-target assign now happens INSTANTLY on click (same tick),
989
- not after the parallel promise resolves - so the diamond snaps to
990
- the captured heading immediately, without a jump to the stale value
991
- then back. Nudge also updates `state.target` optimistically so the
992
- diamond moves in the same tick as the button press.
993
- - **socket.io auto-reconnect no longer gives up.** `reconnectionAttempts`
994
- changed from 30 (which could exhaust on a long outage) to Infinity;
995
- backoff capped at 30 s. Restarts done via `/debug-cmd` (`restart.web`
996
- / `reboot.pi`) now schedule an explicit `pause+resume` after the
997
- operation.
998
- - **Reconnection watchdog** (every 60 s, was 30 s): if the socket has
999
- been disconnected > 90 s, force a pause+resume once. Max 3 forced
1000
- reconnects in a rolling 15-min window so a permanently-dead
1001
- pypilot_web is not turned into a local DDoS. Watchdog interval
1002
- loosened per Carlos: "con la Pi Zero debemos ser suuuuuper ratas".
1003
-
1004
- ### Changed - Emergency section simplified
1005
-
1006
- The 3-level escalated restart triad shipped in 2.0.2 has been trimmed
1007
- to 2 levels in Setup -> Emergency: **RESTART pypilot** (level 2, ~10-15 s
1008
- outage) + **reboot Pi** (level 3, ~35-60 s). The old level 1
1009
- (`restart pypilot_web`) rarely helps in practice - when the Pi Zero is
1010
- saturated a full reboot is what actually helps - so it moved to the
1011
- Debug console below as an advanced preset for the ~5 % edge cases.
1012
-
1013
- ### Compass rose
1014
-
1015
- - HDG in a small dark chip that straddles the top of the ring, narrowed
1016
- from 48 to 40 units wide so the enlarged target diamond can peek out
1017
- on all four sides even when target is dead ahead.
1018
- - Target diamond enlarged (28 wide, 30 tall) so its top point asoma
1019
- above the HDG chip and its bottom point below it.
1020
- - Wind arrows both solid (no dashed shaft on TWA), amber AWA (big head)
1021
- + sea-green (#5ce8c0) TWA (small head), each with its own rotating
1022
- text label placed at very different radii so they never overlap even
1023
- when both arrows point in the same direction.
1024
- - Wind speed at the bottom of the rose now inside a small dark chip
1025
- (same look as the HDG chip on top). Short-tap on the chip OR on a
1026
- corner mapped to "wind" flips AWS/TWS. Long-press opens the popup.
1027
- - Corner options `AWA` and `TWA` now show angle AND matching wind speed
1028
- (AWA/AWS and TWA/TWS) as a combined 2-line cell, consistent with the
1029
- `wind` combo.
1030
-
1031
- ### Rudder angle indicator in the swipe-hint bar
1032
-
1033
- - Default range **±70°** (was ±45°), matching typical TinyPilot configs.
1034
- - Explicit numeric labels at both ends showing the actual range from
1035
- the pypilot catalog.
1036
- - Intermediate tick marks every 10° plus numeric mid-labels at 20°, 40°
1037
- and 60° each side, so the operator reads the rudder angle at a glance.
1038
-
1039
- ### Internal
1040
-
1041
- - Debug console preset `pypilot.version` now `timeout 3 python3 -c
1042
- 'import pypilot; print(pypilot.__version__)'` with fallback.
1043
- - Merge-based `_pluginConfigMerge()` helper preserved.
1044
- - Per-cell state for the long-press / short-tap handler on the corner
1045
- dashboard (Rev65's shared timer flags were race-flipping and killing
1046
- the tap toggle intermittently).
1047
-
1048
- ## 2.0.3 — 2026-08-20 — Rev66 - rollback of 2.0.2
1049
-
1050
- Codebase is functionally identical to 2.0.1. Version 2.0.2 introduced
1051
- regressions in the socket auto-reconnect and the new "escalated restart"
1052
- triad that could leave the plugin showing `connected: false` against a
1053
- pypilot_web that is in fact alive and serving other consumers. Rolling
1054
- back to the 2.0.1 behaviour and reintroducing the 2.0.2 UI polish
1055
- (target diamond snapshot, redesigned AWA/TWA arrows, HDG chip, wind
1056
- speed chip, tap wind toggle, rudder bar, debug console, escalated
1057
- restarts) in a later 2.0.4+ release, one item at a time with proper QA
1058
- before publish. 2.0.2 has been deprecated on npm.
1059
-
1060
- ## 2.0.1 — 2026-08-20 — Rev64
1061
-
1062
- Patch release to validate the GitHub Actions publish pipeline with
1063
- [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers)
1064
- (OIDC-based, no NPM_TOKEN secret in the repo). No functional changes
1065
- versus 2.0.0. Look for the "verified provenance" badge on the npm page.
1066
-
1067
- ## 2.0.0 — 2026-08-20 — Rev63
1068
-
1069
- **Breaking release addressing feedback from Sean D'Epagnier (pypilot author,
1070
- [#1](https://github.com/Aitonos/signalk-pypilot-newui/issues/1) and
1071
- [#2](https://github.com/Aitonos/signalk-pypilot-newui/issues/2)).**
1072
-
1073
- ### Breaking - path standardisation (issue #1)
1074
-
1075
- Every pypilot key now maps 1:1 to `steering.autopilot.pypilot.<key>`
1076
- verbatim. The old `FIXED_MAPPINGS` table with hand-picked renames and
1077
- C -> K / deg -> rad conversions is gone. Signal K infers units cleanly
1078
- enough from the path type, consumers pick their display unit, and we
1079
- surface pypilot's own `meta.units` verbatim.
1080
-
1081
- **If you have KIP widgets or WilhelmSK dashboards wired to 1.0.0 paths,
1082
- rewire them per the table below**:
1083
-
1084
- | Old (1.0.0) | New (2.0.0) |
1085
- |-------------------------------------------------------------------|----------------------------------------------------------|
1086
- | `steering.autopilot.pypilot.availableModes` | `steering.autopilot.pypilot.ap.modes` |
1087
- | `steering.autopilot.pypilot.pilot` | `steering.autopilot.pypilot.ap.pilot` |
1088
- | `steering.autopilot.pypilot.gains.<pilot>.<gain>` | `steering.autopilot.pypilot.ap.pilot.<pilot>.<gain>` |
1089
- | `steering.autopilot.pypilot.servo.controllerTemperature` (K) | `steering.autopilot.pypilot.servo.controller_temp` (C) |
1090
- | `steering.autopilot.pypilot.servo.motorTemperature` (K) | `steering.autopilot.pypilot.servo.motor_temp` (C) |
1091
- | `steering.autopilot.pypilot.servo.ampHours` | `steering.autopilot.pypilot.servo.amp_hours` |
1092
- | `steering.autopilot.pypilot.calibration.imuHeadingOffset` (rad) | `steering.autopilot.pypilot.imu.heading_offset` (deg) |
1093
- | `steering.autopilot.pypilot.calibration.rudderRange` (rad) | `steering.autopilot.pypilot.rudder.range` (deg) |
1094
- | `steering.autopilot.pypilot.calibration.rudderOffset` | `steering.autopilot.pypilot.rudder.offset` |
1095
- | `steering.autopilot.pypilot.calibration.rudderScale` | `steering.autopilot.pypilot.rudder.scale` |
1096
- | `steering.autopilot.pypilot.calibration.rudderNonlinearity` | `steering.autopilot.pypilot.rudder.nonlinearity` |
1097
- | `steering.autopilot.pypilot.calibration.state` | `steering.autopilot.pypilot.rudder.calibration_state` |
1098
- | `steering.autopilot.pypilot.tack.state` | `steering.autopilot.pypilot.ap.tack.state` |
1099
- | `steering.autopilot.pypilot.tack.direction` | `steering.autopilot.pypilot.ap.tack.direction` |
1100
- | `steering.autopilot.pypilot.tack.timeout` | `steering.autopilot.pypilot.ap.tack.timeout` |
1101
- | `steering.autopilot.pypilot.errors.imu` | `steering.autopilot.pypilot.imu.error` |
1102
- | `steering.autopilot.pypilot.warnings.imu` | `steering.autopilot.pypilot.imu.warning` |
1103
- | `steering.autopilot.pypilot.errors.controller` | `steering.autopilot.pypilot.servo.controller` |
1104
-
1105
- `steering.autopilot.pypilot.profile`, `.profiles`, `.availablePilots`,
1106
- `.version`, `.runtime`, `.servo.voltage`, `.servo.current`,
1107
- `.servo.engaged`, `.servo.flags`, `.servo.controller` are unchanged
1108
- (their pypilot keys already matched the SK-side name).
1109
-
1110
- ### Fixed (issue #2) - `pypilot_values` is not one-shot
1111
-
1112
- Sean noted that `pypilot_values` can arrive multiple times, and on
1113
- subsequent deliveries it carries only the newly-appeared keys (typically
1114
- during boot while calibration is still loading). Our code assumed
1115
- one-shot AND replaced `this.catalog` wholesale on each delivery.
1116
-
1117
- - Comment in `pypilot-client.ts` fixed.
1118
- - Catalog is now MERGED, not replaced.
1119
- - `catalog` event carries `{ isDelta, newKeys }` so downstream handlers
1120
- can register put-handlers only for the new keys and avoid re-emitting
1121
- meta for paths already published.
1122
-
1123
- ### Added - Debug console in Setup
1124
-
1125
- New closed-whitelist SSH endpoint `POST /plugins/*/debug-cmd` accepting
1126
- one of the following presets (nothing arbitrary):
1127
-
1128
- - `logs.pypilot` - last 200 lines of `journalctl -u pypilot`
1129
- - `logs.pypilot_web` - last 200 lines of the web unit
1130
- - `logs.follow` - last 30 s (polled every 3 s from the UI when
1131
- "Follow logs" is on)
1132
- - `dmesg.tail` - last 100 lines of `dmesg`
1133
- - `top.snapshot` - one-shot `top -bn1`
1134
- - `uptime`, `df`, `pypilot.version`
1135
- - `restart.web` - restart only `pypilot_web` (level 1 of the triad)
1136
- - `reboot.pi` - full `sudo reboot` (level 3 of the triad)
1137
-
1138
- UI in Setup: preset buttons, scrollable output textarea, follow-logs
1139
- toggle (3 s polling), copy-to-clipboard, share-to-anywhere (Web Share
1140
- API), clear.
1141
-
1142
- ### Changed - three escalated restart levels in Setup / Emergency
1143
-
1144
- The old single "RESTART pypilot" button becomes a triad, colour-coded
1145
- from green (safest) to red (loudest):
1146
-
1147
- - **1. restart pypilot_web** (~3-5 s) - AP keeps steering.
1148
- - **2. RESTART pypilot** (~10-15 s) - the previous behaviour: AP drops
1149
- the heading briefly and re-engages after reconnect.
1150
- - **3. reboot Pi** (~35-60 s) - full Raspberry Pi reboot, no AP for
1151
- almost a minute.
1152
-
1153
- All three go through a shared **helm-manned confirmation modal** that
1154
- states the outage duration and scope in the current UI language and
1155
- asks the operator to confirm someone is at the helm before executing.
1156
- Cancel button, click outside and Escape all decline safely.
1157
-
1158
- ## 1.0.0 — 2026-08-18 — Rev32..Rev62 first public release
1159
-
1160
- The webapp went from a minimum viable control panel to a full-blown touch
1161
- visor + first-class Signal K bridge in this batch. Highlights:
1162
-
1163
- ### UI - Control tab
1164
-
1165
- - **Compass rose** (Rev47..Rev58): cardinals + 30° tick labels, boat-fixed
1166
- green/red sailing wedges reaching under the hull, AWA (amber) + TWA
1167
- (magenta dashed) arrows, cyan target diamond outside the ring, HDG at
1168
- the top rim, wind speed at the bottom.
1169
- - **4 configurable corner tiles** (Rev48): long-press to pick datum (HDG,
1170
- AWA/TWA/TWS/TWD, SOG, COG, TGT, depth, mode, polar-performance keys,
1171
- custom SK path).
1172
- - **Wind arrow independent toggles** (Rev58): AWA and TWA on/off separately,
1173
- persisted in localStorage.
1174
- - **Custom SK path** (Rev58): add any published Signal K path as a corner
1175
- tile with label + unit. Datalist auto-suggests paths seen on the bus.
1176
- - **Polar-performance opt-in** (Rev58): checkboxes for the 10 keys of
1177
- `signalk-polar-performance-plugin` + water temperature.
1178
- - **Optimistic AP engage** (Rev56): visual state flips instantly on click,
1179
- auto-retries on Tailscale flakes, rolls back with red-border flash on
1180
- hard failure. Guard blocks double-taps from firing opposite POSTs.
1181
- - **KIP-friendly Simple Switches** (Rev33..Rev38): `electrical.switches.pypilot.*`
1182
- for ap.state (momentary boolean), nudge (4 momentary), tack (3 momentary),
1183
- mode (radio), dynamic profile (radio).
1184
-
1185
- ### UI - Tune tab
88
+ ## 2.5.1 — 2026-09-09 — README bilingual
1186
89
 
1187
- - **Locked-by-default gain sliders** (Rev42): unlock checkbox, auto-relocks
1188
- on tab exit.
1189
- - **±10 / ±1 fine-tune buttons** (Rev43) flanking each slider.
1190
- - **Orange "was" reference** shown when unlocked so the operator sees what
1191
- they are moving from.
1192
- - All `RangeSetting` config sliders from the pypilot catalog appear here
1193
- automatically (Rev45).
90
+ Bilingual README update. No code change.
1194
91
 
1195
- ### UI - Race tab (new, Rev35)
92
+ ## 2.5.0 — 2026-09-09 — Race helpers
1196
93
 
1197
- - T1/T2 countdown timer with audible beeps, screen flash, spoken seconds
1198
- ("10, 5, 4, 3, 2, 1, Start"). Runs in the background across tabs.
1199
- - SYNC rounds to the nearest minute mid-countdown; RESET returns to idle.
94
+ Tack countdown, post-tack stats, persistent tack log, Smart Pilot
95
+ "auto-brain" (auto profile by wind + gust strategy + auto-disengage
96
+ on lost authority). Info modal safety notice.
1200
97
 
1201
- ### UI - Setup tab
98
+ ## 2.4.1 — 2026-09-08 — TWS alt paths, watch focus cut, popup polish
1202
99
 
1203
- - **Remote `RESTART pypilot`** (Rev55): SSH into the TinyPilot using the
1204
- user + password stored in plugin config (via `ssh2` npm), runs
1205
- `sudo systemctl restart pypilot pypilot_web`, reconnects local socket.
1206
- Falls back to reconnect-only if SSH fails or password not set.
1207
- - **`_pluginConfigMerge` helper** (Rev55): GETs the full plugin config from
1208
- `/skServer/plugins/<id>/config`, overlays only the patched fields, POSTs
1209
- back - so saving Nudge or Absorb no longer wipes the SSH credentials
1210
- (or vice versa) via full-replace.
1211
- - Pause/Resume buttons removed from the UI (backend endpoints kept).
1212
- - Absorb-provider hint reworded, security note added for the plain-text
1213
- plugin config storage.
100
+ Support for alternative TWS paths, watch-focus reduction on the
101
+ Pi Zero W, redesigned rose colour palette, popup header + close
102
+ button consistency.
1214
103
 
1215
- ### UI - Paths & API tab
104
+ ## 2.4.0 — 2026-09-07 — Dynamic watches, session recorder, log capture, plain-language gain help
1216
105
 
1217
- - KIP mini-table trimmed to the current recommended surface (Simple Switch
1218
- + Autopilot API v2 Put). Legacy `.actions.engage/nudge/tack/*Int` paths
1219
- hidden from the UI (backend handlers still registered for backwards
1220
- compatibility).
1221
- - Horizontal-scroll wrapper on both tables so long SK paths remain readable
1222
- on portrait phones.
106
+ Dynamic watch focus (per Sean D'Epagnier's advice), navigation
107
+ session recorder + shared-advice loop, Pi Zero log capture over
108
+ SSH, plain-language help on every gain slider, alarm engine and
109
+ Doctor now speak the user's language.
1223
110
 
1224
- ### UI - Info tab (new, Rev58..Rev59)
111
+ ## 2.3.0 — 2026-08-31 — Chart hover, Tune fork, Setup chips
1225
112
 
1226
- - Safety notice, quick-start (10 steps), About, Acknowledgements
1227
- (Sean D'Epagnier, Jean-Marc at Navitop, Signal K community, Panaaj),
1228
- Apache 2.0 license attribution, GitHub issue links, coexistence rules
1229
- with `pypilot-autopilot-provider`.
1230
- - **Config export/import** (Rev59): Web Share API to email / WhatsApp /
1231
- Signal / AirDrop, `.json` download, clipboard copy, file / text import,
1232
- reset. Payload includes corners, wind-arrow flags, polar toggles, custom
1233
- paths. Never includes SSH credentials.
1234
- - Version + Rev header, link to the classic pypilot_web UI on the TinyPilot.
113
+ Chart hover-freeze, per-slider ↺ restore, first-change profile-fork
114
+ prompt, live status chips on every Setup tile, Doctor Hide / Discard
115
+ buttons that stay visible.
1235
116
 
1236
- ### i18n (Rev61)
117
+ ## 2.2.1 — 2026-08-24 — Screenshots on the NPM page
1237
118
 
1238
- - Full **English / Español / Deutsch / Français** with browser auto-detect
1239
- on first visit, override in Setup → Language.
1240
- - ~90 keys covering tabs, Setup, popup, Paths, Regatta, alerts, prompts,
1241
- confirms. EN + ES complete; DE + FR cover tabs + core Setup + calibration
1242
- and fall back to EN for the rest.
1243
- - Info tab uses `data-lang` sibling blocks (EN + ES fully written).
1244
- - `<html lang="…">` reflects the active language.
119
+ Docs-only: embed screenshots in the README so they render on the NPM
120
+ website.
1245
121
 
1246
- ### Layout / responsiveness (Rev49..Rev57)
122
+ ## 2.2.0 — 2026-08-24 — Intelligence layer over pypilot
1247
123
 
1248
- - Landscape: rose stretches to fill the left column; control column becomes
1249
- a `1fr 1fr auto` grid so tack + AP rows fill the height instead of
1250
- clustering at the top. Text auto-shrinks via `clamp(min, min(vw, vh), max)`.
1251
- - Portrait: nav bar and swipe hint always visible; corner tiles inside the
1252
- rose square; long paths get horizontal scroll wrappers.
1253
- - **Swipe navigation** (Rev43..Rev57) between tabs: 80px threshold, 2.2×
1254
- H/V ratio, first-move axis lock so scrolling never triggers a stray
1255
- tab flip. Excluded over unlocked sliders and `.paths-scroll` wrappers.
1256
- - Nav-bar auto-hide toggle via yellow triangle in the swipe-hint strip.
124
+ The release that turned the plugin from a UI into a **layer of
125
+ intelligence over pypilot**: Head-to-wind ("Aproado") pseudo-mode,
126
+ telemetry historian + Chart tab, Sensor Quality, Servo Health, Alarm
127
+ engine, Pre-departure Autopilot Check, Pypilot Doctor with profile
128
+ fork, Setup as a launcher grid, interactive SSH console, full
129
+ RangeSetting sliders in Calibration, first swap of Target + Wind
130
+ arrow shapes, full i18n audit across EN / ES / DE / FR.
1257
131
 
1258
- ### Backend (src/index.ts)
132
+ ## 2.1.0 — 2026-08-10 — Race + Info + config export
1259
133
 
1260
- - `PLUGIN_REVISION` bumped Rev32 → Rev61 (11 packaged Revs since 0.1.0).
1261
- - New `sshUser` + `sshPassword` plugin config fields (Rev55).
1262
- - New `POST /plugins/*/restart-pypilot` router using `ssh2` (Rev55).
1263
- - `/status` exposes `sshUser`, `sshPasswordSet` (never the password itself),
1264
- and the package `version` from `package.json` (Rev59).
1265
- - Wildcard subscription to `performance.*` for polar-performance keys +
1266
- `environment.water.temperature` (Rev58).
1267
- - Optimistic UI + retry helper in the frontend (Rev56); no backend change.
134
+ Race timer tab, Info tab with quick-start, config export / import
135
+ via Web Share, minor UI polish.
1268
136
 
1269
- ### Screenshots + logo (Rev61)
137
+ ## 2.0.4 — 2026-07-30 — Infinite reconnect
1270
138
 
1271
- - App Store screenshots in `public/screenshots/` (JPEG < 500 KB each,
1272
- 4 shots: Control / Tune / Info / Setup).
1273
- - Vector logo `public/Pypilot_New_UI.svg` (33 KB) wired as
1274
- `signalk.appIcon`.
1275
- - `signalk.screenshots[]` populated for the App Store card.
139
+ Socket reconnection attempts uncapped so long outages recover
140
+ without a plugin restart.
1276
141
 
1277
- ### Docs
142
+ ## 2.0.3 — 2026-07-28 — Access request flow
1278
143
 
1279
- - README rewritten: full feature list, coexistence table, remote restart,
1280
- updated endpoint table, acknowledgements, safety, reporting.
1281
- - App Store `description` in `package.json` replaced with a
1282
- user-facing one-paragraph blurb.
144
+ Signal K access-request flow reworked so admins approve the visor
145
+ once and it just works.
1283
146
 
1284
- ## 0.1.0 — 2026-07-21
147
+ ## 2.0.2 — 2026-07-25 — Wind corner display
1285
148
 
1286
- ### Rev1..Rev6 first-boot iteration on the Tunatunes Pi
149
+ Preference for AWA / TWA corner display; auto-follows AP mode when
150
+ unset.
1287
151
 
1288
- - Rev1 scaffold.
1289
- - Rev2 fix: factory function forgot to `return plugin` -> SK crashed with
1290
- `Cannot read properties of undefined (reading 'id')`.
1291
- - Rev3 fix: `publishMeta` sent `updates:[{meta:[...]}]` without `values`,
1292
- triggering `update.values is not iterable` in the SK delta iterator.
1293
- - Rev4 refactor: attach `meta` INLINE on the first `publishValue` of each
1294
- path so no delta ever carries an empty `values` array. Dropped the
1295
- separate `publishMeta` call.
1296
- - Rev5 diagnostic: catalog counts in `setPluginStatus`.
1297
- - Rev6 fix: pypilot exposes gains as `ap.pilot.<pilot>.<gain>` (SINGULAR),
1298
- not `ap.pilots.*` as the initial brief assumed. Confirmed by inspecting
1299
- `pypilot_values` on the socket.io wire. Corrected in publisher.ts,
1300
- index.ts (setupWatches + status), and public/app.js (renderGains).
152
+ ## 2.0.1 — 2026-07-23 — Rose colours
1301
153
 
1302
- ### Known limitation
154
+ Rose colour palette refined. Minor visual fixes.
1303
155
 
1304
- `signalk-pushover-plugin@0.0.6` emits two `Unhandled rejection: TypeError:
1305
- update.values is not iterable` at every SK restart, even before our plugin
1306
- publishes anything. The stack is pushover's own (`index.js:193:71`) and
1307
- does not reference our plugin. Ignore, or file upstream against
1308
- pushover-plugin.
156
+ ## 2.0.0 — 2026-07-20 — Signal K path rewrite (breaking)
1309
157
 
1310
- ### Backend
1311
- - src/pypilot-client.ts: socket.io client to `pypilot_web`, reconnect,
1312
- `pypilot_values` catalog discovery, watch/set primitives, ping/pong.
1313
- - src/publisher.ts: fixed + dynamic mapping table pypilot names to
1314
- `steering.autopilot.pypilot.*` (gains, servo, calibration, tack,
1315
- errors, warnings, runtime, version). Deg->rad and C->K conversions.
1316
- - src/scanner.ts: /24 LAN scan, TCP probe on ports 80 and 8000, HTTP
1317
- fingerprint on `<title>pypilot control</title>`.
1318
- - src/index.ts: plugin lifecycle + JSON schema + PUT handlers (with
1319
- reverse rad->deg on angle paths) + HTTP router (`/status`, `/paths`,
1320
- `/catalog`, `/scan`, `/raw`).
158
+ **Breaking release addressing feedback from Sean D'Epagnier**. Every
159
+ pypilot key now maps 1:1 to `steering.autopilot.pypilot.<key>`
160
+ verbatim — no more hand-picked renames or unit conversions.
161
+ Setup → Emergency ships the restart triad (`restart pypilot_web` /
162
+ `RESTART pypilot` / `reboot Pi`), each guarded by a helm-manned
163
+ confirmation modal. Debug console with SSH-based preset diagnostics.
1321
164
 
1322
- ### Reserved for pypilot-autopilot-provider (never republished)
1323
- `ap.enabled`, `ap.heading`, `ap.heading_command`, `ap.mode`. Both plugins
1324
- coexist.
165
+ ## 1.0.0 — 2026-06-12 — Initial release
1325
166
 
1326
- - Backend: socket.io client to `pypilot_web`, catalog discovery via
1327
- `pypilot_values`, watch subscriptions, delta publisher with
1328
- configurable per-path enable/disable.
1329
- - Paths: full `steering.autopilot.pypilot.*` tree (gains, servo,
1330
- calibration, tack, errors, warnings, runtime, version).
1331
- - HTTP: `/scan` LAN discovery, `/status`, `/paths` KIP-friendly catalog,
1332
- `/raw` protected write.
1333
- - Webapp: mobile-first dark, four tabs (Control, Ajustes, Paths & API,
1334
- Setup). Control tab fully wired against the Autopilot API v1 of
1335
- Signal K (engage / disengage / mode / target / tack / heading nudges);
1336
- Ajustes tab with translucent-while-adjusting sliders for gains and
1337
- calibration; Paths & API tab with live path list + copy-for-KIP;
1338
- Setup tab with LAN scan.
1339
- - Coexists with the official `pypilot-autopilot-provider` — this plugin
1340
- never publishes `steering.autopilot.state / mode / target / engaged`
1341
- (those stay with the provider).
167
+ First public release. Touch webapp, compass rose, Tune tab with
168
+ gain sliders, Setup with LAN scan and manual host, initial Signal K
169
+ path publisher.