Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 21 Jun 10:16
· 110 commits to main since this release
Immutable release. Only release title and notes can be modified.

Changes

  • Merge remote-tracking branch 'origin/main' into worktree-render-perf (d8da04a)
  • chore(release): bump firmware minor version 0.3.0 -> 0.4.0 (02671cd)
  • docs(qa): final on-device verification screenshots (depth fit, review fixes) (1a02945)
  • fix(depth): fit-to-width hero (doubled, but shrinks so deep values fit) (a04e321)
  • docs(design): update MIDL — XTE in nm + P/S side (review S2) (0ef1485)
  • fix(ui): implement design-review fixes (S1-S6 + per-screen) (44a5df2)
  • docs(design): MIDL screen definitions + cards (brand font, embedded MIDL) (bb0c8f7)
  • feat(depth): double hero font + depth-history sparkline; brand-font design cards (78bd9ea)
  • chore(midl): bump submodule to 5b09c81 (semantic validation + tightened schema) (41f4473)
  • docs(design): Claude Design cards for all 11 screens (0e85a2a)
  • fix(ui): XTE tile shows auto-shrunk value, not tofu '>' (font_xl_64 lacks '>') (ff52530)
  • fix(ui): swipe-nav, depth restyle, and the open QA issues (3c14628)
  • docs(qa): two-pass on-device screen QA (per-element + combined) (be8cb5b)
  • fix(ui): QA fixes — value-fit, hero label, STW, AP depth scaling (907233d)
  • feat(ui): course-adjust controls + depth screen restructure (145c7e5)
  • feat(ui): show rudder angle on the steering screen (aef5cec)
  • feat(format): configurable per-unit value scaling (k/M) + decimals (36ba53e)
  • feat(data): plumb rudder angle + fix VMG subscription (3a778c9)
  • fix(alarm): reposition banner to top, blink, cycle multiple alarms (1e7e81c)
  • wip(idf5): hybrid framework reaches LINK stage (4 tooling rungs cleared) (26f0110)
  • chore(midl): bump submodule to 83ed4e0 (dir->flow, README, license headers) (eef742e)
  • revert(idf5): back to non-hybrid (BLE works); hybrid blocked on pioarduino tooling (45c06f8)
  • wip(idf5): hybrid framework setup (EXCLUDE_COMPONENTS + BT/IRAM-safe sdkconfig) (79bfebd)
  • feat(idf5): bring BLE back on NimBLE-Arduino 2.x (version-conditional) (99a6b9a)
  • feat(n0183): default to UDP transport, TCP opt-in, shorter connect timeout (f475279)
  • wip(idf5): esp_lcd single-fb PARTIAL attempt — UNRESOLVED (flicker/hang) (3f6d8b5)
  • feat(idf5): esp_lcd double-buffer display — builds + boots on IDF-5 (baa7781)
  • chore(idf5): migration groundwork — BLE-disable flag + IDF-5 spike env (6896b78)
  • docs(bench): record double-buffer finding (blocked on esp-idf 4.4) (d02d534)
  • perf(render): dedicated LVGL task; gate DIRECT off (flickers) -> buffered PARTIAL (f1d5847)
  • docs(bench): cumulative render optimization results (baseline/opt1/opt2) (a3b2487)
  • perf(render): DIRECT-mode render into the RGB panel framebuffer (80e14e5)
  • perf(render): quantize rotations to whole degrees in set_rot_if_changed (ebcb711)
  • feat(bench): per-screen first-load + cold-build metrics in render sweep (6875399)
  • Merge remote-tracking branch 'origin/main' (73b988a)
  • chore(midl): point submodule at yey-boats/midl remote (83f9499)
  • feat(midl): serve embedded generated manifest at /api/midl/manifest (f0f812b)
  • docs(plan): YB-MIDL manager migration, phased (plan 4 of 6) (8b2ff5a)
  • chore(midl): bump submodule to distributable build (ccb92f6)
  • chore(midl): bump submodule to web renderer + licensing (plan 3) (e7eafbe)
  • docs(plan): YB-MIDL web renderer (plan 3 of 6) (e27b070)
  • refactor(midl): extract MIDL into standalone repo, include as submodule (723ccff)
  • test(midl): guard committed manifests against catalog drift (b6f4662)
  • test(midl): dispatch-covers-catalog consistency check (c2c96c1)
  • test(midl): generated manifests validate against the capabilities schema (25cbd18)
  • feat(midl): C++ element catalog + host manifest generator (95020c3)
  • docs(plan): YB-MIDL catalog -> manifest generator (plan 2 of 6) (4b6222a)
  • docs(plan): record deferred validation-coverage follow-ups from Plan 1 review (70d10a5)
  • fix(midl): validate manifest before parsing its version in validateDocument (2b50a8f)
  • feat(midl): validateDocument pipeline + golden corpus (80e6de8)
  • feat(midl): capability-satisfaction validator (ac0ece1)
  • feat(midl): config + capabilities JSON Schemas with structural validation (e800b85)
  • feat(midl): preset expansion + tile/depth metrics (d72aa9f)
  • feat(midl): YAML/JSON canonicalization + lossless round-trip (f3abcc4)
  • feat(midl): version parse + compatibility rule (cc097e9)
  • feat(midl): shared config + manifest types (381a395)
  • feat(midl): scaffold @yey-boats/midl TS package (d80a3c1)
  • docs(plan): YB-MIDL language core (plan 1 of 6) (ecd45bb)
  • docs(spec): YB-MIDL generic dashboard runtime rendering model (47c9cc7)
  • docs(spec): YB-MIDL generic dashboard runtime rendering model (2911825)
  • ci(tip): drop release-based tip job; serve TIP from CI artifacts (52147bd)
  • ci(tip): immutable-release-safe publish (draft -> upload -> publish) (680a517)
  • tools: migrate-lab-rename.sh notes/verify -> yey-net (network renamed) (a0a1c22)
  • refactor(rebrand): WiFi network esp-lab -> yey-net (provisioning, env, docs) (9b5fe7c)
  • tools: add lab-host espdisp->yeydisp migration script (sudo, idempotent) (2db716e)
  • ci(version): MAJOR.MINOR.BUILD with auto BUILD + rolling tip prerelease (80de0ce)
  • fix(markers): center compass/wind-rose marker rings on the dial center (c0f9479)
  • refactor(rebrand): ESPDISP_ env/flags -> YEYBOATS_, tool filenames -> yeydisp (5e56fe3)
  • refactor(rebrand): firmware tools FW_NAME/mDNS/BLE/OTA defaults -> yey (27add64)
  • fix(screens): correct pushed-tile rendering, zoom pivot, and SSID telemetry (22b9b05)
  • refactor(rebrand)!: rename auth header + provision token + C++ namespace (e46aa48)
  • docs: drop named external repo reference (navado/NMEA2000-DISPLAY-on-ESP32S3) (b88331a)
  • chore: retarget old navado/esp32-boat-mfd refs -> yey-boats/instruments + Yey Boats Instruments (a900ab8)
  • refactor(rebrand)!: rename proto npm package @espdisp/proto -> @yeyboats/proto (v2.0.0) (405f3fd)
  • chore(license): Required Notice URL -> github.com/yey-boats/instruments (90a0b7f)
  • chore(license): source-file copyright comments -> Yey Boats Project (9340b70)
  • chore(license): owner = Yey Boats Project, contact rights@yey.boats (2d6f1a3)
  • refactor(rebrand)!: SignalK config-push path network.espdisp.configPush -> network.yeyboats.configPush (fe49a03)
  • refactor(rebrand)!: rename wire protocol/mDNS identifiers + bump control proto to v2 (3912fce)
  • refactor(rebrand)!: device identity prefix espdisp- -> yey-d- + boot migrations (d137eae)
  • docs(sim): lab deploy = host-net + web 8088, retire kdcube-sim, current emitted (3faa3d8)
  • refactor(rebrand)!: firmware manager plugin path -> /plugins/yey-boats-display-manager (4ee40ff)
  • feat(provision): firmware applies manager-pushed OTA password from config (dc3f364)
  • docs(plan): manager console slice 7 (provisioning config-push + auto-numbering) (df4a95a)
  • docs(plan): manager console slice 6 (per-device Update Firmware + validation) (e86625b)
  • docs(plan): manager console slice 5 (ESP Web Tools + manifest + WebSerial provisioning) (87a398d)
  • build(fw): emit merged factory image for ESP Web Tools (esptool merge_bin) (d5c109c)
  • docs: slice 4 plan (merged factory image); drop Improv for existing serial commands (db8f293)
  • feat(ota): runtime OTA password in NVS + ota-pass serial commands (a741df7)
  • test(ota): pure effective-OTA-password selector + host tests (449cf5d)
  • docs(plan): manager console slice 3 (firmware runtime OTA password) (6ec849c)
  • docs(plan): manager console slice 2 (System Settings) (cce3c0d)
  • docs(sim): migrate lab deployment to the yey-boats/simulator GHCR image (169bd72)
  • docs(plan): manager device console slice 1 (UI restructure) (f0628cc)
  • docs(sim): repoint docs + system tests to yey-boats-sim (8746d68)
  • chore(sim): remove legacy fake_boat.py; use full-blown yey-boats/simulator (68a187c)
  • docs(spec): manager device console — merged UI, settings, USB/OTA flashing (aabb041)
  • fix(sim): address review — single route advance, 400m legs, clamp XTE, AIS spread (7811057)
  • feat(sim): compose phase-driven run loop + --dump smoke path (b47fc04)
  • feat(sim): self + AIS delta builders (route/AP/polar/keel/closest) (69e7d76)
  • feat(sim): PhaseScheduler cycles route/AP/AIS populated<->cleared (8dfbd2b)
  • feat(sim): AisFleet synthetic targets (converging CPA + nearest) (498804f)
  • feat(sim): Route derives XTE/CTS/BTW/DTW/VMG, advances on arrival (57d4ec9)
  • feat(sim): BoatState dead-reckoned position with heading slew (c17cc31)
  • feat(sim): great-circle geo helpers (bearing/distance/dead-reckon/XTE) (1bf602a)
  • refactor(sim): make fake_boat importable + argparse CLI scaffold (f275700)
  • docs(plan): implementation plan for phase-driven fake_boat.py sim (c264936)
  • docs(spec): queue phase-driven fake_boat.py feature-coverage sim (3e5c56d)
  • docs(spec): adjust screens-preview scope to device-reported bindings (5f268d7)
  • docs(spec): queue SignalK screens preview-fidelity rework (743806c)
  • chore: move SignalK manager plugin out to yey-boats/Instruments-manager (e6dbe11)
  • feat(manager): bulk-clear offline / all devices from the registry (197e9ef)
  • fix(security): escape apState in autopilot HUD SVG (defense-in-depth) (97b8f59)
  • fix(security): escape device telemetry in System panel SVG (XSS) (560372e)
  • fix(manager): faithful System/status panel in live view (not a generic grid) (e9d3028)
  • fix(slice3): defer subscription reductions to avoid WS-disconnect churn (33019dc)
  • Merge: configurable compass marker rings (HDG/COG/CTS + wind/target) (62e7154)
  • docs(markers): note ui_markers PSRAM canvas-buffer ownership in memory traps (dff3384)
  • docs(markers): regenerate marker-ring sim previews (final colors) (5e73275)
  • refactor(markers): standardize CTS color to alarm; rename steer_live (f0a9cce)
  • feat(markers): report glyphs + maxMarkersPerDial in capability manifest (e8374b4)
  • test(markers): manifest reports glyphs + maxMarkersPerDial (red) (68eefed)
  • refactor(markers): drop unused single-marker helpers (make_dir_marker, rotate_needle) (d323bd1)
  • feat(markers): wind rose apparent/true heads; wind-steer HDG/COG/CTS+TWD ring (d67e254)
  • test(tools): serial stress soak — cycles screens to exercise per-screen subs (de75893)
  • refactor(markers): name the semicircular marker inset constant (drop r-42 magic) (56a311d)
  • feat(markers): autopilot HUD shows HDG/COG/CTS + target marker ring (d549ed2)
  • docs(markers): fix stale switch comment (Compass has its own case now) (800c81a)
  • test(tools): on-device slice 3/4/6 serial verification driver (de368ea)
  • docs(spec): clarify per-widget reference frame (fixed-bezel tile is north-up) (ef8231d)
  • fix(markers): steering tile is north-up (markers at true bearings, match static bezel) (5840080)
  • feat(slice6): per-field zoom (auto-scale / screen-ref) (96f520b)
  • feat(markers): steering tile compass shows HDG/COG/CTS marker ring (50e5aa8)
  • feat(slice5): manifest-gated layout editor CRUD + field schema (7287157)
  • refactor(markers): name semicircle window const; document canvas buffer ownership (0af3340)
  • fix(markers): honor filled for cross (outline) and chevrons (bold stroke) (d4bd642)
  • feat(markers): LVGL glyph drawing + orbiting MarkerRing primitive (d8555f1)
  • feat(slice4): flash-persistent applied config (5931f6a)
  • test(markers): cover occlusion boundary + null glyph token; clarify fold comment (0b0524b)
  • feat(slice3): per-screen subscribe/unsubscribe (96246f6)
  • feat(markers): pure marker-math placement + glyph-token map (green) (4a0696a)
  • test(markers): pure marker-math placement + glyph-token tests (red) (cd7cb05)
  • docs(plan): compass marker rings — TDD implementation plan (8123e23)
  • docs(spec): raise marker-ring cap to 12, document dynamic sources follow-on (8847f44)
  • docs(spec): configurable marker rings for compass-like widgets (089b673)
  • feat(slice2): device capability manifest + manager ingest (21ee621)
  • docs(bench): captured bench-sweep results from device (espdisp-28372f8a0290) (6c840de)
  • feat(bench): bench-sweep harness — render/CPU/net/throughput/memory per screen (40d2398)
  • feat(bench): BenchRow accumulator+formatter for the on-device sweep (host-tested) (fb2f0f9)
  • docs(plan): on-device benchmark harness (bench-sweep) — render+CPU+net+throughput (716ed5f)
  • feat(fw): feed PSRAM dynamic path store from WS deltas (a65a21e)
  • feat(fw): resolve unknown paths via dynamic store (widget_data step 3) (9bbd925)
  • feat(fw): generic dynamic SignalK path->value store (PathStore) (58621ec)
  • docs(plan): slice 1 — firmware generic path->value store (TDD plan) (72b4631)
  • docs(spec): device-mirrored, version-gated layout editor (umbrella design) (21d43cd)
  • fix(manager): mirror the device — faithful live HUDs, discovered screens (e9ad755)
  • fix(manager): sync wind dial, wind-steer + trend previews to the device (9e38a7d)
  • fix(manager): autopilot screen design matches the device HUD (267f7ea)
  • feat(plugin): device-page live-view usability pass + full screen coverage (dfb863c)
  • test(plugin): widget-parity expects 15 theme colors (arc_band added) (c6632a9)
  • style(wind-steer): lighter wind marks (faint no-go tint + slim laylines) (0663873)
  • fix(plugin): live preview shows live objects + syncs to the device screen (7b3bad4)
  • refactor(wind-steer): rebuild on the autopilot layout (matched pair) (f6ad2b1)
  • feat(wind-steer): TWS-responsive target sector width (f0f2161)
  • fix(plugin): prevent prototype pollution in save-screen edits (d39b413)
  • feat(plugin): edit data fields in the live preview + Switch/Update/Create (B2) (025e31a)
  • style(wind-steer): thick band + proper red/green sectors, matching AP compass (bb615e7)
  • fix(wind-classic): heading-up dial with upright cardinal labels (dddf5c2)
  • fix(autopilot): exactly-square data tiles, clear of the XTE strip (149b071)
  • feat(plugin): live data-driven screen preview on the device page (B1) (1e75b4f)
  • feat(wind-classic): North-up card (fixed upright cardinals, boat rotates) (ce91512)
  • feat(wind-steer): 220-deg working-zone arc, target sectors, downwind verified (5eca649)
  • feat(wind-steer): bow-up working-zone arc (no-go + laylines from polars) (964b017)
  • feat(manager): report device screen list + use it in the view switcher (6be6742)
  • feat(wind-steer): drive tack/gybe from SignalK polars, empirical fallback (32732ea)
  • feat(ui): wind-steer screen, bold A/T markers; remove breadcrumb + MOB button (3e406fe)
  • feat(plugin): per-screen switch control on the device page (d691c3c)
  • feat(ui): drop on-screen title chip; wider AP compass + bigger labels (77580ef)
  • fix(ui): wind cardinals upright + fix zoom/position overflow & XTE tofu (cac10bf)
  • fix(ui): upright compass labels + wider bands; restore classic wind screen (fb3c688)
  • docs: AP + wind reference-redesign screenshots at all display sizes (2d91abe)
  • feat(ui): reference glass-cockpit autopilot HUD + decluttered wind dial (b68b622)
  • docs(spec): reference-style autopilot + wind screen redesign (a8e72fe)
  • build(deps): bump checkout v6, setup-python v6, upload-artifact v7, action-gh-release v3 (aa7cf4c)
  • ci: build the harness envs in the matrix (7f025a9)
  • refactor(harness): rebuild protocol harness on shared net infra (OTA-capable) (4f4c067)
  • docs(claude): memory traps — large structs on task stacks; N16R8 memory_type (0aaee76)
  • fix(harness): octal-PSRAM memory_type for DevKitC-1 N16R8 (boot crash) (e88861d)
  • fix(proto): same large-stack-temporary crash in IP target + harness handlers (e4cfe8e)
  • fix(proto): BLE Control handlers crashed target (large stack temporaries) (7594941)
  • docs(spec): align auth wording to plaintext-NVS local-trust model (10d9554)
  • feat(harness): BLE-central soak mode for protocol harness (31d5fa6)
  • docs: espdisp control protocol guide + knob/README/testing updates (987b56f)
  • fix(proto): lock-snapshot shared key in handle_attach; harden ctl key clear (a9ca05b)
  • feat(proto): ctl console commands to set controller color + shared key (ec68bae)
  • feat(plugin): migrate discovery+control onto the protocol lib (fb70565)
  • feat(proto): on-demand BLE central controller (Phase 4.2) (5957e79)
  • fix(proto): byte-guard BLE DeviceRecord read under the 512-byte cap (c6ce2bc)
  • feat(proto): target BLE Control GATT service (bf3e53b)
  • fix(proto): drain pending IP switch/views every worker tick (manager-less path) (570e811)
  • feat(proto): mDNS discovery + IP peer merge into knob_remote (949734a)
  • docs(sim): control-frame overlay renders (1 + 3 sessions, rect + round) (862b1ed)
  • feat(ui): per-controller colored control frame overlay + switch NAK fix (ff93d75)
  • feat(proto): target /api/p2p endpoints (c7d8d57)
  • feat(proto): target session table + view-switch state (proto_target) (c8a8cf6)
  • fix(harness): 3s HTTP timeout + value-init ack structs (b54f156)
  • feat(harness): headless ESP32-S3 controller + IP protocol client (bb08a4a)
  • fix(proto): emit all $defs as TS interfaces; add heartbeat/detach validators + ack tests (e6f62e3)
  • feat(proto): JS lib (ajv validators + version) + make proto + CI freshness (cfeced0)
  • test(proto): cover full-table, last-writer, detach, reap boundary, multi-session; derive version string (9c53058)
  • test(proto): C++ conformance + version/auth/session tests (b9309db)
  • feat(proto): pure version/auth/session-table logic (7f94fbb)
  • feat(proto): C++ generator + generated ArduinoJson records (599e369)
  • feat(proto): conformance fixtures (valid + incompatible + forward-compat) (4d48652)
  • feat(proto): espdisp control protocol v1 JSON Schema (68facf7)
  • docs(plan): espdisp control protocol implementation plan (a35f525)
  • docs(spec): combined delivery + ESP32-S3-DevKitC-1 test harness (0f4d95e)
  • docs(spec): espdisp versioned P2P control protocol (IP + BLE) (4b48ab0)
  • docs: knob testing & simulation guide + encoder-calibration docs (d6ecf66)
  • feat(knob): runtime-tunable encoder counts/detent + direction invert (90c4bbc)
  • test(plugin): pin knob remote-display wire contract + e2e route test (d28a041)
  • feat(sim): render knob menu overlay states (mode/display paging/view) (f5878ee)
  • test(knob): gesture-journey tests + signalk_put_for contract tests (09be940)
  • refactor(knob): extract pure signalk_put_for; route knob_ui AP PUTs through it (b615df0)
  • docs: knob board in README + Remote Knob section, plugin install + deploy guide (e029008)
  • feat(sim): render round 360 knob views for the gallery (9f92ca9)
  • fix(knob): defer remote view-switch HTTP to the manager worker (6ed8d85)
  • feat(knob): enumerate + remote-switch displays via the manager (69fd4b7)
  • feat(plugin): GET /devices/summary + GET /devices/:id/views projections (1c022e2)
  • fix(knob): start encoder task after app queue init; include ctype.h (dd19d06)
  • feat(knob): menu UI overlay, round views, and Knob event dispatch (3feee8a)
  • feat(knob): device/view registry with local dedicated views (2c06990)
  • fix(knob): read button pin directly for held-step flag (41a13e0)
  • feat(knob): encoder + button input task emitting Knob events (Phase D1) (3fc17bb)
  • feat(board): board-gated CST816 touch read for the knob (0632ab4)
  • feat(wind): triangular A/T wind indices + directional current arrow (f36e586)
  • feat(board): board-gated ST77916 QSPI display init for the knob (bd51aed)
  • test(knob): close knob_menu coverage gaps (picker highlight, seed, view wrap) (cc0349f)
  • feat(knob): select-display/select-view nav + switch-view action (0ba9fa0)
  • feat(knob): home engage toggle + mode picker (22dafff)
  • feat(knob): home course adjust (+/-1, +/-5 held, wrap, pre-set) (ec1a0d1)
  • feat(knob): knob_menu pure state-machine interface (7adbaa8)
  • feat(board): knob platformio envs + CI matrix + native filter (6607272)
  • feat(board): waveshare knob board::* implementation (9ba4064)
  • feat(board): gate board_pins.h so knob pulls its own map (99c84c7)
  • feat(board): waveshare knob pin map header (b788c36)
  • docs(plan): Waveshare knob remote implementation plan (8ddeabc)
  • docs(spec): Waveshare ESP32-S3 knob remote controller design (a4864b9)
  • feat: SP4 push-live dashboards - instant config apply via SignalK delta (029fce0)
  • feat(ui): rebuild autopilot screen as wind/compass/route steering (a3d0c09)
  • feat(plugin): autopilot bridge - device PUTs -> KDCube sim command deltas (610d46d)
  • feat(lab): deploy KDCube modeled simulator + tidal-current emission patch (e9368bf)
  • feat(ui): centered current vector + zero-ring, HDG clear of arc, A>>/T>> wind markers (0334a94)
  • feat(ui): direction triangle outside ring + bigger center number; wind AWS/TWS centered (df91af0)
  • docs(stability): manager loop restored (device re-provisioned, heartbeat 200) (6f5fa72)
  • feat(sim): no-overlap/bounds assertion + make sim target + README gallery (0ce731d)
  • feat(sim): headless LVGL resolution harness + per-resolution screenshots (f4dd3af)
  • docs(plan): host LVGL-SDL resolution test harness implementation plan (3f6fafe)
  • docs: update layout-editor guide for glass-cockpit rework + switch-view (6f089c2)
  • feat(plugin): 'switch this device to view' button on device page (0909efa)
  • fix(ui): live rotating needle on small wind + compass widgets (c6dfae0)
  • feat(plugin): sync layout-editor palette to glass-cockpit; fix parity test (a9ffa1b)
  • docs: refresh screenshots to glass-cockpit design + SignalK user guide (80e7854)
  • feat(ui): tap-to-zoom single-value screen (badaa30)
  • feat(ui): wind 48px inner + SOG/SOW corners; dashboard 64px hero numbers (b0b50e3)
  • test(lab): emit navigation.speedThroughWater for the SOW readout (2a639ea)
  • feat(ui): wind screen rework - 64px readouts inside the rose (002bded)
  • test(lab): emit environment.current set/drift from fake_boat (12d4219)
  • feat(ui): drop tile accent rails, glass-cockpit chrome on all tiles (9474af2)
  • feat(ui): glass-cockpit theme - gradient cells, cool palette, chrome tokens (808e994)
  • docs(plan): SP1 complete (B1-B4 shipped+verified, D1/D2 already in place) (6ca817e)
  • feat(mgr): label heartbeat outcome + classify failures (S5) (e78bc7d)
  • refactor(sk): drive stall ladder from pure net_health::evaluate (dffb154)
  • feat(net): pure net_health stall-escalation decision + host tests (de5de37)
  • feat(build): enable -fstack-protector-strong stack canaries (e1b05aa)
  • docs(plan): SP1 root-cause network fix shipped + verified (soak PASS) (69d2461)
  • docs(stability): before/after evidence for internal-heap fix (soak PASS) (0e5e5df)
  • fix(heap): move LVGL draw buffers to PSRAM to end network starvation (46e22e3)
  • docs(plan): mark SP1 workstreams A + C complete (6ef11eb)
  • feat(soak): espdisp soak subcommand + pure verdict logic (15bbd81)
  • docs(stability): record Workstream A re-resolution verification (9.2s fall-through proof) (f4d28c1)
  • fix(manager): re-resolve device address across candidates on fetch failure (fc591a9)
  • docs: SP1 stability implementation plan (3670555)
  • docs: dashboard program design spec + stability evidence capture (c0a9b70)
  • fix: screen semantic correctness + data stability (9c7e178)
  • test: update numeric widget preview PNGs after font/layout polish (e3df375)
  • docs: add architecture notes, load test tools, manager design guide (cd22ea9)
  • feat: proper secrets.h generation + OTA auth + gitignore cleanup (77b9c37)
  • feat: add server-setup provisioning scripts for nav-server (434bba8)
  • fix: resolve four real-device visual defects in UI (73e83a9)
  • fix(heap): drop montserrat_16/18, keep only 14/20/28/38/48 (faad793)
  • test(parity): Playwright snapshots of every widget kind + no-overlap proof (ac737fa)
  • test(parity): editor primary px must map to an enabled lv_font_montserrat_N (c9b6f97)
  • feat(ui): widget polish - bigger numbers, labels track, no overlap (d62eb16)
  • fix(screenshot): yield every 32 rows during PNG encoding (72cb0ec)
  • fix(ui): replace_screen() fires post-build callback for new root (f2333a9)
  • feat(layout): renderer translates editor JSON into device tile screens (0dbf76b)
  • fix(ui): autopilot painter no longer drags tile root on every button (a7f60ad)
  • feat(ui): lazy-load secondary screens, only dashboard built at boot (c97edb9)
  • feat(ui): wind dial parametric on LCD_W/LCD_H for cross-resolution (6671d21)
  • refactor(ui): route screen delegates to QuadGrid template (006110e)
  • refactor(ui): nav + depth screens delegate to QuadGrid template (dcd15a4)
  • feat(ui): path-bound previews + readable compass/gauge on editor and device (971d7f3)
  • feat(ui): widget-kind dispatcher with per-widget painters on device (56aa453)
  • feat(presets): per-display-class tile budgets for all screens (9d65959)
  • test(parity): cross-check editor preview palette + fonts vs device LVGL (dbb4932)
  • feat(ui): align single-field tile rendering with editor preview (54fc014)
  • revert(web): drop ESPAsyncWebServer to restore device data display (5c0435f)
  • feat(editor): windDial widget + Montserrat + device-palette parity (a467b3b)
  • fix(plugin/security): close SSRF + CORS holes on screenshot proxy (6dcc6ac)
  • feat(editor): live device-screenshot preview after save (proxied) (f3bcf6a)
  • feat(editor): searchable metric-path dropdown + per-widget visual preview (1a5505d)
  • fix(web): shrink AsyncTCP task stack to 4 KB to fit constrained heap (cc259ca)
  • feat(web): migrate to ESPAsyncWebServer for binary-body streaming (f6bab1b)
  • feat(screenshot): PNG encoder via ROM miniz + tiered heap breaker (66eef4c)
  • fix(plugin,web): generalize el() prop assignment + heap-breaker tier (f81cbce)
  • fix(plugin): el() dataset assignment fails layout editor on load (dfe4f11)

Flash instructions

Download the merged firmware image for your board target:

  • esp32-4848s040-merged_firmware.bin
  • waveshare-touch-lcd-4-merged_firmware.bin
  • waveshare-touch-lcd-4_3-merged_firmware.bin
  • waveshare-touch-lcd-4_3b-merged_firmware.bin
  • waveshare-touch-lcd-5_800x480-merged_firmware.bin
  • waveshare-touch-lcd-5_1024x600-merged_firmware.bin
  • waveshare-touch-lcd-7_800x480-merged_firmware.bin
  • waveshare-touch-lcd-7b_1024x600-merged_firmware.bin

Single-file flash (covers bootloader, partition table, OTA boot selector, and app):

esptool.py --chip esp32s3 --port /dev/cu.usbserial-* write_flash 0x0 <target>-merged_firmware.bin

Or via authenticated OTA once the device is on the network:

YEYBOATS_OTA_PASSWORD='<ota-password>' make ota DEVICE_IP=<device-ip>

SignalK plugin

The SignalK manager plugin is released separately from the
yey-boats/Instruments-manager repository.