Skip to content

feat(ui): render LiveValue.text enum labels in gauge + CSV - #64

Merged
ohgeeceee merged 2 commits into
mainfrom
feat/u8-enum-frontend-v2
Jul 15, 2026
Merged

feat(ui): render LiveValue.text enum labels in gauge + CSV#64
ohgeeceee merged 2 commits into
mainfrom
feat/u8-enum-frontend-v2

Conversation

@ohgeeceee

Copy link
Copy Markdown
Owner

Wires the frontend half of the u8_enum feature shipped to the backend in PR #60 (commits 643bb24, 995a209). With this change, opening Live Data with a B58 profile renders the new gear and engine_state parameters as text gauges ("3rd", "Running") instead of as a 0.0 needle pinned to min.

What ships

  • src/js/gauges.jsGauge gains a text-mode rendering path:
    • set(value, label?): when label is non-null, the gauge enters text mode; otherwise it behaves exactly as before.
    • tick(): skips the easing loop in text mode (labels are discrete, not numeric).
    • draw(): renders the dial face (kept for visual consistency with adjacent numeric gauges), then either the text label centred with the unit underneath, or the existing dial / ticks / needle / numeric readout. Long labels auto-shrink the font from 22 → 12 px so words like "Cranking" or "Overrun" fit without clipping.
    • textOverride field on the instance; defaults to null so numeric gauges are unchanged.
  • src/js/main.js:
    • pollOnce (line 720): ensureGauge(v).set(v.value, v.text).
    • logTick (line 1347): stores point.text alongside y for each logged sample.
    • buildLogCsv (line 1584): emits the label as a quoted CSV cell (JSON.stringify(p.text)) when present, falling back to the existing two-decimal numeric format otherwise. Result: a B58 gear log exports 0.00,"P/N",0.00,"1",... instead of 0.00,0,0.00,1,....
  • CHANGELOG.md: [Unreleased]### Added entry referencing PR feat(data): u8_enum decoder + per-parameter enum-map pipeline #60.

Protected-path flags

None touched. transport/, protocol/, commands.rs, and bmw_diag/core/** are all unchanged. This is a frontend-only PR.

Scope deliberately deferred

  • Chart rendering for enum params — categoricals over time (e.g. a gear line graph that steps from 0 → 1 → 2 → 3 → 4) are a meaningful UX problem worth their own design pass. The chart still renders an enum param as its numeric value (always 0.0 today) when a user opts in via the existing checkbox. No regression; no new behaviour here.
  • Parameter Explorer enum editor — letting users author enum maps in-app is a UX-heavy follow-up. Use TOML for now.
  • Reformatting drift in the wider repo. Pre-existing.

Verification

  • cargo test --lib34/34 passing (no Rust touched; verified on clean origin/main first).
  • node --check src/js/main.js src/js/gauges.js — clean syntax.
  • Manual visual check: the system reminder flagged this is creative UI work; I have NOT launched Tauri to confirm the gauge canvas renders the label text correctly across font-size and label-length combinations. The auto-shrink loop has been tested by reading the math: at 22 px with the default r=74, the gauge accepts labels up to ~118 px wide before shrinking. Real-world BMW labels ("P/N", "1", "Cranking", "Running", "Idle", "Overrun", "Shutdown") are all under 90 px in 22 px Segoe UI, so no shrink should be needed in practice.

Refs

Risk + rollback

Single revert, no migrations, no schema, no async surfaces touched. Rollback restores the gauge to numeric-only and the CSV to numeric-only exports.

@ecc-tools

ecc-tools Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

DB_PATH=""

P2 Badge Avoid overwriting the resolved DB path

This new resolver is dead code in the normal production case: after it computes BEEMUU_DATA_DIR or /var/www/beemuu/data/beemuu.db, the assignment below resets DB_PATH back to ${BEEMUU_DB_PATH:-/var/www/beemuu/backend/data/beemuu.db}. On hosts using the documented new /var/www/beemuu/data layout without BEEMUU_DB_PATH, the backup still looks at the old backend path and exits; please remove the later reassignment or fold the resolver into it.


pub enum_map: std::collections::HashMap<u8, String>,

P2 Badge Round-trip enum maps when exporting profiles

With this new per-parameter enum_map, exporting a community profile that contains u8_enum params through export_profile/profile_to_toml loses the map: the TOML still emits decode = "u8_enum" but no enum = { ... }, so importing that export creates empty maps and read_live_data never emits those enum values. Please serialize non-empty enum maps in profile_to_toml so B58/N55 exports remain usable.



P2 Badge Keep unknown enum bytes visible

With the new best-effort enum profiles, any raw byte that is missing from enum_map takes this continue path without pushing a LiveValue. In those unverified/new ECU states the gauge and logging row disappear instead of showing an unknown/raw value, which prevents users from seeing or capturing the byte needed to extend the map; please emit a fallback text/raw value when decode_enum_string returns None.


if (advOpen && kind === "kdcan") await refreshPorts();

P2 Badge Refresh K+DCAN ports even when options are collapsed

When a user switches from Simulator to K+DCAN while the new connection-options panel is collapsed, advOpen is false so this no longer calls refreshPorts(). The hidden conn-port select then stays empty, and clicking Connect sends an empty port to the K+DCAN transport instead of the available serial device; the old handler refreshed ports on every K+DCAN selection. Please refresh the port list regardless of the collapsed state, or before connecting.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ohgeeceee added a commit that referenced this pull request Jul 15, 2026
Locks down the pure helpers introduced (logically) by PR #64 so a
future refactor of main.js / gauges.js can't silently drift the CSV
emission rules or the gauge numeric clamp. A regression here would
re-break the "B58 gear log exports 'P/N,1,2,3' instead of '0,1,2,3'"
behaviour #64 just shipped.

- src/js/live_format.js: dual-context module with two pure helpers,
  csvCell(point) and clampGaugeValue(value, min, max). Loads in the
  browser via the existing <script> tag pattern (sets window.LiveFormat)
  and `require()`s cleanly under Node for the test harness.
- src/js/test/live_format.test.cjs: eight tests covering every branch
  of csvCell (numeric, enum, comma-bearing label, missing, empty
  text) and clampGaugeValue (in-range, below, above, equal bounds, NaN).
  Uses Node's built-in `node:test`; no framework added.
- src/js/gauges.js, src/js/main.js: Gauge.set and buildLogCsv now
  call the helpers instead of inlining the rules. No behaviour change.
- src/index.html: loads live_format.js before gauges.js / main.js so
  window.LiveFormat is available when those run.
- package.json: adds `test:js` script that runs `node --test
  src/js/test/*.test.cjs`. Existing `test:dtc` unchanged.

The test harness deliberately stays small. There is no JS test runner
in the repo today; the only existing JS tests are under server/dtc/test
and use the same `node --test` runner. Extending the pattern to the
frontend keeps the toolchain uniform.

Verified locally:
- npm run test:js → 8/8 pass
- node --check on the three changed JS files
- cargo test --lib → 34/34 (no Rust touched)

Refs: PR #64 (gauge + CSV wiring), LiveValue.text from PR #60.
Wires the frontend half of the u8_enum feature shipped to the backend
in PR #60 (commits 643bb24, 995a209). With this change, opening Live
Data with a B58 profile renders the new `gear` and `engine_state`
parameters as text gauges ("3rd", "Running") instead of as a 0.0
needle pinned to min.

- src/js/gauges.js: Gauge constructor stores textOverride = null;
  Gauge.set(value, label?) enters text mode when a label is present
  (dial, ticks, and needle hidden; label drawn centred with unit
  underneath; font auto-shrinks 22 → 12 px so longer labels fit);
  Gauge.tick() skips the easing loop in text mode since labels are
  discrete. Numeric path is byte-identical.
- src/js/main.js: pollOnce passes v.text through to Gauge.set.
  logTick stores point.text on each logged point. buildLogCsv emits
  the label as a quoted CSV cell when present so a gear-change log
  exports `0.00,"P/N",0.00,"1",...` rather than `0.00,0,0.00,1,...`.
- CHANGELOG.md: [Unreleased] entry under Added.

No backend/protected-path edits: transport/, protocol/, commands.rs,
and bmw_diag/ are all untouched. Verified on clean origin/main:
`cargo test --lib` 34/34, `node --check` clean on both JS files.

Refs: PR #60 (backend), LiveValue.text field, UNIQUE_FEATURES.md §1.
@ohgeeceee
ohgeeceee force-pushed the feat/u8-enum-frontend-v2 branch from a708c54 to dbd4dce Compare July 15, 2026 06:27
@ecc-tools

ecc-tools Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@ohgeeceee
ohgeeceee merged commit 39e2ef0 into main Jul 15, 2026
6 of 7 checks passed
@ohgeeceee
ohgeeceee deleted the feat/u8-enum-frontend-v2 branch July 15, 2026 06:31
ohgeeceee added a commit that referenced this pull request Jul 15, 2026
…66)

PR #64 added the gauge text-mode rendering and the CSV enum-label

fidelity. PR #65 added the npm run test:js harness around the pure

helpers in src/js/live_format.js. PR #66 added the wider-stance

decode_enum_string_or_unknown so U8Enum samples with bytes that

aren't in the profile enum_map surface as 0xNN ? instead of

disappearing. None of the three had an [Unreleased] entry; this

commit adds them so the next release notes compile cleanly.
github-actions Bot pushed a commit that referenced this pull request Jul 15, 2026
…66) (#68)

PR #64 (gauge text-mode rendering, CSV enum-label fidelity).

PR #65 (npm run test:js harness around src/js/live_format.js).

PR #66 (wider-stance decode_enum_string_or_unknown so unmapped

U8Enum bytes surface as 0xNN ? instead of disappearing).

All three shipped to main but were missing from [Unreleased].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant