pyscript-Backend zur echten HA-Integration umgebaut (HACS-fähig)
Das Backend liegt jetzt als custom_components/audi_dashboard/ vor - eine normale Home-Assistant-Integration mit Config-Flow, einer sensor-Plattform und 18 Diensten. Damit ist die App über HACS installierbar; bis das Repo auf GitHub gespiegelt ist (HACS spricht ausschließlich mit GitHub), installiert homeassistant/installationspaket/install.ps1 denselben Ordner ohne HACS. Fünf Installationsschritte entfallen ersatzlos: der pyscript:-Block, der panel_custom:-Block, das Kopieren der Oberfläche nach www/, das langlebige Zugriffstoken (der Verlauf wird direkt über die recorder-API gelesen) und "pip install pypdf" (steht in manifest.json). Das Fahrzeugprofil legt die Integration beim ersten Start aus ihrer Vorlage an. Drei alte Schwächen sind dabei mit erledigt: - Die Nutzlast landet nicht mehr in der Recorder-Datenbank (_unrecorded_attributes - das kann nur eine echte Entität). - Eine laufende Fahrt überlebt einen Neustart (Store statt Arbeitsspeicher); fiel sie während eines Ausfalls ins Ende, schließt nach_neustart_fortsetzen() sie beim letzten aufgezeichneten Zeitpunkt. - Sensor-Zuordnungen wirken sofort - die Zustandsbeobachter werden neu gebunden, der Neustart-Hinweis und der Neustart-Dienst sind weg. Namensvertrag geändert, beide Oberflächen mitgezogen: pyscript.audi_dashboard_x -> sensor.audi_dashboard_x, pyscript.audi_dashboard_y -> audi_dashboard.y. Eine Companion-App vom alten Stand findet nach dem Umstieg nichts mehr und muss neu gebaut werden; das Panel liegt in der Integration und kann nicht driften. Der selbstgebaute Updater entfällt - HACS ist die Update-Mechanik, die Home Assistant kennt. Die Versionierung schrumpft auf eine Quelle: manifest.json. Geprüft am laufenden Testcontainer (Container byteweise identisch mit dem Repo): alle 18 Dienste, Panel, Config-Entry neu laden, Historienimport, echter Shell-Beleg in-process, Neuinstallation im Wegwerf-Container blank mit automatisch nachinstalliertem pypdf. Companion-App: tsc sauber, 112/112 Tests, beide Rauchtests gegen das laufende Backend grün. Belegparser 8/8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+171
-353
@@ -1,404 +1,222 @@
|
||||
# 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").
|
||||
Zwei Wege führen zum selben Ergebnis: HACS lädt den Ordner
|
||||
`custom_components/audi_dashboard/` aus dem Repository, das Skript kopiert
|
||||
denselben Ordner von der Festplatte. Was danach passiert, ist identisch.
|
||||
|
||||
**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 (wird für pyscript selbst
|
||||
gebraucht, siehe Schritt 1). Für die Fahrterkennung und die Fahrzeugdaten
|
||||
wird zusätzlich ein Teltonika FMM003 (bzw. dessen Integration in Home
|
||||
Assistant, z. B. über flespi) vorausgesetzt — Details siehe
|
||||
`COMPANION_APP_ARCHITECTURE.md` im Projektstamm. Ohne FMM003 läuft die App
|
||||
trotzdem: alle davon abhängigen Werte zeigen einfach „unbekannt" statt
|
||||
eines Werts.
|
||||
|
||||
Zeitaufwand: ca. 30–40 Minuten, größtenteils Warten auf Neustarts.
|
||||
Wer von der früheren pyscript-Fassung kommt: [Umstieg](#umstieg-von-der-pyscript-fassung)
|
||||
weiter unten. Die Fahrzeugdaten bleiben dabei, wo sie sind.
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
## Der schnelle Weg: install.sh
|
||||
- Home Assistant 2025.1 oder neuer
|
||||
- Zugriff auf das `config`-Verzeichnis (Samba-Add-on, SSH oder ein
|
||||
gemounteter Pfad) — nur für den Weg ohne HACS
|
||||
- Mindestens eine Datenquelle, die den Zündungs-/ACC-Status des Fahrzeugs
|
||||
als `binary_sensor` meldet. Ohne sie läuft die App, erkennt aber keine
|
||||
Fahrten.
|
||||
|
||||
Für eine neue Instanz gibt es ein Skript, das die Schritte 1 bis 3 und 5
|
||||
zusammen erledigt. Am einfachsten direkt auf der HA-Instanz im Add-on
|
||||
**Terminal & SSH**:
|
||||
Nicht mehr nötig, anders als bei der pyscript-Fassung: pyscript selbst, ein
|
||||
langlebiges Zugriffstoken, ein `pip install` im Container und Einträge in der
|
||||
`configuration.yaml`. Details dazu im Kopf von
|
||||
[`__init__.py`](../custom_components/audi_dashboard/__init__.py).
|
||||
|
||||
```bash
|
||||
bash <(curl -fsSL https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh)
|
||||
---
|
||||
|
||||
## Weg A — über HACS
|
||||
|
||||
1. HACS → **Integrationen** → Menü oben rechts → **Benutzerdefinierte
|
||||
Repositories**
|
||||
2. Repository-URL eintragen, Kategorie **Integration**, hinzufügen
|
||||
3. **Audi Dashboard** suchen und herunterladen
|
||||
4. Home Assistant neu starten
|
||||
|
||||
**Hürde, die man kennen muss:** HACS spricht ausschließlich mit GitHub —
|
||||
`github.com` und `api.github.com` stehen fest im Code, es gibt keinen
|
||||
Schalter für Gitea, GitLab oder eine selbst gehostete Instanz. Liegt das
|
||||
Repository woanders, findet HACS es auch als benutzerdefiniertes Repository
|
||||
nicht, und es bleibt Weg B.
|
||||
|
||||
## Weg B — ohne HACS, per Skript
|
||||
|
||||
Vom Windows-Rechner aus, der das `config`-Verzeichnis erreicht:
|
||||
|
||||
```
|
||||
homeassistant\installationspaket\Installieren.cmd
|
||||
```
|
||||
|
||||
Liegt das Repository privat (Standard), braucht der Aufruf Zugangsdaten — mit
|
||||
Token oder mit Nutzer und Passwort, beides funktioniert:
|
||||
Das Skript sucht die HA-Instanz selbst (`\\homeassistant\config` und die
|
||||
üblichen Varianten) und fragt nach, wenn es sie nicht findet. Es kopiert
|
||||
`custom_components\audi_dashboard\` dorthin — und sonst nichts.
|
||||
|
||||
```bash
|
||||
curl -fsSL -H "Authorization: token <TOKEN>" \
|
||||
https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh -o install.sh
|
||||
bash install.sh --repo https://<nutzer>:<token>@gitea.nothaft.cloud/paul/audi-app.git
|
||||
Zum Vorabschauen, ohne dass etwas geschrieben wird:
|
||||
|
||||
```
|
||||
powershell -ExecutionPolicy Bypass -File homeassistant\installationspaket\install.ps1 -Pruefen
|
||||
```
|
||||
|
||||
**Eine Überlegung lohnt sich dabei:** Was in `--repo` steht, wird als Updatequelle
|
||||
hinterlegt und landet im Klartext in `pyscript/modules/einstellungen.py`. Ein
|
||||
Token ist dort besser aufgehoben als das Kontopasswort, weil er einzeln
|
||||
widerrufbar und auf Lesezugriff beschränkbar ist. Wer gar nichts ablegen will,
|
||||
hängt `--update-repo aus` an und aktualisiert weiter über dieses Skript.
|
||||
Die Abwägung im Einzelnen steht in `ha_install.md`, Abschnitt 1b.
|
||||
Was das Skript garantiert (und warum), steht in seinem eigenen Kopfkommentar.
|
||||
Die kurze Fassung: es schreibt ausschließlich in seinen eigenen Ordner, fasst
|
||||
`configuration.yaml` und `.storage\` nicht an, löscht nur den eigenen Ordner
|
||||
und auch den nur, wenn dessen `manifest.json` ihn als solchen ausweist.
|
||||
|
||||
Alternativ von einem Rechner aus gegen ein eingebundenes config-Verzeichnis:
|
||||
Danach Home Assistant neu starten.
|
||||
|
||||
```bash
|
||||
./install.sh --ziel /Volumes/config --von ~/Development/audi-app
|
||||
```
|
||||
---
|
||||
|
||||
Das Skript installiert pyscript, spielt Backend und Oberfläche ein, legt das
|
||||
Fahrzeugprofil aus der Vorlage an (**vorhandene Daten bleiben unangetastet**),
|
||||
trägt den Abschnitt in die `configuration.yaml` ein — mit Sicherungskopie und
|
||||
so, dass ein zweiter Lauf ihn ersetzt statt anhängt — und verdrahtet die
|
||||
Selbstaktualisierung, damit „Update suchen" in der App funktioniert.
|
||||
`--hilfe` zeigt alle Optionen.
|
||||
## Nach dem Neustart
|
||||
|
||||
Danach bleiben nur noch drei Dinge, alle in der Weboberfläche: neu starten,
|
||||
Sensoren zuordnen (Schritt 4 unten), Fahrzeugdaten eintragen.
|
||||
### 1. Integration hinzufügen
|
||||
|
||||
Wer lieber jeden Schritt selbst nachvollzieht, folgt der ausführlichen
|
||||
Anleitung ab hier.
|
||||
**Einstellungen → Geräte & Dienste → Integration hinzufügen → Audi
|
||||
Dashboard.** Es gibt nichts einzugeben — ein Bestätigungsschritt, mehr nicht.
|
||||
|
||||
Beim ersten Laden installiert Home Assistant die Abhängigkeit `pypdf` nach
|
||||
(für die Tankbelege); das kann eine Minute dauern.
|
||||
|
||||
## Schritt 1 — pyscript installieren
|
||||
Danach steht **Mein Audi** in der Seitenleiste, und es entstehen zwölf
|
||||
Entitäten `sensor.audi_dashboard_*` sowie 18 Dienste `audi_dashboard.*`.
|
||||
|
||||
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**)
|
||||
### 2. Sensoren zuordnen
|
||||
|
||||
## Schritt 2 — Dateien auf den Home-Assistant-Rechner kopieren
|
||||
In der App: **Einstellungen → Fahrzeug einrichten → Setup.**
|
||||
|
||||
Drei Ordner müssen in das `config`-Verzeichnis von Home Assistant kopiert
|
||||
werden. Wählt den Weg, der zu eurer Installation passt:
|
||||
Im Auslieferstand ist **kein** Sensor vorbelegt. Das ist Absicht: welche
|
||||
Entity-IDs richtig sind, hängt an der Instanz und ihren Integrationen, und
|
||||
eine gesetzte, aber falsche ID ist schlechter als eine leere — die App zeigt
|
||||
dann „unbekannt" statt eines falschen Werts.
|
||||
|
||||
**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.
|
||||
| Rolle | Braucht es für |
|
||||
|---|---|
|
||||
| **Zündung/ACC** (Pflicht) | Fahrterkennung, Anzeige „fährt/steht" |
|
||||
| Kilometerstand | Fahrtabschluss, Reifenzähler, Ölwechsel-Prognose |
|
||||
| Tankfüllstand | automatische Tankerkennung |
|
||||
| 12V-Spannung | Batterieverlauf |
|
||||
| GPS Breiten-/Längengrad | Standort-Kachel |
|
||||
| Türen, Fenster, Heckklappe, Haube | „Sicher abgestellt" |
|
||||
| Reichweite, Service-Fälligkeiten | Anzeige in der Übersicht |
|
||||
|
||||
**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)
|
||||
Beim FMM003 **nicht** den selbst berechneten Gesamtkilometerstand
|
||||
(`*_total_calculated_mileage`) zuordnen: der beruht auf GPS-Streckenrechnung
|
||||
statt auf dem Tacho und verfälscht damit alle drei Auswertungen, die daran
|
||||
hängen. Der vom CAN gelesene Wert ist der richtige.
|
||||
|
||||
**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"
|
||||
Änderungen wirken sofort. Der frühere Hinweis „wirkt erst nach einem
|
||||
Neustart" bei Zündung, Kilometerstand und Tankfüllstand ist entfallen — die
|
||||
Integration meldet ihre Beobachter bei jedem Speichern neu an.
|
||||
|
||||
**Alternative: SSH & Terminal Add-on**, falls bereits eingerichtet — dann
|
||||
reicht `scp`/`rsync` vom gewohnten Terminal aus.
|
||||
### 3. Datenaufbewahrung verlängern — zeitkritisch
|
||||
|
||||
## Schritt 3 — configuration.yaml ergänzen
|
||||
Home Assistant löscht Sensor-Verläufe nach **10 Tagen**. Das ist die Grenze,
|
||||
bis zu der „Daten importieren aus Home Assistant" zurückreichen kann; was
|
||||
gelöscht ist, kommt nicht wieder. Je früher der Block aus
|
||||
[`recorder_snippet.yaml`](recorder_snippet.yaml) in der `configuration.yaml`
|
||||
steht, desto mehr Vergangenheit bleibt erhalten.
|
||||
|
||||
`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 beiden Zeilen `allow_all_imports: true`
|
||||
und `hass_is_global: true` darin ergänzen statt einen zweiten Block anzulegen.
|
||||
Vorher **Einstellungen → System → Speicher** prüfen: ein Jahr Verlauf braucht
|
||||
grob 1–1,5 GB. Bei knappem Platz mit `purge_keep_days: 90` anfangen.
|
||||
|
||||
`hass_is_global: true` braucht nur der nachträgliche Datenimport
|
||||
(Schritt 8) — ohne die Zeile läuft alles andere unverändert, der Import
|
||||
meldet dann aber, dass er den Verlauf nicht lesen kann.
|
||||
Bewusst nicht automatisch eingetragen: das ist eine Entscheidung über den
|
||||
Plattenplatz der Instanz, und viele Instanzen haben bereits einen eigenen
|
||||
`recorder:`-Block, den man zusammenführen muss statt zu überschreiben.
|
||||
|
||||
Der `panel_custom:`-Block kann schon jetzt mit rein; er wird erst mit dem
|
||||
Frontend-Baustein wirksam und stört bis dahin nicht.
|
||||
### 4. Fahrzeugdaten eintragen
|
||||
|
||||
### Datenaufbewahrung — je früher, desto mehr ist zu retten
|
||||
**Einstellungen → Fahrzeug einrichten.** Das Profil ist bereits angelegt —
|
||||
die Integration hat es beim ersten Start aus ihrer Vorlage erzeugt. Zu
|
||||
ersetzen sind die Platzhalter: VIN, Kennzeichen, Erstzulassung, HU-Termin,
|
||||
Versicherung, Werkstatt, Servicebuch.
|
||||
|
||||
Zusätzlich `recorder_snippet.yaml` aus demselben Ordner übernehmen. Home
|
||||
Assistant löscht Sensor-Verläufe **standardmäßig nach 10 Tagen**; der Block
|
||||
hebt das auf ein Jahr an.
|
||||
### 5. Vergangenes nachholen (optional)
|
||||
|
||||
Das ist zeitkritisch, anders als der Rest dieser Anleitung: was der recorder
|
||||
einmal gelöscht hat, ist endgültig weg — auch für den Import in Schritt 8.
|
||||
Wer diesen Block erst in vier Wochen einbaut, kann die dazwischen liegenden
|
||||
Fahrten nicht mehr nachtragen.
|
||||
**Einstellungen → Einrichten → Daten importieren aus Home Assistant.** Der
|
||||
Import liest denselben Verlauf, den die Live-Erkennung sonst in Echtzeit
|
||||
sieht, und leitet daraus rückwirkend Fahrten, Tankvorgänge und
|
||||
Spannungswerte ab. Mehrfach ausführbar — überschneidende Zeiträume erzeugen
|
||||
keine Dubletten.
|
||||
|
||||
Nicht betroffen sind die Bestände der App selbst (`fahrten.jsonl`,
|
||||
`tankvorgaenge.jsonl`, `batteriespannung.jsonl`, `fahrzeugprofil.json` unter
|
||||
`/config/audi_dashboard/`): die werden nirgends automatisch gekürzt und
|
||||
bleiben dauerhaft erhalten. Die 10-Tage-Grenze betrifft nur den **rohen**
|
||||
Sensor-Verlauf, aus dem die App ihre Datensätze erst ableitet.
|
||||
---
|
||||
|
||||
Zum Platzbedarf (an der Testinstanz gemessen: rund 5.300 Zustandsänderungen
|
||||
pro Tag, hochgerechnet grob 1–1,5 GB für ein Jahr) steht alles im Kopf von
|
||||
`recorder_snippet.yaml`, samt einer auskommentierten `exclude:`-Liste zum
|
||||
Kürzen, falls die Datenbank zu groß wird.
|
||||
## Prüfen, ob alles geladen hat
|
||||
|
||||
## Schritt 4 — die Sensoren zuordnen
|
||||
**Entwicklerwerkzeuge → Zustände**, Filter `audi_dashboard`. Erwartet werden
|
||||
zwölf Entitäten. Zwei sagen auf einen Blick, ob es läuft:
|
||||
|
||||
Anders als früher wird dafür **nicht** mehr `pyscript/modules/
|
||||
einstellungen.py` von Hand bearbeitet — das übernimmt ein grafisches
|
||||
Setup-Menü direkt in der App: **Mein Audi → Einstellungen → Fahrzeug
|
||||
einrichten → Einrichten → „Setup — Sensoren zuordnen"** (letzter Punkt,
|
||||
erscheint erst nach Klick auf „Einrichten").
|
||||
- `sensor.audi_dashboard_app_version` — steht auf der installierten Version
|
||||
- `sensor.audi_dashboard_fahrzeugstatus` — Attribut `daten` enthält die live
|
||||
gelesenen Fahrzeugwerte
|
||||
|
||||
> **Reihenfolge beachten:** Dieser Schritt braucht eine bereits laufende App.
|
||||
> Arbeite deshalb erst die Schritte 5 bis 9 ab (Token, Neustart, Prüfung,
|
||||
> Restarbeiten, Frontend) und komm dann hierher zurück. Schritt 7 verweist
|
||||
> seinerseits auf die hier vorgenommene Zuordnung — das ist kein Widerspruch,
|
||||
> sondern schlicht die Reihenfolge: erst starten, dann zuordnen, dann prüfen.
|
||||
Im Protokoll (**Einstellungen → System → Protokolle**) steht beim Start eine
|
||||
Zeile `Audi Dashboard <Version> eingerichtet`.
|
||||
|
||||
Das Setup-Menü listet jede Sensor-Rolle, die die App kennt (Zündung/
|
||||
Fahrterkennung, Kilometerstand, Tankfüllstand, Standort, Batteriespannung,
|
||||
Türen/Fenster/Schlösser, Ölwechsel/Inspektion, …), schlägt je Rolle
|
||||
passende vorhandene HA-Entitäten vor (Schalter „Nur passende Sensoren
|
||||
anzeigen" grenzt auf die erwartete Domäne/Einheit ein) und schreibt die
|
||||
Auswahl direkt in eine Override-Datei — `einstellungen.py` selbst bleibt
|
||||
unverändert.
|
||||
---
|
||||
|
||||
Die Override-Datei ist `/config/audi_dashboard/entitaeten.json`. Sie wird von
|
||||
der automatischen Sicherung und vom Backup-Export mit erfasst; ein
|
||||
Wiederherstellen spielt die Zuordnung also mit zurück.
|
||||
## Umstieg von der pyscript-Fassung
|
||||
|
||||
**Hinweis zu den Vorgabewerten:** Drei Rollen sind in `einstellungen.py` mit
|
||||
den Test-Entitäten der Entwicklungsinstanz vorbelegt (Zündung, Batterie-
|
||||
spannung, Standort — jeweils `*_testzone_fmm003`). Auf einer frischen
|
||||
Installation zeigen sie ins Leere; das Setup-Menü meldet dann „Entität nicht
|
||||
gefunden". Einfach die eigenen Entitäten zuordnen, damit ist es erledigt.
|
||||
Die Daten wandern nicht: Ordnername (`/config/audi_dashboard/`) und
|
||||
Dateiformate sind unverändert. Die Integration liest den bestehenden Bestand
|
||||
einfach weiter — es gibt keine Migration und damit auch keinen Weg, dabei
|
||||
etwas zu verlieren.
|
||||
|
||||
**Zwingend, damit die Fahrterkennung läuft:**
|
||||
- **Zündung/ACC-Status** (`ZUENDUNG_SENSOR`) — ein `binary_sensor`, `on`
|
||||
= Fahrt läuft. Kommt vom Teltonika FMM003 (z. B.
|
||||
`binary_sensor.<gerätename>_engine_ignition_or_acc_status`).
|
||||
1. Integration installieren (Weg A oder B oben)
|
||||
2. Aus der `configuration.yaml` entfernen: den `pyscript:`-Block und den
|
||||
`panel_custom:`-Eintrag `audi-dashboard-panel`. Bleiben sie stehen, gibt
|
||||
es den Sidebar-Eintrag zweimal, und beide Backends schreiben in dieselben
|
||||
Dateien.
|
||||
3. Aus `/config/pyscript/` entfernen: `backup.py`, `batterieverlauf.py`,
|
||||
`belegverarbeitung.py`, `bilderverwaltung.py`, `fahrtabschluss.py`,
|
||||
`fahrterkennung.py`, `frontend_api.py`, `historienimport.py`,
|
||||
`reifenzaehler.py`, `tankerkennung.py`, `updateverwaltung.py` und den
|
||||
Ordner `modules/`. Andere pyscript-Skripte bleiben unberührt; wird
|
||||
pyscript sonst nicht gebraucht, kann es über HACS ganz entfernt werden.
|
||||
4. Aus `/config/www/` entfernen: `audi-dashboard-app.js`,
|
||||
`audi-dashboard-panel.js`, `audi-dashboard.css`, `audi-dashboard-ios.css`,
|
||||
`audi-dashboard-version.json` und den Ordner `badges/`. Die Integration
|
||||
liefert diese Dateien selbst aus. **`www/bilder/` bleibt** — das sind die
|
||||
eigenen Fahrzeugfotos.
|
||||
5. `/config/audi_dashboard/ha_token.txt` kann weg: der Verlauf wird nicht mehr
|
||||
über die REST-API gelesen.
|
||||
6. Home Assistant neu starten, Integration hinzufügen.
|
||||
|
||||
**Alles Weitere ist optional** — ohne zugeordneten Sensor zeigt die
|
||||
Oberfläche „unbekannt"/em-dash statt eines Werts, kein Absturz:
|
||||
- Kilometerstand (`KM_SENSOR`), Tankfüllstand (`TANK_SENSOR`), Reichweite
|
||||
(`RANGE_SENSOR`) — bis zu einer neuen Datenquelle unbelegt, siehe
|
||||
`AGENTS.md` (die frühere `TommiG1/HA_VAG-EU-Data-Act`-Integration liefert
|
||||
diese nicht mehr)
|
||||
- Standort (`STANDORT_LAT_SENSOR`/`STANDORT_LON_SENSOR`, zwei eigene
|
||||
`sensor`-Entities für Breiten-/Längengrad — flespi liefert Koordinaten so,
|
||||
nicht als `latitude`/`longitude`-Attribute eines `device_tracker`) und
|
||||
Batteriespannung (`BATTERIE_SENSOR`) — vom FMM003, z. B.
|
||||
`sensor.<gerätename>_latitude_coordinate_value`/`..._longitude_coordinate_value`
|
||||
bzw. `sensor.<gerätename>_external_power_voltage` (**nicht**
|
||||
`..._battery_voltage` — das ist die interne Pufferzelle des Trackers,
|
||||
nicht die Fahrzeugbatterie)
|
||||
- Türen/Fenster/Schlösser, Ölwechsel/Inspektion — je nach Fahrzeug/
|
||||
Integration vorhanden oder nicht
|
||||
Die Sensor-Zuordnung aus `entitaeten.json` wird unverändert übernommen.
|
||||
|
||||
Wer lieber direkt in Entwicklerwerkzeuge → Zustände nach Entity-IDs sucht,
|
||||
kann das weiterhin tun — die Suche im Setup-Menü filtert exakt auf
|
||||
denselben Datenbestand (`HASS.states`), nur mit Vorschlägen und Filter.
|
||||
|
||||
**Einschränkung bei drei Feldern** (Zündung, Kilometerstand,
|
||||
Tankfüllstand): sie sind intern fest mit einem Auslöser verdrahtet
|
||||
(`@state_trigger`), der einmalig beim Laden des Backends gesetzt wird.
|
||||
Eine Änderung im Setup-Menü wird gespeichert, wirkt für die Fahrterkennung
|
||||
selbst aber erst nach einem Neustart von Home Assistant — das Setup-Menü
|
||||
zeigt dafür einen Hinweis an.
|
||||
|
||||
## 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 der Zündungs-Sensor (`ZUENDUNG_SENSOR`,
|
||||
nach dem Zuordnen in Schritt 4) kurz auf `on` und wieder auf `off` gesetzt
|
||||
wird (Pausenregel greift, kurzer Ausflug wird als eine Fahrt gewertet) bzw.
|
||||
länger als die eingestellte Pausenzeit auf `off` bleibt (Fahrt wird
|
||||
angelegt) — am Fahrzeug reicht dafür kurz die Zündung, ohne Fahrzeug
|
||||
funktioniert es auch manuell über **Entwicklerwerkzeuge → Zustände** (den
|
||||
Sensor suchen, Zustand testweise auf `on`/`off` setzen). 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
|
||||
- **Vergangene Daten nachtragen:** Fahrterkennung, Tankerkennung und
|
||||
Batterieverlauf laufen erst ab der Installation mit. Was Home Assistant
|
||||
vorher schon aufgezeichnet hat, holt **Einstellungen → Einrichten → „Daten
|
||||
importieren aus Home Assistant"** nach: Zeitraum wählen, „Importieren", und
|
||||
es entstehen dieselben Fahrten, Tankvorgänge und Spannungswerte, die die
|
||||
Live-Erkennung erzeugt hätte. Der Vorgang ist gefahrlos wiederholbar —
|
||||
überschneidet sich ein Zeitraum mit bereits erfassten Fahrten, wird er
|
||||
übersprungen statt doppelt angelegt.
|
||||
|
||||
Wie weit er zurückreicht, hängt allein an der Aufbewahrung aus Schritt 3
|
||||
(Standard 10 Tage, mit `recorder_snippet.yaml` ein Jahr). Kommt „0 Fahrten
|
||||
angelegt" zurück, nennt das Fenster den frühesten Zeitpunkt, zu dem
|
||||
überhaupt noch etwas aufgezeichnet ist.
|
||||
|
||||
## 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 Sensoren aus Schritt 4 im Setup-Menü zuordnen.
|
||||
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.
|
||||
**Die Companion-App muss neu gebaut und aufgespielt werden.** Sie spricht
|
||||
Entitäten und Dienste unter neuen Namen an (`sensor.audi_dashboard_*` statt
|
||||
`pyscript.audi_dashboard_*`, `audi_dashboard.<dienst>` statt
|
||||
`pyscript.audi_dashboard_<dienst>`) — eine App vom alten Stand findet nach
|
||||
dem Umstieg nichts mehr. Das Panel ist davon nicht betroffen: es wird von der
|
||||
Integration mitgeliefert und ist damit automatisch auf demselben Stand.
|
||||
|
||||
---
|
||||
|
||||
## 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 | `ZUENDUNG_SENSOR` ist im Setup-Menü nicht oder falsch zugeordnet, oder er ist nach einer Änderung im Setup-Menü noch nicht durch einen HA-Neustart aktiv geworden (siehe Schritt 4) |
|
||||
| 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` ist im Setup-Menü nicht zugeordnet, 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`/... im Setup-Menü noch nicht zugeordnet 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) |
|
||||
**„Mein Audi" fehlt in der Seitenleiste.** Ist die Integration unter
|
||||
Einstellungen → Geräte & Dienste wirklich hinzugefügt? Das Panel entsteht
|
||||
erst dabei, nicht schon beim Kopieren der Dateien.
|
||||
|
||||
**Das Panel bleibt auf „Lädt …".** Die App fragt so lange nach, bis das
|
||||
Backend Daten liefert — ein Abbruch ist nicht vorgesehen. Bleibt es dauerhaft
|
||||
stehen, im Protokoll nach `audi_dashboard` suchen.
|
||||
|
||||
**Alle Kacheln zeigen „unbekannt".** Kein Sensor zugeordnet (siehe Schritt 2)
|
||||
oder die zugeordneten Entitäten existieren nicht mehr. Das Setup-Fenster
|
||||
zeigt neben jedem Feld, ob der gewählte Sensor gerade einen brauchbaren Wert
|
||||
liefert.
|
||||
|
||||
**Fahrten werden nicht erkannt.** Ohne Zündungs-/ACC-Sensor gibt es keine
|
||||
Fahrterkennung — das ist das eine Pflichtfeld. Prüfen lässt sich das direkt:
|
||||
den Zustand der zugeordneten Entität in Entwicklerwerkzeuge → Zustände
|
||||
beobachten, während das Fahrzeug an- und ausgeht.
|
||||
|
||||
**Fahrten bleiben „offen".** „Offen" heißt: die Strecke fehlt noch, nicht
|
||||
„unterwegs". Der Kilometerstand kommt laut Datenquelle teils erst mit der
|
||||
nächsten Fahrt; das Screening trägt ihn dann nach. Bleibt es dauerhaft offen,
|
||||
fehlt der Kilometerstand-Sensor oder der recorder reicht nicht weit genug
|
||||
zurück.
|
||||
|
||||
**Belege lassen sich nicht lesen.** `pypdf` fehlt — normalerweise
|
||||
installiert Home Assistant es beim ersten Laden der Integration selbst. Im
|
||||
Protokoll nach `pypdf` suchen.
|
||||
|
||||
Reference in New Issue
Block a user