Skip to content

Replace Battery tab with Troubleshooting tab#88

Merged
cormoran merged 4 commits into
mainfrom
claude/sleepy-sutherland-e0e316
Jul 6, 2026
Merged

Replace Battery tab with Troubleshooting tab#88
cormoran merged 4 commits into
mainfrom
claude/sleepy-sutherland-e0e316

Conversation

@cormoran

@cormoran cormoran commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Removes the unstable "Battery" tab (battery history charting via recharts) and the unused, never-wired-up HealthCheckPage.
  • Adds a new Troubleshooting tab in the same position, with four independently-degrading diagnostic sections:
    • Device Info — build/hardware/ZMK-config/runtime details from the firmware (zmk__device_info).
    • Stability (Watchdog) — freeze/crash/reset incident history, including split-peripheral relay + live push notifications (cormoran__watchdog).
    • Key Switches — per-device KScan config and chatter/stuck-switch detection from paginated press/release statistics (cormoran__kscan_diagnostics).
    • Trackball Sensor (PMW3610) — sensor info + on-demand surface diagnostics; handles the subsystem being SECURED (ZMK Studio lock) (cormoran__pmw3610).
  • Adds a "Copy Support Report" action that assembles a stable, English-only Markdown report (never translated) from whatever data is currently loaded, so users can paste it when contacting their keyboard's seller.
  • Each section resolves its own firmware subsystem independently — one missing/erroring module never breaks the other three.

Firmware modules

Protos for all four were vendored verbatim under proto/ and regenerated via npm run generate (buf + ts-proto). Demo-mode handlers were added for all four so the tab is fully exercised in the demo transport (src/lib/transport/demo-*.ts), replacing the old battery demo handler.

i18n

All new UI strings are wired through t() with natural Japanese translations added to src/i18n/translations.ts (Troubleshootingトラブルシューティング). The support report content itself is intentionally NOT translated — its keys/labels are always English so a keyboard seller gets a stable, comparable format regardless of the reporter's UI language.

Screenshots

TODO: add screenshots

Test plan

  • npm test — 25 suites, 235 passed / 1 skipped (pre-existing, unrelated skip in useRuntimeInputProcessor), 0 failed.
  • npm run lint — clean, no errors or warnings.
  • npm run build — succeeds (buf generate + tsc -b + vite build).

New tests added:

  • src/lib/__tests__/troubleshootingReport.test.ts — pure-function tests for the report builder (all sections present/absent/erroring, English-only output guarantee).
  • src/pages/__tests__/TroubleshootingPage.test.tsx — renders with no subsystems (4 "not available" notices), renders with mocked per-section data, verifies one section's error doesn't affect the others, verifies the copy-to-clipboard flow.
  • src/lib/transport/__tests__/demo-watchdog.test.ts — status/pagination/delete-one/delete-all/peripheral-error paths.
  • src/lib/transport/__tests__/demo-kscan-diagnostics.test.ts — info/device/paginated stats/reset-stats, and that exactly one chattery suspect key is detected.

Follow-up (UX enhancements)

Building on the four sections above, a follow-up commit adds three UX improvements:

  • Collapsible sections — every section now starts collapsed (a lot of detail lived in each one); the header is clickable (chevron, aria-expanded) and always shows a compact status summary badge even while collapsed, so you can tell at a glance whether a section needs attention:

    • Device Info: "OK" (green) or "N devices not ready" (red).
    • Watchdog: "No incidents" (green) or "N incidents" (amber/red), plus a red "recording paused" indicator when the incident store is full.
    • Key Switches: "OK" (green) or "N suspect keys" (amber).
    • Trackball: "OK" (green) or "init error" (red).
      Data still auto-fetches in the background regardless of collapse state, so "Copy Support Report" keeps working; the one exception is the (heavier) kscan wiring topology below, which now loads lazily on first expand.
  • Interactive KScan keyboard view — replaces the external "open the dedicated web UI" link with an inline, interactive keyboard preview built from the official Studio physical-layout RPC and the kscan wiring topology:

    • Row GPIO pin buttons on the left, column pin buttons along the bottom (one per unique wire actually used by the layout).
    • Hovering (mouse or keyboard focus) a pin button highlights every key on that line; clicking pins it persistently (multiple lines can stay pinned at once, with a "Clear" button to reset) — the primary interaction on touch, where hover doesn't apply.
    • Hovering a key highlights its row/column pins in the other direction.
    • Per-key status markers: a muted dashed marker for untested keys (0 presses), an amber/red triangle badge for suspect keys (chatter or press/release mismatch), and a dashed pin-less style for keys with no wiring info (e.g. a split peripheral half, where wiring is only known centrally).
    • A tooltip on key hover shows position, matrix row/col, row/col GPIO port+pin, press/release counts, min repress gap, and chatter counts.
    • The driver-info rows and suspect-key stats table move into a collapsed <details> below the visualization.
  • Trackball live frame streaming — adds a "Live sensor view" to the Trackball section: a size selector (19–22 px per side), "Capture Once" for a single frame, and a Start/Stop Streaming toggle that subscribes to the sensor's FrameStreamChunk notifications and renders each completed frame to a canvas (nearest-neighbor upscaled) with a live fps counter and per-frame stats (pixels captured, complete, invalid-byte count, capture time). Capture Once is disabled while streaming (the firmware shares one frame buffer between the two). The stream stops on unmount, on disconnect, and resets its UI state if Studio locks mid-stream (the firmware silently drops the stream on lock).

Demo mode was extended to exercise all three: the demo kscan handler now models a full 5×12 matrix topology (layout/device/GPIO paging) covering the DYA Dash's 59-key layout, and the demo pmw3610 handler synthesizes an animated radial-gradient frame for both one-shot capture and a ~5fps notification-based stream.

🤖 Generated with Claude Code

Removes the unstable Battery history feature and the unused HealthCheckPage,
and adds a new Troubleshooting tab with four independent diagnostic
sections (Device Info, Stability/Watchdog, Key Switches, Trackball Sensor)
backed by four new vendored firmware-module protocols, plus a
"Copy Support Report" action that composes a stable, English-only Markdown
report for keyboard sellers/support.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

🚀 Cloudflare Workers Preview

Preview URL: https://00225b54-dya-studio.cormoran707.workers.dev

Deployed from commit fdebf15

codex and others added 2 commits July 7, 2026 01:35
…all live streaming

Three UX enhancements to the Troubleshooting tab:

- Sections now collapse by default (SectionCard gets a clickable header,
  chevron, aria-expanded, and a status summary badge visible even while
  collapsed) so users open only what they need; data still auto-fetches
  in the background for the support report.
- KScan Diagnostics gains an interactive keyboard preview replacing the
  external diagnostics-site link: row/column GPIO pin buttons that
  highlight wired keys on hover/click (pins can be pinned), suspect/
  no-record markers, and a tooltip with wiring + press stats. Backed by
  a new topology fetch (useKscanDiagnostics.loadTopology, lazy on first
  expand) and src/lib/kscanTopology.ts (ported wiring-resolution logic).
- Trackball section gains a "Live sensor view": one-shot frame capture
  and continuous streaming from the PMW3610 sensor, rendered to a
  canvas with nearest-neighbor upscaling and an fps counter. Backed by
  src/lib/pmw3610Frame.ts (frame (re)assembly, ported with tests) and
  streaming/capture RPC plumbing added to usePmw3610.

Demo transport updates so demo mode exercises all of the above:
kscan topology (layout/device/GPIO paging) now models the DYA Dash
59-key layout, and the pmw3610 handler synthesizes capture/stream
frames with a proper notification-based stream loop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…i18n/demo conflicts

Union-merge main's Connection tab (os-detection, default-layer) with our
Battery-to-Troubleshooting tab replacement. Renumbered demo subsystem
indices (watchdog/kscan-diagnostics/pmw3610 now 10-12, os-detection/
default-layer moved to 13-14) to avoid collisions, and dropped the
Battery-specific i18n strings while keeping the new Connection strings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Vendor the current upstream pmw3610.proto (adds PixelFormat PG7/RAW8
enum, CaptureFrameResponse.format, FrameStreamChunk.format, and the
peripheral-relay `source` fields for wire-compat) and regenerate the
TS bindings. Thread PixelFormat through pmw3610Frame.ts's
assembleFrame/isValidPixelByte/pixelByteToGray/frameToRgba, and through
usePmw3610/Pmw3610FrameViewer so captured/streamed frames render
correctly under either format. The demo transport now emits RAW8 for
streaming (exercising the new high-fps burst path) and PG7 for
one-shot capture (exercising the legacy path), with tests covering
both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cormoran cormoran merged commit 7fd6653 into main Jul 6, 2026
3 checks passed
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.

2 participants