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>
15 KiB
Installation — Schritt für Schritt
Betrifft den kompletten aktuellen Baustand: das pyscript-Backend
(Fahrterkennung, Fahrtabschluss, Reifenzähler, Belegverarbeitung) und
das Frontend (panel_custom, Sidebar-Eintrag „Mein Audi").
Getestet, nicht nur geprüft. Beides lief in einer Wegwerf-Testinstanz
(Home Assistant in Docker) wirklich: das Backend über echte Service-Aufrufe
(Reifen wechseln hat die Profildatei tatsächlich umgeschrieben, eine
manuell angelegte Fahrt wurde tatsächlich an fahrten.jsonl angehängt),
das Frontend, indem das Custom Element mit genau diesen echten Daten
gefüttert wurde und daraus korrekt die Übersicht und die Fahrtenliste
gerendert hat — inklusive der zuvor testweise umgeschalteten Winterbereifung,
sichtbar an der Fahrbahn-Szene. Wofür die Testinstanz nicht reichte: der
Weg über Home Assistants echte WebSocket-Verbindung, mit der der
panel_custom-Rahmen (ha-panel-custom) das Element normalerweise selbst
erzeugt und mit hass versorgt — diese Testumgebung ließ keine
WebSocket-Verbindung zu, unabhängig vom eigenen Code. Dieser letzte Schritt
— dass die Oberfläche beim ganz normalen Draufklicken in der Sidebar
erscheint — ist deshalb der einzige Teil, der sich erst bei euch wirklich
zeigt. panel_custom selbst ist Home Assistants eigener, seit Jahren
stabiler Mechanismus, nicht eigener Code, entsprechend gering ist das
Risiko dort.
Voraussetzung: HACS ist bereits installiert (ergibt sich aus der
laufenden Integration TommiG1/HA_VAG-EU-Data-Act).
Zeitaufwand: ca. 30–40 Minuten, größtenteils Warten auf Neustarts.
Schritt 1 — pyscript installieren
- In Home Assistant: HACS → Integrationen → Explore & Download Repositories
- Nach „pyscript" suchen, auswählen, Download
- Home Assistant neu starten (Einstellungen → System → Neu starten)
Schritt 2 — Dateien auf den Home-Assistant-Rechner kopieren
Drei Ordner müssen in das config-Verzeichnis von Home Assistant kopiert
werden. Wählt den Weg, der zu eurer Installation passt:
Vorher: data/fahrzeugprofil.json enthält bei einer laufenden Installation
echte Fahrzeug- und Personendaten (VIN, Kennzeichen, Versicherung, Werkstatt,
Servicehistorie) und ist deshalb nicht Teil dieses Repos (siehe .gitignore).
Für eine neue Installation zuerst data/fahrzeugprofil.example.json nach
data/fahrzeugprofil.json kopieren — die Platzhalter darin lassen sich nach
dem ersten Start bequem direkt in der App eintragen: Einstellungen →
Fahrzeug einrichten deckt FIN, Kennzeichen, Erstzulassung und Ausführung ab,
Versicherung/Werkstatt/Reifen haben eigene Bearbeiten-Ansichten.
Am einfachsten: Samba-Share-Add-on
- Falls noch nicht installiert: Einstellungen → Add-ons → Add-on Store → „Samba share" installieren und starten
- Am Windows-Rechner im Explorer verbinden:
\\<HA-IP-Adresse>\config - Von diesem Projektordner aus kopieren:
pyscript\(der ganze Ordner) →\\<HA-IP>\config\pyscript\data\(der ganze Ordner) →\\<HA-IP>\config\audi_dashboard\(Ordner beim Kopieren vondatainaudi_dashboardumbenennen)www\(der ganze Ordner, Frontend) →\\<HA-IP>\config\www\(Inhalt zusammenführen, falls dort schon einewww-Ablage existiert)
Alternative: Studio Code Server Add-on
- Einstellungen → Add-ons → Add-on Store → „Studio Code Server" installieren, starten, öffnen
- Im Dateibaum links Ordner
pyscript,audi_dashboardundwwwunter/configanlegen, falls sie fehlen - Dateien einzeln per Drag & Drop aus dem Explorer in den Browser ziehen, oder Rechtsklick → „Upload"
Alternative: SSH & Terminal Add-on, falls bereits eingerichtet — dann
reicht scp/rsync vom gewohnten Terminal aus.
Schritt 3 — configuration.yaml ergänzen
configuration_snippet.yaml aus diesem Ordner öffnen. Die zwei Blöcke
(pyscript: und panel_custom:) in die bestehende configuration.yaml
übernehmen — nicht die Datei komplett ersetzen. Falls dort schon ein
pyscript:-Block existiert, nur die Zeile allow_all_imports: true darin
ergänzen statt einen zweiten Block anzulegen.
Der panel_custom:-Block kann schon jetzt mit rein; er wird erst mit dem
Frontend-Baustein wirksam und stört bis dahin nicht.
Schritt 4 — die Entity-IDs eintragen
Das ist die einzige Stelle, die inhaltlich angepasst werden muss — Datei
pyscript/modules/einstellungen.py.
Zwingend fürs Backend (ohne diese drei läuft die Kernlogik nicht):
- In Home Assistant: Entwicklerwerkzeuge → Zustände
- Dort suchen und die genauen Entity-IDs notieren für:
- den Kilometerstand-Sensor (aus
TommiG1/HA_VAG-EU-Data-Act) →KM_SENSOR - den Tankfüllstand-Sensor (dieselbe Integration) →
TANK_SENSOR - den WLAN-Verbindungssensor des iPhones →
WLAN_SENSOR— dafür vorher in der iOS-Companion-App unter Einstellungen → Companion App → Sensoren den Sensor für das verbundene WLAN aktivieren, falls er dort noch grau ist
- den Kilometerstand-Sensor (aus
Optional fürs Frontend (nur für die Übersicht/Zustand-Seite, ohne sie zeigt die Oberfläche „unbekannt" statt eines Werts — kein Absturz):
-
Ebenfalls in Entwicklerwerkzeuge → Zustände suchen:
- Reichweite →
RANGE_SENSOR - Türstatus (falls als ein Sammel-Sensor vorhanden) →
DOORS_SENSOR - Fensterstatus →
WINDOWS_SENSOR - Verriegelung (Domäne
lock.) →LOCK_ENTITY - Batteriespannung, falls überhaupt vorhanden →
BATTERY_VOLTAGE_SENSOR
- Reichweite →
-
Datei
pyscript/modules/einstellungen.pyöffnen (Samba: direkt im Explorer, Studio Code Server: im Editor) und alle gefundenen Werte eintragen. Was ihr nicht findet, einfach auf dem Platzhalter stehen lassen — siehe Kommentar in der Datei dazu.
Schritt 5 — Long-Lived Access Token erzeugen
Wird für das Kilometerstand-Screening gebraucht (§7.2) — pyscript hat keinen eingebauten Weg, auf die Recorder-Historie zuzugreifen, deshalb läuft das über die normale Home-Assistant-Web-API.
-
Unten links auf den eigenen Profil-Avatar klicken
-
Ganz nach unten scrollen zu „Long-lived access tokens"
-
„Token erstellen", einen Namen vergeben (z. B.
audi_dashboard) -
Den angezeigten Token-Wert sofort kopieren — er wird danach nicht noch einmal angezeigt
-
Eine neue Datei
audi_dashboard/ha_token.txtanlegen (im selben Ordner, in dendata/kopiert wurde) und nur den Token-Wert hineinschreiben, keine Anführungszeichen, keine zweite Zeile⚠️ Diese Datei enthält ein Geheimnis. Nicht weitergeben, nicht in ein Backup hochladen, das öffentlich einsehbar ist.
Schritt 6 — neu starten
Einstellungen → System → Neu starten.
Schritt 7 — prüfen, ob alles geladen hat
- Einstellungen → System → Protokolle, nach „pyscript" oder
„audi_dashboard" filtern — es sollten keine roten Fehlermeldungen
auftauchen, insbesondere keine
ImportErroroderModuleNotFoundError - Entwicklerwerkzeuge → Zustände, nach
pyscript.reifensuchen — dort solltenpyscript.reifen_sommer_km,pyscript.reifen_winter_km(Wert0, solange noch kein Kilometerstand-Update seit der Installation einging) undpyscript.reifen_aktiver_satzauftauchen - Entwicklerwerkzeuge → Aktionen, nach „audi_dashboard" suchen — die
Services
pyscript.audi_dashboard_screening_jetzt,pyscript.audi_dashboard_reifen_wechseln,pyscript.audi_dashboard_fahrt_manuell_anlegen,pyscript.audi_dashboard_beleg_hochladenundpyscript.audi_dashboard_tankvorgang_manuellsollten dort erscheinen
Wenn das alles stimmt, läuft das Backend. Die Fahrterkennung selbst lässt
sich am einfachsten testen, indem das WLAN am Handy kurz ausgeschaltet und
wieder eingeschaltet wird (Pausenregel greift) bzw. länger als die
eingestellte Pausenzeit ausgeschaltet bleibt (Fahrt wird angelegt) — danach
in audi_dashboard/fahrten.jsonl nachsehen, ob eine Zeile entstanden ist.
Schritt 8 — was jetzt noch fehlt, bevor es vollständig nutzbar ist
- Reifen-Kilometerstände: laufen automatisch mit (
reifen.saetze. sommer/winter.km, siehe reifenzaehler.py) — beide starten bei der Installation bei0. Hat einer der Sätze schon Laufleistung von vor der Installation, den Wert einmalig direkt inaudi_dashboard/ fahrzeugprofil.jsonnachtragen - Kfz-Steuer-Fälligkeit:
steuer.faelligim selben Profil eintragen - shell_beleg_parser.py liegt bereits unter
data/shell_beleg_parser.pyund wird mit demdata-Ordner aus Schritt 2 automatisch nachaudi_dashboard/shell_beleg_parser.pymitkopiert. Er ruftpython3als eigenen Prozess auf (nicht die pyscript-Sandbox) und braucht dafür einmaligpypdf: im Terminal & SSH-Add-on (oder perdocker exec)pip install pypdfausführen. Ohne das schlägt jeder Beleg-Upload mitModuleNotFoundError: No module named 'pypdf'im Log fehl. - Tailscale „VPN On Demand" in der Tailscale-App selbst einrichten
(Regel „Only On", gebunden an
Audi_MMI_2804_5GHz) — unabhängig von Home Assistant, kann jederzeit parallel erledigt werden
Schritt 9 — Frontend prüfen
Der panel_custom-Eintrag aus Schritt 3 zeigt auf
/config/www/audi-dashboard-panel.js, die in Schritt 2 mitkopiert wurde.
- In der Sidebar sollte nach dem Neustart aus Schritt 6 ein neuer Eintrag „Mein Audi" erscheinen (Auto-Symbol). Anklicken.
- Die Übersicht sollte erscheinen: Fahrzeugbild (als Platzhalter, siehe unten), Typenschild, Kilometerstand, Reichweite. Falls Kilometerstand oder Reichweite „unbekannt"/leer bleiben, obwohl Schritt 7 erfolgreich war: die optionalen Entity-IDs aus Schritt 4 nachtragen.
- Falls die Seite leer bleibt oder gar nicht in der Sidebar erscheint: im Browser die Entwicklerkonsole öffnen (F12) und nach Fehlern mit „audi-dashboard" oder „pyscript" suchen — siehe Troubleshooting.
Was direkt sichtbar fehlt, ganz bewusst (siehe README):
- Bilder — der Ordner
bilder/mit den elf Fotos aus §7a ist nicht Teil dieses Baustands. Die Bildflächen bleiben leer bzw. zeigen ein gebrochenes Bild-Symbol, das Layout selbst springt nicht (die Maße sind reserviert). Bilder können jederzeit einzeln unterwww/bilder/nachgereicht werden, feste Dateinamen siehe §7a im Lastenheft. - Karten (Leaflet) laden weiterhin von einem CDN, genau wie im Prototyp. Das Gerät braucht dafür zusätzlich zur Tailscale-Verbindung normalen Internetzugang — sonst bleibt die Karte auf der Fahrt- und Tankvorgang-Detailseite leer.
- Statistik-Seite zeigt weiterhin Beispielzahlen aus dem Prototyp, keine echte Auswertung der eigenen Fahrten — eigenes Arbeitspaket.
Schritt 10 — künftige Updates einspielen, ohne die App neu zu bauen
Ab hier ändert sich der Ablauf: kein Neustart mehr nötig, weder für Backend- noch für Frontend-Änderungen.
Backend (pyscript): pyscript überwacht pyscript/ selbst auf
Änderungen und lädt geänderte Dateien automatisch neu — an der
Testinstanz gemessen: eine bearbeitete Datei war innerhalb von
Millisekunden aktiv, neue Services erschienen sofort in
Entwicklerwerkzeuge → Aktionen, ganz ohne Neustart. Es reicht, die neue
Datei per Samba/Studio-Code-Server/scp in pyscript/ zu überschreiben.
Frontend: hier gibt es keinen eingebauten Auto-Reload, dafür aber ein
echtes Cache-Problem — Home Assistant liefert Dateien aus /local/ mit
Cache-Control: max-age=2678400 aus, 31 Tage (an der Testinstanz
gemessen). Ohne Gegenmaßnahme würde eine Aktualisierung im Browser
tagelang nicht ankommen. Deshalb ist das Frontend zweigeteilt:
audi-dashboard-panel.jsist ein kleiner, stabil bleibender Lade-Stub, auf denpanel_customin derconfiguration.yamlzeigt- er lädt bei jedem Seitenaufruf zuerst
audi-dashboard-version.jsonungecacht, hängt deren Versionsnummer als Parameter an und lädt darüber erst den eigentlichen Code ausaudi-dashboard-app.jsnach — jede neue Versionsnummer ist für den Browser eine neue URL und wird nie aus einem alten Cache bedient
Am einfachsten mit dem beiliegenden Skript:
.\update.ps1 -Ziel "\\<HA-IP-Adresse>\config"
Kopiert pyscript/ und die Frontend-Dateien, schreibt
audi-dashboard-version.json automatisch mit einem neuen Zeitstempel —
lässt data/ unangetastet, damit ein bereits laufendes Fahrzeugprofil
oder Fahrten-Archiv nicht überschrieben wird. Voraussetzung: der
Samba-Share aus Schritt 2 ist als Netzlaufwerk verbunden.
Danach: pyscript-Änderungen sind sofort aktiv, für das Frontend reicht ein ganz normales Neuladen der Seite (F5) — kein Hard-Refresh, kein HA-Neustart.
⚠️ Server-seitig geprüft: eine neue audi-dashboard-version.json und ein
geänderter audi-dashboard-app.js-Inhalt standen an der Testinstanz sofort
zur Verfügung (per curl nachgemessen). Ob ein echter Browser das beim
nächsten Öffnen tatsächlich nachlädt, ließ sich in der Sandbox-Testumgebung
nicht abschließend zeigen — deren eigene Netzwerkschicht verhielt sich
bereits beim WebSocket-Test nicht wie ein normaler Browser (siehe README).
Das Verfahren selbst (cache:"no-store" plus versionierter
Import-Parameter) ist eine Standardtechnik gegen genau dieses Problem,
keine Vermutung — der erste echte Test dafür ist trotzdem der erste echte
Update-Durchlauf bei euch.
Troubleshooting
| Symptom | Wahrscheinliche Ursache |
|---|---|
ModuleNotFoundError: No module named 'einstellungen' (oder profil, fahrtabschluss_logik) |
Ordner falsch kopiert — modules/-Unterordner muss unter pyscript/modules/ liegen, nicht direkt unter pyscript/ |
| pyscript lädt gar nicht, keine Fehler, keine Services | allow_all_imports: true fehlt oder Einrückung in der configuration.yaml ist falsch (YAML ist einrückungsempfindlich) |
| Fahrt wird nie angelegt | WLAN_SENSOR in einstellungen.py zeigt auf die falsche Entity, oder fahrzeug.wlan_name im Profil passt nicht exakt zum Sensorwert (Groß-/Kleinschreibung zählt) |
| Screening findet nie einen Kilometerstand | ha_token.txt fehlt, ist leer, oder der Token wurde widerrufen — in den Protokollen nach HTTPError oder 401 suchen |
| Reifenzähler zeigt dauerhaft „unbekannt" | KM_SENSOR in einstellungen.py liefert keinen Wert, oder es kam seit der Installation noch keine Änderung des Kilometerstands an (reifenzaehler.py reagiert nur auf Sensor-Änderungen) |
| „Mein Audi" fehlt in der Sidebar | panel_custom:-Block fehlt oder ist falsch eingerückt in configuration.yaml; nach Änderungen daran hilft nur ein vollständiger Neustart, kein „YAML neu laden" |
| Sidebar-Eintrag da, Seite bleibt leer | Browser-Konsole (F12) prüfen: 404 bei /local/audi-dashboard-panel.js → Datei liegt nicht unter /config/www/; JS-Fehler beim Laden → Datei unvollständig kopiert, Dateigröße mit dem Original vergleichen |
| Übersicht erscheint, aber alle Werte „unbekannt" | Normal, solange KM_SENSOR/TANK_SENSOR/... in einstellungen.py noch Platzhalter sind (Schritt 4) — kein Frontend-Fehler |
| Karten bleiben leer auf Fahrt-/Tankdetailseite | Gerät hat keinen Internetzugang zusätzlich zu Tailscale — Leaflet lädt von einem CDN (siehe Schritt 9) |