Initialer Import: HA-Panel, Design-System, Companion-App
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>
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
# 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
|
||||
|
||||
1. In Home Assistant: **HACS → Integrationen → Explore & Download Repositories**
|
||||
2. Nach „pyscript" suchen, auswählen, **Download**
|
||||
3. 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**
|
||||
1. Falls noch nicht installiert: **Einstellungen → Add-ons → Add-on Store →
|
||||
„Samba share"** installieren und starten
|
||||
2. Am Windows-Rechner im Explorer verbinden: `\\<HA-IP-Adresse>\config`
|
||||
3. 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 von `data` in `audi_dashboard` umbenennen)
|
||||
- `www\` (der ganze Ordner, Frontend) → `\\<HA-IP>\config\www\`
|
||||
(Inhalt zusammenführen, falls dort schon eine `www`-Ablage existiert)
|
||||
|
||||
**Alternative: Studio Code Server Add-on**
|
||||
1. **Einstellungen → Add-ons → Add-on Store → „Studio Code Server"**
|
||||
installieren, starten, öffnen
|
||||
2. Im Dateibaum links Ordner `pyscript`, `audi_dashboard` und `www` unter
|
||||
`/config` anlegen, falls sie fehlen
|
||||
3. 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):
|
||||
|
||||
1. In Home Assistant: **Entwicklerwerkzeuge → Zustände**
|
||||
2. 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
|
||||
|
||||
**Optional fürs Frontend** (nur für die Übersicht/Zustand-Seite, ohne sie
|
||||
zeigt die Oberfläche „unbekannt" statt eines Werts — kein Absturz):
|
||||
|
||||
3. 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`
|
||||
|
||||
4. 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.
|
||||
|
||||
1. Unten links auf den eigenen Profil-Avatar klicken
|
||||
2. Ganz nach unten scrollen zu **„Long-lived access tokens"**
|
||||
3. **„Token erstellen"**, einen Namen vergeben (z. B. `audi_dashboard`)
|
||||
4. Den angezeigten Token-Wert **sofort kopieren** — er wird danach nicht
|
||||
noch einmal angezeigt
|
||||
5. Eine neue Datei `audi_dashboard/ha_token.txt` anlegen (im selben Ordner,
|
||||
in den `data/` 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
|
||||
|
||||
1. **Einstellungen → System → Protokolle**, nach „pyscript" oder
|
||||
„audi_dashboard" filtern — es sollten keine roten Fehlermeldungen
|
||||
auftauchen, insbesondere keine `ImportError` oder `ModuleNotFoundError`
|
||||
2. **Entwicklerwerkzeuge → Zustände**, nach `pyscript.reifen` suchen — dort
|
||||
sollten `pyscript.reifen_sommer_km`, `pyscript.reifen_winter_km` (Wert `0`,
|
||||
solange noch kein Kilometerstand-Update seit der Installation einging) und
|
||||
`pyscript.reifen_aktiver_satz` auftauchen
|
||||
3. **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_hochladen` und
|
||||
`pyscript.audi_dashboard_tankvorgang_manuell` sollten 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 bei `0`. Hat einer der Sätze schon Laufleistung von vor der
|
||||
Installation, den Wert einmalig direkt in `audi_dashboard/
|
||||
fahrzeugprofil.json` nachtragen
|
||||
- **Kfz-Steuer-Fälligkeit:** `steuer.faellig` im selben Profil eintragen
|
||||
- **shell_beleg_parser.py** liegt bereits unter `data/shell_beleg_parser.py`
|
||||
und wird mit dem `data`-Ordner aus Schritt 2 automatisch nach
|
||||
`audi_dashboard/shell_beleg_parser.py` mitkopiert. Er ruft `python3` als
|
||||
eigenen Prozess auf (nicht die pyscript-Sandbox) und braucht dafür
|
||||
einmalig `pypdf`: im **Terminal & SSH**-Add-on (oder per `docker exec`)
|
||||
`pip install pypdf` ausführen. Ohne das schlägt jeder Beleg-Upload mit
|
||||
`ModuleNotFoundError: 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.
|
||||
|
||||
1. In der Sidebar sollte nach dem Neustart aus Schritt 6 ein neuer Eintrag
|
||||
„Mein Audi" erscheinen (Auto-Symbol). Anklicken.
|
||||
2. 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.
|
||||
3. 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 unter `www/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.js` ist ein kleiner, stabil bleibender Lade-Stub,
|
||||
auf den `panel_custom` in der `configuration.yaml` zeigt
|
||||
- er lädt bei jedem Seitenaufruf zuerst `audi-dashboard-version.json`
|
||||
ungecacht, hängt deren Versionsnummer als Parameter an und lädt darüber
|
||||
erst den eigentlichen Code aus `audi-dashboard-app.js` nach — 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:**
|
||||
|
||||
```powershell
|
||||
.\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) |
|
||||
Reference in New Issue
Block a user