Starter display: boundary v0 client, readout, mark button, CI
CI / Analyze & Test (push) Successful in 12s
CI / Debug APK (push) Successful in 57s

Connects to svc-gw over one WebSocket, heartbeats, treats timeout_ms of
silence as a dead link, and retries commands under the same id until acked.
Shows link state, signals with stale/null/missing told apart, the raw stream,
a mock banner on the surface, and a Mark button that stamps the recording.
Android: keeps the screen on and binds the process to the USB NCM network
when the gateway is on it. CI mirrors android-stuff's host-mode runner setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-09 20:23:00 +09:00
parent 62c6a79f89
commit 50081d5417
10 changed files with 770 additions and 132 deletions
+43 -5
View File
@@ -7,8 +7,10 @@ updated: 2026-10-09
## Order
1. MQTT client, subscribing to the retained vehicle topics. Text readout only —
prove the contract before drawing anything.
1. Text readout of the boundary stream — prove the contract before drawing
anything. **Starter in place:** connects to `svc-gw` (protocol v0, contracts
`docs/BOUNDARY.md`), shows link state, every signal with stale/null/missing
told apart, the raw message log, the mock banner, and a Mark button.
2. Gauges.
3. Moving map: MapLibre against the PMTiles basemap served by the Orin, with the
position from `yukart/gnss/fix`. No routing involved.
@@ -19,9 +21,8 @@ needs no routing engine at all. Routing is the expensive last fraction.
## Open
- **Transport.** Whether the app reaches the broker directly or goes through
`svc-gw` is decided in that repo — see its initial plan. The physical link is
settled (below).
- **Transport.** The app talks to `svc-gw` over one WebSocket (boundary v0).
Whether high-rate topics later bypass it to the broker is decided in `svc-gw`.
- **CJK labels.** MapLibre cannot ship Japanese glyph sets as SDF ranges. Local
font rendering must be configured, or labels will be slow or absent.
- **Sunlight.** A typical tablet is unreadable through a windscreen in daylight.
@@ -96,3 +97,40 @@ has to arrive here to be heard.
without either side coordinating.
- The microphone stays on the Orin. This app never captures audio; ASR input never
crosses the boundary.
## Development workflow
| Where | Device link | Gateway |
|---|---|---|
| Desk | tablet USB → halogen, ADB over USB | `cargo run -- --mock` in `svc-gw` on halogen; app built with `--dart-define=YUKART_GW=ws://<halogen LAN IP>:7700/`, or the address changed at runtime by tapping the link bar |
| Car | tablet USB → Orin (tablet is USB host; no ADB over USB) | `yukart-gw.service` on the Orin, `ws://192.168.55.1:7700/`, the default |
The app binds the process to the USB Ethernet network only when the gateway
address is on `192.168.55.0/24`, so a desk build pointed at halogen over WiFi is
not routed into a dead USB link.
### ADB in the car, without a hub
The tablet's only USB port is the Orin link, and in it the tablet is the host —
USB debugging is unavailable there. ADB over TCP is not, and it travels over the
same NCM link:
```bash
adb tcpip 5555 # at the desk, over USB, once per tablet boot
# in the car, from halogen, through the Orin over the tailnet:
ssh -N -L 5555:192.168.55.100:5555 mikkeli-orin-nano &
adb connect localhost:5555
flutter run -d localhost:5555
```
The tablet keeps the RSA authorisation from the USB pairing. `adb usb` turns TCP
mode off again; a reboot does too. Android's *Wireless debugging* (pairing) is
WiFi-only and does not help here. Untested in the car so far.
### CI
`.gitea/workflows/ci.yaml` mirrors the android-stuff apps: host-mode runner on
halogen, label `flutter-android`, analyze + test, then a debug APK artifact on
push. The existing `halogen-android` runner is registered to the android-stuff
org only, so this repo needs a runner registered to the `yukart` org (a second
instance on halogen, the way `gitea-runner-audio` is set up) before jobs run.