Skip to content

0.10.0

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 May 07:20
· 471 commits to main since this release
fc0e80b

CANShift v0.10.0

A UX-focused release: the device finally reads at a glance. Per-sensor colours, real units everywhere, smaller decimals, a diag drawer that actually closes, and a top bar that hides what it doesn't know yet. The Studio canvas now mirrors the firmware pixel-by-pixel for everything we ship as defaults.

Big internal cleanups too: warningLevel and dangerLevel are now a single threshold, the demo dashboard ships with the sensor palette wired up, and a Rust spike landed for ota_hmac (phase 3 — staticlib linked into PlatformIO without growing flash).

Highlights

  • Semantic per-sensor palette. Each metric draws in its native colour (coolant blue, oil pressure green, boost violet, AFR magenta, RPM cyan, throttle orange, IAT light blue, …) below the threshold, warning red above. Two zones only — the old three-zone tinting is gone.
  • Units everywhere, by default. Every gauge / bar / numeric widget shows its unit (°C, km/h, bar, kPa, V, AFR, %) without per-widget configuration. Pulled from the bound signal's unit field in signals.json; cfg.suffix still wins when set manually.
  • Smaller fractional digits on AFR / voltage / lambda / pressure readouts — the integer part stays headline-size, the .X / .XX renders at ~70 %. Arc gauges + numeric widgets, firmware and Studio match.
  • Diag drawer rebuild. Full-screen panel, swipe-up to open from anywhere, big visible X to close (no longer shares coordinates with the top bar's day/night toggle), scrollable content, ECU flag dots now visibly circular instead of squarish.
  • Top bar de-clutter. Signal slots with no live reading hide themselves instead of showing a misleading --.- placeholder. Mode-flag badges (ALS, LC, FS, TC, MAP) gained a hidden-on-startup state so they only appear once the ECU asserts them.
  • Theme toggle survives page rebuilds. The day / night icon used to vanish into a fragmented heap after a few toggles; LVGL image cache doubled to 24 entries, theme icons get re-warmed before every rebuild, the post-rebuild FS-open guard relaxed (with graceful fallback if the pool is still starved).
  • Error bar — visible X + no-reboot dismiss. Hit target widened, glyph swapped to uppercase, dismiss path guarded against the low-heap LVGL allocations that previously triggered the assert handler on press.

Firmware

  • Demo dashboard migrated: 4 pages (overview / engine / fluids / controls), every gauge opts into the sensor palette via iconName, controls page slimmed to 4 buttons (MAP1, MAP2, Launch, Anti-lag) with strong on/off contrast.
  • Numeric widget value re-centered (was anchored at the bottom of the cell post flex-row refactor).
  • Engine page bottom row split: TPS numeric (160×56) + Battery numeric (160×56) instead of a single full-width horizontal bar.
  • Overview ↔ engine: Gear moved to engine (xl), IAT moved to overview (l).
  • -- placeholder replaces em-dash (no more U+2014 glyph spam in the serial log).
  • Lambda unit renamed from λ to AFR (Orbitron doesn't carry the Greek small letter lambda).
  • Per-row dismiss on the error drawer with stable newest-first row→index mapping.
  • Optimistic SignalStore write on toggle-button click — the diag-drawer flag turns red on tap even without a CAN echo (then reconciles when the ECU answers).
  • Top bar mode-flag badges (ALS / LC / FS / TC / MAP slot) — visible only while the bound signal is high; adjacent separators auto-hide so the bar stays tight.
  • Orbitron 28 / 48 px fonts restored.
  • BLE write size capped before JSON parse (prevents the UI thread from chewing oversize payloads).
  • USB JSON snprintf paths detect truncation and surface a warn line.
  • BLE GATT writes detect serializeJson truncation.
  • PUT_FILE path validation flipped from blacklist to strict allowlist.
  • Concurrent lazy page-build requests now coalesce instead of double-allocating.
  • TWAI driver tick guarded when uninstalled; init retries on heap recovery.
  • Boot-time log line DIAG_DRAWER init done — z-reaffirm + scroll + 12px badges + frac digits build so you can confirm at a glance which firmware is on the chip.

Studio

  • Canvas preview keeps per-widget colours instead of collapsing them to the page palette — finally matches the rail thumbnails.
  • Default unit overlay on numeric widgets (small grey, right of the value, baseline-aligned) and on arc gauges (centred below). Falls back to the built-in MaxxECU catalog when the local signal store is empty, so units appear on first launch without picking a profile.
  • Smaller fractional digits in the Canvas preview, matching the firmware.
  • Signal binding in the property panel is now a Radix Select dropdown listing every loaded signal as signal_name — unit. Picking a signal auto-applies suffix / min / max / dangerLevel from the catalog.
  • Horizontal bar gauge orientation removed from the bar-gauge picker (the layout didn't read well; only vertical remains).
  • defaultSimConfig.ts mirrors the new firmware demo (palette + controls page + Gear/IAT swap + TPS+Battery split).
  • Config validation on File → Open and session restore paths.
  • CAN-frame flush interval cleared on shutdown.
  • IPC: every USB connection transition now published to the renderer (no more stale connected indicators).
  • Detached CLI window registers setWindowOpenHandler so external links don't open silently.
  • mainWindow ref nulled out in the closed handler — fixes a latent dangling-pointer warning.

Core (@tmbk/canshift-core)

  • SensorPalette schema + per-sensor OK / warning colour table (shared by firmware + Studio + mobile).
  • Threshold collapse: warningLevel dropped, dangerLevel is now the sole numeric threshold across gauge / bar configs. Migration runner upgrades existing dashboards.
  • New 1.15 → 1.16 → 1.17 migration steps; CURRENT_SCHEMA_VERSION bumped accordingly.
  • Schema fixture test confirms the bundled dashboard.json validates clean against the catalog.
  • Signal protocol id renamed maxxecu_v1.2 → generic custom_v1.0 so the open-source repo stops mentioning a specific brand by default.
  • Export the ButtonAction discriminant tuple + type guards for downstream consumers.
  • LIGHT_TOKENS made internal until the light-theme consumer lands.

Mobile

  • DashTopBar sim / BLE mode now reactive via the Zustand store (no more stale toggle on app resume).

Rust spike (firmware)

  • ota_hmac ported to Rust in three phases: host parity tests → C ABI bridge → staticlib linked into PlatformIO.
  • Δ flash −16 B once weak memcpy / memmove / memset / memcmp / bcmp symbols in the Rust library are localized so ESP-IDF's strong IRAM versions win at link time (fixes a boot-time EXCCAUSE 7 we hit while validating).
  • Behind the USE_RUST_OTA_HMAC build flag — the C++ implementation stays the default until the on-device 1 h soak passes.

CI / chores

  • Sanitizers, clang-tidy, and the firmware boot-smoke (QEMU) checks gating every PR.
  • --depth=1 dropped from the base-ref refetch so merge bases stay reachable on long-lived branches.
  • Documentation pass to make the repo ECU-agnostic — MaxxECU / VR6 specifics moved into examples, FIRST_FLASH translated to English.

Known limitations

  • Heap fragmentation after several rapid day/night toggles can still trip the LVGL FS-open guard on icon decodes. Mitigations are in place (preload before and after rebuild, cache size doubled, heap floor relaxed) but the deeper SPIFFS-driver fix is tracked in #895.
  • A USB task watchdog reboot path was observed once after touch calibration on a heap-starved boot. Tracked in #976.
  • Disconnecting the device in Studio immediately auto-reconnects within 2 s — there's no manual-disconnect flag yet. Tracked in #977.
  • The Studio Canvas day / night toggle preview drifts from the firmware render in a few places. Tracked in #957.

Upgrade notes

  • Flash both binary AND SPIFFS for the new dashboard / signals to take effect:
    pio run -e crowpanel_28 -t upload
    pio run -e crowpanel_28 -t uploadfs
    
  • After flash, the serial log should show DIAG_DRAWER init done — z-reaffirm + scroll + 12px badges + frac digits build at boot. Grep for it to confirm the new firmware is on the device.
  • Existing dashboards are auto-migrated to the 1.17 schema on first load; warningLevel is dropped and dangerLevel becomes the single threshold. Re-save in Studio to persist.