Die App spricht jetzt echt mit Home Assistant. Ein Datenkontext buendelt die
vier Datentoepfe, haengt sich an den WebSocket-Ereignisstrom und reicht
Verbindungszustand und Warteschlange nach aussen; die Screens kennen weder
REST noch WebSocket. Ersteinrichtung prueft die Zugangsdaten, bevor sie sie
speichert, und unterscheidet in der Fehlermeldung zwischen abgelehntem Token
und nicht erreichbarem Server - zwei Faelle, die voellig verschiedene
Reaktionen verlangen.
Zwei echte Fehler, die erst der Test gegen die laufende Instanz zutage
brachte:
1. Die Typen der Datenschicht deklarierten tank_prozent, sicher_abgestellt
und sicherheit. Das Backend schreibt tankprozent, gesichert und
sicherheitscheck - die Oberflaeche haette still ueberall undefined
gelesen, ohne dass irgendetwas fehlgeschlagen waere.
2. Der Profil-Adapter reichte lebende Verweise ins Rohprofil durch. Ein
Formular haette damit den Rohstand mitveraendert und die Zusage gebrochen,
den vom Backend fortgeschriebenen Reifen-Kilometerstand nie zu
ueberschreiben. Abschnitte werden jetzt kopiert.
Ausserdem zwei Parameter-Eigenschaften in der Datenschicht aufgeloest, weil
Node sie im Strip-Modus nicht uebersetzt und genau darueber die Rauchtests
laufen.
Belegt durch neun Pruefungen gegen die laufende Instanz (Lesen, Dienstaufruf,
vollstaendiger Warteschlangenumlauf, WebSocket-Anmeldung) und 21 Unit-Tests.
Zwei Layouts aus derselben Zusammensetzung: unter 1000px Tab-Leiste unten,
darueber Seitenleiste links mit Brotkrume statt Zurueck-Pfeil. Navigation
ist wie im alten Panel ein flacher Zustand mit fester ZURUECK-Tabelle statt
eines Router-Pakets - die Verschachtelung ist hoechstens dreistufig.
Theme und Tab-Beschriftung ueberleben einen Neustart (localStorage,
abgesichert fuer den Privatmodus), Startwert folgt der Systemeinstellung.
Symbole aus dem alten Panel uebernommen, damit App und Panel gleich aussehen.
Neun Rendertests belegen die Abnahmekriterien: Layoutwechsel in beide
Richtungen, Zurueck-Ziel ueber die Tabelle, Zahnrad statt Tab-Leiste fuer
die Einstellungen, Theme-Persistenz.
npm-Workspace im Repo-Root verbindet companion-app mit @audi-dash/ui, so
dass die App die Komponentenbibliothek als echte Abhaengigkeit nutzt statt
nur in der Doku. Dazu Vite, React 18, Einstiegsdateien und eine schlanke
Grundlage-CSS, die nur enthaelt was eine App braucht und eine Bibliothek
nicht mitbringt: Vollbild, sichere Bereiche, Scrollverhalten.
Zwei Audit-Befunde des alten Panels sind hier von Anfang an beruecksichtigt:
Formularfelder mit 16px (sonst zoomt iOS Safari beim Fokus) und ein
globaler :focus-visible-Ring.
Nebenbei im design-system den Kontrastwert --fg3 nachgezogen: dort stand
noch #657081 mit 3,0:1 auf --tile, das Panel hatte den Wert laengst auf
#8a94a3 korrigiert. Ohne das haette die neue App den bereits behobenen
WCAG-Verstoss geerbt.
Drei zusammengehörige Teile in einem Repository:
- homeassistant/ Das fertige, im Einsatz befindliche Home-Assistant-Panel
(panel_custom Custom Element + pyscript-Backend). Echte Fahrzeug- und
Personendaten (fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl,
Tankbelege) bleiben per .gitignore außen vor; die anonymisierte Vorlage
fahrzeugprofil.example.json ist mit dabei.
- design-system/ Eigenständige React-Komponentenbibliothek (@audi-dash/ui),
die die visuelle Sprache des Panels nachbildet - ohne Audi-Markenzeichen
und ohne die lizenzierte Hausschrift. Dient als Grundlage für Claude
Design. War bis hierher ein eigenes Repository und ist in dieses
eingeschmolzen worden.
- companion-app/ Datenschicht der neuen App DataMetric360 (iOS/Android via
Capacitor, zusätzlich als Iframe im HA-Dashboard). Noch ohne Oberfläche:
REST- und WebSocket-Zugriff auf Home Assistant plus Warteschlange für
Änderungen ohne Netz. Ersetzt das eingespritzte hass-Objekt, das nur
innerhalb des HA-Frontends existiert.
Dazu die Projektdokumentation: SPECIFICATION.md (Ist-Stand des Panels),
COMPANION_APP_ARCHITECTURE.md (Architekturentscheidungen der neuen App),
AUDIT_2026-08-10.md, DESIGN_BRIEF_DATAMETRIC360.md und der ursprüngliche
Bauauftrag.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>