Skill car-logs: fetch and read the car's recordings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
name: car-logs
|
||||||
|
description: Download the signal recordings the MG4 sent to the car server (fetch-logs) and read them. Use when the owner says a recording is on the server, asks to get, download or look at the car's logs or recordings, or after a test drive with the signal recorder.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Fetch and read the car's recordings
|
||||||
|
|
||||||
|
The app's signal recorder (Logs tab, `SignalRecorder`) sends each finished recording to the
|
||||||
|
car server (`LogOutbox`, `PUT /v1/logs/{name}`); the server keeps the newest 200
|
||||||
|
(`server/logs.go`). `fetch-logs` in the dev shell downloads the ones not yet in `logs/`.
|
||||||
|
|
||||||
|
## Fetch
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix develop -c fetch-logs
|
||||||
|
```
|
||||||
|
|
||||||
|
It prints each new file (`logs/signal-recording-YYYYMMDD-HHMMSS.txt`) and `fetch-logs: N new`.
|
||||||
|
The token comes from `~/.config/nilsmg4/logs-token` (the server's `LOGS_TOKEN`) and goes only in
|
||||||
|
a header.
|
||||||
|
|
||||||
|
- **Never print, cat or echo the token**, and never pass it on a command line you show. Do not
|
||||||
|
read the token file.
|
||||||
|
- `no token`: ask the owner to put the server's `LOGS_TOKEN` in `~/.config/nilsmg4/logs-token`
|
||||||
|
(and in `k8s/secrets/secrets.yaml`, then apply it). Do not create or fill it yourself.
|
||||||
|
- HTTP 401: the file and the server's Secret differ. HTTP 404: reading is off (no
|
||||||
|
`LOGS_TOKEN` on the server) or the server is older than 2.9.0. The owner applies manifests and
|
||||||
|
Secrets; never run `kubectl` against the cluster, not even read-only.
|
||||||
|
- `0 new`: nothing arrived. In the car, the Logs tab says "Sent to the server." or how many wait
|
||||||
|
and why (no server set up, server not reached, an HTTP status); the car retries every 2
|
||||||
|
minutes while the service runs.
|
||||||
|
|
||||||
|
## Read
|
||||||
|
|
||||||
|
The files are plain text but `file` may call them data; search with `rg -a`. Newest first:
|
||||||
|
`ls -t logs/`. If the owner said what they did and when (e.g. "ACC on at 08:50, set speed
|
||||||
|
100→90 at 08:51"), line those times up with the timeline.
|
||||||
|
|
||||||
|
A recording has four parts, in this order:
|
||||||
|
|
||||||
|
1. Header: captures, start time, app version.
|
||||||
|
2. **Steering-wheel keys and notes.** The first note says whether listening worked:
|
||||||
|
`listening to N assistance properties (M refused)`, or `not possible (<reason>)`.
|
||||||
|
3. **Assistance properties heard** (`EVHardware.listenToProperties` on `AssistBlock`, the
|
||||||
|
`0x21x0A1xx` block): change events, properties whose value changed first. This is where a
|
||||||
|
value shows up that the head unit fills only while someone listens.
|
||||||
|
4. **Changed values (polled)**, rarest first, then **Everything, in order**: every capture
|
||||||
|
(about every 5 s) with what changed since the last.
|
||||||
|
|
||||||
|
Useful cuts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rg -a 'listening to' logs/<file> # did listening work
|
||||||
|
awk '/^Assistance properties heard/,/^$/' logs/<file> # what listening heard
|
||||||
|
rg -a 'A15B|A15A' logs/<file> # one property's history
|
||||||
|
rg -a 'getLatestSpeed' logs/<file> | head # the car's speed over time
|
||||||
|
```
|
||||||
|
|
||||||
|
Known leads (SPECS.md, 2026-10-27): `0x2160A15B` is `AAD_EPTCCTRGTSPD`, by its name the cruise
|
||||||
|
control's target speed (0.0 when only polled); `0x2140A15A` moved between 3 and 7;
|
||||||
|
`0x2160A1A3`/`0x2160A1A4` counted up by 0.1. A value that tracks what the owner did at the
|
||||||
|
times they name is a lead; say how sure it is, and that it is not confirmed until a second
|
||||||
|
drive shows the same.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Recordings are the car's data: `logs/` and `/signal-recording-*.txt` are gitignored. Never
|
||||||
|
commit, publish or upload them anywhere.
|
||||||
|
- Findings that change what the project knows go into a `SPECS.md` done-log entry, as usual.
|
||||||
@@ -111,7 +111,7 @@ nix develop # JDK 21, Android SDK, Go
|
|||||||
./gradlew testStableDebugUnitTest testUnstableDebugUnitTest lintStableDebug
|
./gradlew testStableDebugUnitTest testUnstableDebugUnitTest lintStableDebug
|
||||||
build-car # build/car/NilsMG4-unstable-<version>.apk + .sha256
|
build-car # build/car/NilsMG4-unstable-<version>.apk + .sha256
|
||||||
publish-car # pre-release car-<version> on the forge (needs a token)
|
publish-car # pre-release car-<version> on the forge (needs a token)
|
||||||
fetch-logs # the car's recordings from the server into logs/ (needs LOGS_TOKEN)
|
fetch-logs # the car's recordings from the server into logs/ (needs LOGS_TOKEN; skill car-logs)
|
||||||
cd server && go vet ./... && go test ./... && govulncheck ./...
|
cd server && go vet ./... && go test ./... && govulncheck ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does *
|
|||||||
confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces
|
confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces
|
||||||
upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator`
|
upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator`
|
||||||
(Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked).
|
(Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked).
|
||||||
|
- 2026-10-27 — Skill `car-logs` (`.claude/skills/car-logs/SKILL.md`; owner: "can we write a skill for downloading the logs?"): fetch with `fetch-logs` without ever showing the token, what its errors mean, how a recording is laid out, the cuts that find a lead, the leads so far, and that recordings are never committed. Its commands tried on the 08:52 recording.
|
||||||
- 2026-10-27 — Server 2.9.0 pushed (`sha256:c68837f0e53cfca150644987be535e04d5e999bd4c91064d40973db67235df48`, pinned in `k8s/server.yaml`); app 2.41.0 published (`car-2.41.0`).
|
- 2026-10-27 — Server 2.9.0 pushed (`sha256:c68837f0e53cfca150644987be535e04d5e999bd4c91064d40973db67235df48`, pinned in `k8s/server.yaml`); app 2.41.0 published (`car-2.41.0`).
|
||||||
- 2026-10-27 — App 2.41.0, server 2.9.0: **recordings reach the server** (owner: "can we make
|
- 2026-10-27 — App 2.41.0, server 2.9.0: **recordings reach the server** (owner: "can we make
|
||||||
it so that we can upload the logs to an endpoint in the server, and you can get the logs from
|
it so that we can upload the logs to an endpoint in the server, and you can get the logs from
|
||||||
|
|||||||
Reference in New Issue
Block a user