Commit Graph
15 Commits
Author SHA1 Message Date
nilsandClaude Opus 5.5 f3de272c69 Grafana: map zooms to the route; plain hyphens in titles
- "Where the car was" fits the route again: in Grafana's fit view the
  zoom value is the maximum zoom, and 6 held it at country level. Now
  15 with 10 % padding. Checked by rendering the Live dashboard with a
  simulated 10 km drive.
- Dashboard titles use "-" instead of an em dash: "MG4 - Live",
  "MG4 - Consumption", "MG4 - Charging".
- SPECS.md: Grafana keeps its state in SQLite on its PVC, which is why
  it runs as one replica with Recreate; high availability needs
  PostgreSQL or MySQL first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 21:59:17 +02:00
nilsandClaude Opus 5.5 84fb3aac21 k8s: work with kubectl apply -f as well as -k
- The secrets template moves to k8s/secrets/, and the filled-in copy to
  k8s/secrets/secrets.yaml (gitignored). `kubectl apply -f k8s/` does
  not recurse, so neither the placeholder template nor the real secrets
  can be applied by accident.
- The server image digest is pinned in server.yaml instead of through
  kustomize's images override, which `-f` ignores (it would have pulled
  a nonexistent :latest).
- README and kustomization.yaml say to use `-k`: plain `-f` never
  creates the generated Grafana ConfigMaps.
- The IngressRoutes drop `tls: {}`, like the other routes on this
  Traefik: TLS is configured on the websecure entrypoint.

Manifests validated both ways (14 resources rendered with kustomize,
11 as plain files — the difference is the Grafana ConfigMaps).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 21:36:17 +02:00
nilsandClaude Opus 5.5 6f57351866 Use the traefik-internal ingress class
Both IngressRoutes (server and Grafana) now use traefik-internal, like
the rest of *.k8s.stinnesbeck.com, instead of the traefik-external
placeholder. README and SPECS updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 18:16:52 +02:00
nilsandClaude Opus 5.5 315586f94c Move the server to car.k8s.stinnesbeck.com
The server's host is car.k8s.stinnesbeck.com, not car.stinnesbeck.com:
IngressRoute, PUBLIC_URL (so the pairing QR code points there), the
app's pre-filled server URL and hint, and the docs. Grafana's
placeholder host follows to car-grafana.k8s.stinnesbeck.com, so one
*.k8s.stinnesbeck.com default certificate covers both. App 2.4.1 for the
new default; the server image is unchanged (its URL comes from the
manifest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 18:08:35 +02:00
nilsandClaude Opus 5.5 59ee2cae3b Deploy server 2.1.0; keep filled-in secrets out of git
- kustomization pins mg4-server 2.1.0 by digest; server.yaml sets
  PUBLIC_URL for the pairing QR code; the secrets template gains
  APPROVAL_PASSWORD.
- Filled-in Secrets now go into k8s/secrets.yaml, which is gitignored;
  the template stays on placeholders. This follows a leak where real
  values typed into the template were committed and pushed (amended and
  force-pushed since; both values regenerated).
- SPECS.md records pairing and the incident.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 16:16:52 +02:00
nilsandClaude Opus 5.5 4fe29189c0 Pin the pushed server image; drop the pull secret
mg4-server:2.0.0 is on git.stinnesbeck.com and pulls anonymously, so
the Deployment no longer references a registry pull secret. The image
is pinned by digest (sha256:6feea777…) so a re-pushed tag cannot
change what the cluster runs. README and secrets template updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 16:14:53 +02:00
nilsandClaude Opus 5.5 5473ab1c2b Dashboards in Grafana; clean up after the Next.js app
- k8s/grafana.yaml: Grafana 13.2.3 with a 1Gi PVC, sign-up and
  anonymous access off. The InfluxDB datasource (URL and token from the
  environment) and three dashboards — Live, Consumption, Charging — are
  provisioned from k8s/grafana/ via kustomize-generated ConfigMaps.
- server.yaml for the Go server (port 8080, UID 65532, smaller limits),
  image tag 2.0.0. The NetworkPolicy now admits Grafana to InfluxDB.
- ingress.yaml: IngressRoutes for car.stinnesbeck.com and Grafana
  (placeholder host car-grafana.stinnesbeck.com) with tls: {}, using
  Traefik's default certificate; the cert-manager Certificate is gone.
- secrets.example.yaml: drops the dashboard secrets, adds grafana-admin.
- AGENTS.md loses its Next.js block; SPECS.md describes the new setup.

The removal of web/ (the Next.js app) and of the stale .next/ cache
upstream had committed already landed in 51e6f6f, which was staged
together with the Go server by mistake.

Checked end to end in podman (Go server + InfluxDB 2.7.12 + Grafana
13.2.3): all 25 dashboard queries return the expected data, and the
dashboards were rendered with headless Chromium. Manifests validated
offline with kustomize and kubeconform. Nothing applied to a cluster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 15:18:09 +02:00
nilsandClaude Opus 5.5 538d03361d Translate the dashboard to English; euro instead of lira
Dashboard: every label, empty state, chart legend and the login page
are English; numbers and dates use en-GB (24-hour clock, day-month
dates), money is EUR, percentages read 80% instead of %80, durations
"2 h 05 min". html lang is en. Server version 1.1.2; manifests pin it.

Car app: the charging tab's price suffix, validation message and total
cost use € instead of ₺.

Checked by rendering all three pages from the 1.1.2 image against
InfluxDB 2.7.12 in podman.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 14:39:59 +02:00
nilsandClaude Opus 5.5 818442db08 Rename the web app from FatihsMG4 to Nils' MG4
Browser title, login heading, hidden password-manager username, session
cookie (nilsmg4_session) and package name. The README keeps the credit
to fatihdonmezdev/FatihsMG4. Server version 1.1.1; the manifests pin it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 14:34:16 +02:00
nilsandClaude Opus 5.5 6145736c97 App 2.3.0: Server tab, live telemetry to the car server
- New Server tab: server URL, ingest token and installation id, with
  Save, Test connection (health, then a read-only token check) and the
  config-file import that upstream removed (app folder / USB stick first,
  document picker as fallback). Settings are kept encrypted and read on
  every use, so the service picks up a change without a restart. Each
  installation generates its own id; the inherited upstream UUID and
  the baked-in CONSUMPTION_API_* build fields are gone.
- Live telemetry restored from before ea8032a (TelemetryPayload,
  UploadCadence, UploadSettings, GPS) and sent in batches to
  POST /v1/telemetry instead of ABRP; the server forwards to ABRP. Adds
  ext_temp, voltage and current. Unsent samples queue in memory (about
  8 h) while offline.
- Upload tab: the live-telemetry switch and cadence controls work again;
  the dead service and autostart switches are removed.
- Manifest: location permissions and foreground service types.
- Unit tests compile again: 114 (stable) / 136 (unstable) pass. Tests
  for the deleted AbrpApi and HeadUnitWeather removed; new tests for
  ServerConfig and TelemetryQueue. Lint passes.

Not yet tried on the car.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:23:04 +02:00
nilsandClaude Opus 5.5 d4fb4ba3af Plan the car server (InfluxDB 2, ABRP forwarder, k8s manifests) in SPECS.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:51:07 +02:00
nilsandClaude Opus 5.5 de2428786a Journal diagnostics and upstream ABRP removal in SPECS.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:38:47 +02:00
nilsandClaude Opus 5.5 10029623e3 Remove on-screen diagnostics from the Logs tab
They served their purpose: vehicle values show on the car. This reverts
commit b2a5b32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:38:36 +02:00
nilsandClaude Opus 5.5 b2a5b32b08 Add on-screen diagnostics to the Logs tab
Without adb there was no way to see why vehicle values stay blank:
refreshVehicle() swallowed every exception. The Logs tab now shows the
package, version, UID (and whether it is the system UID), signer
SHA-256, firmware, car permission grants, the last snapshot and read
error, and the newest 200 entries of the vehicle library's AppLogger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:26:39 +02:00
nilsandClaude Opus 5.5 a707b590f7 Rename package and APKs to NilsMG4, credit Fatih, add SPECS.md
- applicationId com.evsuite.abrp -> com.stinnesbeck.nilsmg4 (the car
  build is .unstable); the Java namespace is unchanged. Installs next to
  upstream's app rather than over it.
- APK names NilsMG4-*.apk, debug builds included; build-car follows.
- OTA install-result action, cache/download names, User-Agent and log
  tags follow the new name.
- About credits fatihdonmezdev / FatihsMG4.
- SPECS.md journals what changed and what is still to do, starting
  with pointing the About link and QR code at git.stinnesbeck.com/nils/mg4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:08:09 +02:00