8e268f044d
Doku-Drift behoben: die Statistik-Seite rechnet laengst echt (Behauptung stand an drei Stellen), INSTALL.md nannte in Schritt 4 vier Variablennamen, die es nie gab, README erwaehnte die entfernte 97-Prozent-Volltankungsregel und liess fuenf pyscript-Dateien in der Uebersicht aus. Obsoleter TODO-Kommentar in belegverarbeitung.py entfernt. profil_lesen() gibt bei fehlender oder beschaedigter Profildatei None zurueck statt zu werfen; alle sieben Aufrufstellen fangen den Fall ab. An der Testinstanz geprueft: Datei entfernt, es folgt eine verstaendliche Fehlermeldung mit Verweis auf INSTALL.md statt eines Tracebacks pro Trigger-Durchlauf, Home Assistant laeuft normal weiter.
284 lines
16 KiB
Markdown
284 lines
16 KiB
Markdown
# 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 → `TUER_SENSOREN` (Liste mit vier Einzelsensoren:
|
||
vorne links/rechts, hinten links/rechts)
|
||
- Fensterstatus → `FENSTER_SENSOREN` (ebenfalls vier Einzelsensoren)
|
||
- Verriegelung → `TUERSCHLOSS_SENSOREN` (vier Einzelsensoren; die
|
||
Integration liefert kein `lock.`-Entity)
|
||
- Heckklappe und Motorhaube → `HECKKLAPPE_SENSOR`,
|
||
`HECKKLAPPENSCHLOSS_SENSOR`, `HAUBE_SENSOR`, `HAUBENSCHLOSS_SENSOR`
|
||
- Service-Fälligkeit → `NAECHSTER_OELWECHSEL_SENSOR`,
|
||
`OELWECHSEL_STRECKE_SENSOR`, `NAECHSTE_INSPEKTION_SENSOR`,
|
||
`INSPEKTION_STRECKE_SENSOR`
|
||
- Batteriespannung, falls überhaupt vorhanden → `BATTERIE_SENSOR`
|
||
(bei der aktuellen Integration nicht vorhanden, bleibt leer)
|
||
|
||
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** wertet die eigenen Fahrten und Tankvorgänge echt aus
|
||
(Zeiträume, Verbrauch, Tag/Nacht, privat/Arbeitsweg). Sie bleibt nur so
|
||
lange leer, wie noch keine Fahrten und Tankungen erfasst sind.
|
||
|
||
## 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) |
|