Skip to content

Car status dashboard: ROTA + POTA-to-validate + session-fallback rows - #730

Closed
patrickrb wants to merge 2 commits into
devfrom
feat/car-status-dashboard
Closed

Car status dashboard: ROTA + POTA-to-validate + session-fallback rows#730
patrickrb wants to merge 2 commits into
devfrom
feat/car-status-dashboard

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

What

Implements the Pane-layout status dashboard from the FT8AF CarPlay/Android Auto design exploration (Claude Design project). Extends the existing Android Auto status screen with the design's activation dashboard, whose defining behavior is "activation rows drop out, session stats take the slot."

Beside the existing POTA line, the pane now shows:

  • ROTA rowROTA <trip> · N QSOs with X.X mi driven this activation, read from RotaTripManager.state.
  • POTA validation secondaryN more to validate the activationActivation validated (POTA's 10-QSO program rule; no existing constant, so POTA_ACTIVATION_TARGET = 10 is defined here).
  • Band decodes secondaryN decodes last cycle.
  • Session-fallback rowSession · N QSOs / Last logged JA1XYZ · 20m · 41 min, shown only when neither POTA nor ROTA is active.

How

Decision/format logic lives in pure, Android-free helpers in CarQsoStatus.kt (buildCarActivationRows, potaValidateSpec, buildCarSessionRow, formatMiles, minutesAgo, carDecodesSecondary), unit-tested directly. QsoStatusScreen stays thin — it maps the app singletons (PotaSessionManager, RotaTripManager, GeneralVariables, FT8TransmitSignal.mutableQsoCompletedAt) into those helpers.

Both render paths use the same builder: the PaneTemplate fallback (older hosts) and the map Surface overlay (modern hosts) — CarSurfaceState.potaText is generalized to activationLines so ROTA/session appear on real devices, not just old hosts. The shared buildCarQsoStatus is left untouched, so the existing status/slot/band logic and its tests are unaffected.

Notes / judgment calls

  • POTA and ROTA are practically mutually exclusive (parked at a park vs. roving on roads), so the rare both-active pane could hit a 4-row host limit and drop the last row; the common single-activation and idle cases fit.
  • "Session QSOs" uses the today/yesterday worked-callsign set (QSL_Callsign_list_today) — the only cheap in-memory count; "last logged" is best-effort from the last partner + completion timestamp. Both documented at the call site.

Testing

  • CarDashboardTest.kt17 new tests, 0 failures; existing car tests (incl. the manifest-wiring Robolectric test) still green: ./gradlew testDebugUnitTest --tests 'radio.ks3ckc.ft8af.car.*'.
  • Full assembleDebug passes (validates the 9 new string resources + manifest merge).
  • ⚠️ Not driven on a real head unit: no device was tethered, and Android Auto needs a DHU/AAOS host. The debug inject receiver also has no ROTA path yet — a follow-up could add one so the ROTA row is screenshot-testable on an emulator.

🤖 Generated with Claude Code

Extends the Android Auto status screen with the activation dashboard from
the CarPlay design exploration (Pane layout). Adds, beside the existing
POTA line:

- a ROTA (Roads On The Air) row — "ROTA <trip> · N QSOs" with mileage
- a POTA "N more to validate the activation" / "Activation validated"
  secondary (POTA's 10-QSO program rule; no existing constant)
- a "N decodes last cycle" secondary on the band row
- a session-summary row ("Session · N QSOs" / "Last logged …") that takes
  the slot when no POTA/ROTA activation is running — the design's
  "activation rows drop out, session stats take the slot" behavior

The decision/format logic lives in pure, Android-free helpers in
CarQsoStatus.kt (buildCarActivationRows, potaValidateSpec, buildCarSessionRow,
formatMiles, minutesAgo, carDecodesSecondary), unit-tested in CarDashboardTest.
QsoStatusScreen maps the app singletons (PotaSessionManager, RotaTripManager,
GeneralVariables, FT8TransmitSignal) into those helpers.

Both render paths use the same builder: the PaneTemplate fallback (older
hosts) and the map Surface overlay (modern hosts) — CarSurfaceState.potaText
is generalized to activationLines so ROTA/session show on real devices too.
buildCarQsoStatus is left untouched, so the shared status/slot/band logic and
its tests are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@patrickrb
patrickrb requested a lite review from Copilot August 9, 2026 07:20
@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.81967% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.93%. Comparing base (7052afc) to head (f75a0e8).

Files with missing lines Patch % Lines
...n/kotlin/radio/ks3ckc/ft8af/car/QsoStatusScreen.kt 0.00% 27 Missing ⚠️
...in/radio/ks3ckc/ft8af/car/CarMapSurfaceRenderer.kt 0.00% 1 Missing ⚠️
...main/kotlin/radio/ks3ckc/ft8af/car/CarQsoStatus.kt 96.87% 0 Missing and 1 partial ⚠️
...n/kotlin/radio/ks3ckc/ft8af/car/CarSurfaceState.kt 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                dev     #730      +/-   ##
============================================
+ Coverage     35.89%   35.93%   +0.03%     
  Complexity      289      289              
============================================
  Files           248      248              
  Lines         30512    30565      +53     
  Branches       4031     4046      +15     
============================================
+ Hits          10952    10983      +31     
- Misses        19208    19229      +21     
- Partials        352      353       +1     
Flag Coverage Δ
android 17.76% <50.81%> (+0.11%) ⬆️
native 9.93% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...in/radio/ks3ckc/ft8af/car/CarMapSurfaceRenderer.kt 0.00% <0.00%> (ø)
...main/kotlin/radio/ks3ckc/ft8af/car/CarQsoStatus.kt 95.04% <96.87%> (+0.84%) ⬆️
...n/kotlin/radio/ks3ckc/ft8af/car/CarSurfaceState.kt 26.66% <0.00%> (ø)
...n/kotlin/radio/ks3ckc/ft8af/car/QsoStatusScreen.kt 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a pane-layout “activation dashboard” to the Android Auto/Car status UI so that POTA/ROTA activation rows appear while activating and collapse into a session-summary row when idle, and mirrors those activation lines onto the map surface overlay.

Changes:

  • Introduces pure helper functions for activation/session row selection and formatting (POTA “to validate”, ROTA miles, session “last logged”, decode-count secondary), plus unit tests.
  • Updates QsoStatusScreen to build activation/session rows (POTA + ROTA + session fallback) and to render them both in the PaneTemplate path and the Surface overlay.
  • Adds new string resources for the new dashboard rows.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
ft8af/app/src/test/kotlin/radio/ks3ckc/ft8af/car/CarDashboardTest.kt New unit tests covering the pure dashboard helpers (activation/session selection + formatting).
ft8af/app/src/main/res/values/strings_compose.xml Adds string resources for POTA validation, ROTA row/miles, session fallback, and decode-count secondary.
ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/car/QsoStatusScreen.kt Wires new dashboard helpers into the pane rows and the surface overlay; adds decode-count secondary under band line.
ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/car/CarSurfaceState.kt Generalizes surface overlay status from a single POTA line to a list of activation/session lines.
ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/car/CarQsoStatus.kt Adds pure helpers: activation/session row builders, POTA validation spec, miles/minutes formatting, decode-count secondary.
ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/car/CarMapSurfaceRenderer.kt Renders the new activationLines list on the surface overlay instead of only POTA text.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/car/QsoStatusScreen.kt
carDecodesSecondary read mutableFt8MessageList.size, which accumulates across
cycles when clearDecodesEveryCycle is off (the default) — the "N decodes last
cycle" secondary would show a stale, growing count. Use vm.currentMessages
(the per-cycle label overlay), which is refreshed each cycle and cleared on a
silent slot, so the count reflects the latest cycle and drops to 0 correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@patrickrb

Copy link
Copy Markdown
Owner Author

Heads up: holding this PR rather than merging it right now.

It conflicts structurally with #729 (Restore Android Auto — Play-approved IOT shape), which is merging first. #729 deletes CarMapSurfaceRenderer.kt, CarSurfaceState.kt, CarMapProjection.kt, and CarPanelLayout.kt because the NAVIGATION-category map/surface variant was rejected by Play review. This PR extends that same surface overlay, so once #729 lands, this branch will both conflict and re-introduce the rejected surface path.

The Copilot review comment here (per-cycle decode count) has been verified and fixed on this branch regardless.

Next step (separate follow-up): rebase on the new dev and port only the net-new, host-agnostic features from here — the POTA "N more to validate" secondary, the session-fallback row, and the per-cycle decode count — onto #729's pane path, dropping the surface-overlay changes. Leaving this open as the reference for that work.

@patrickrb

Copy link
Copy Markdown
Owner Author

Superseded by #731, which implements the same dashboard design on the pane path that landed with #729 (this PR was built on the map/surface overlay #729 deleted). Closing in favor of #731; reopen if needed.

@patrickrb patrickrb closed this Aug 9, 2026
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