Datenaufbewahrung (recorder_snippet.yaml, neu): Home Assistant loescht Sensor-Verlaeufe standardmaessig nach 10 Tagen - das war die stille Obergrenze dafuer, wie weit sich ueberhaupt je etwas rekonstruieren laesst, denn geloeschte recorder-Zeilen sind endgueltig weg. Der Block hebt das auf 365 Tage. Die Bestaende der App selbst (fahrten.jsonl, tankvorgaenge.jsonl, batteriespannung.jsonl, fahrzeugprofil.json) waren davon nie betroffen, die kennen ohnehin keine Purge-Logik. Platzbedarf an der Testinstanz gemessen statt geschaetzt: 90.858 Zeilen in 17 Tagen, hochgerechnet grob 1,9 Mio. Zeilen und 1-1,5 GB im Jahr, davon 96 % aus der EU-Data-Act-Integration - dafuer liegt eine auskommentierte exclude:-Liste bei. Bewusst kein include:-Block, der wuerde jeder anderen Integration den Verlauf nehmen und dabei kaum Platz sparen. Historienimport (pyscript/historienimport.py, neu): neuer Dienst audi_dashboard_historie_importieren(start, ende) liest denselben Verlauf, den die Live-Trigger in Echtzeit sehen, und leitet rueckwirkend dieselben Datensaetze ab - Fahrten aus dem Zuendungsverlauf (inklusive der Pausenregel, kurze Unterbrechungen verschmelzen zu einer Fahrt), Tankvorgaenge nach derselben Tiefststand-Logik und denselben Schwellen wie tankerkennung.py, Tagesmin/-max der Batteriespannung. Mehrfach ausfuehrbar: ueberschneidet sich eine Fahrt mit einer bereits erfassten, wird sie uebersprungen statt doppelt angelegt. Erzeugte Datensaetze tragen source: "import". Gelesen wird ueber HAs eigene recorder-API (get_significant_states), nicht per direktem SQL auf home-assistant_v2.db: das Schema ist HA-intern und aendert sich zwischen Versionen, die Funktion ist die stabile Schnittstelle. Preis dafuer ist hass_is_global: true im pyscript-Block; ohne die Zeile laeuft alles andere unveraendert weiter, nur der Import meldet, dass er den Verlauf nicht lesen kann. Oberflaeche in beiden Codebasen: Knopf "Daten importieren aus Home Assistant" unter Einstellungen -> Einrichten, dahinter ein Fenster mit Von/Bis (Vorbelegung: letzte 30 Tage), "Importieren" als Hauptaktion und "Abbrechen" als zweite Wahl. Das Fenster bleibt offen und zeigt das Ergebnis, statt optimistisch zu schliessen - hier ist das Ergebnis der Zweck des Aufrufs. Fortschritt ueber die Entitaet pyscript.audi_dashboard_import_status, weil pyscript-Dienste sofort zurueckkehren. In companion-app bewusst NICHT ueber die Offline-Warteschlange: ein spaeter aus dem Nichts abgefeuerter Importlauf waere fuer den Nutzer nicht nachvollziehbar. Beim Testen gefunden und mitgefixt: profil.batterieverlauf_tageswert_ aktualisieren() haengte in Einfuegereihenfolge an. Solange nur die Live-Aufzeichnung schrieb, war das dasselbe wie sortiert (sie traegt immer den heutigen Tag ein) - der Import traegt vergangene Tage nach, die waeren hinter den neueren gelandet und das Diagramm haette zeitlich rueckwaerts gelaufen. Sortiert jetzt nach Datum, wie der eigene Docstring es ohnehin versprach. Auslieferstand bereinigt: einstellungen.py brachte zwei Entity-IDs einer laengst abgeraeumten Testinstanz mit (testzone_fmm003_...). Beim Testen unsichtbar, weil die Testinstanz sie ueber entitaeten.json ueberschreibt - auf einer Neuinstallation waeren sie die wirksamen Werte gewesen. Und schlimmer als nur wirkungslos: fahrterkennung.py registriert seinen @state_trigger nur, wenn das Feld belegt ist, ausdruecklich als Schutz gegen eine leere Entity-ID. Ein gesetzter, aber nicht existierender Wert hebelt genau diesen Schutz aus. Beide Felder jetzt leer wie alle anderen; Kopfkommentar der Datei ueberarbeitet, er behauptete noch, die EU-Data-Act-Integration werde nicht mehr verwendet. install.ps1 abgesichert, da die erste echte Installation auf HA OS ansteht: die feste configuration.yaml.bak wurde bei jedem Lauf ueberschrieben, ausgerechnet das Original war nach dem zweiten Lauf weg - Sicherungen jetzt zeitgestempelt. Nach dem Schreiben wird die Datei zurueckgelesen und geprueft (Laenge, genau ein Markerblock, bisheriger Inhalt unveraendert); bei der kleinsten Abweichung rollt das Skript automatisch zurueck. Die Sicherheitseigenschaften stehen jetzt im Kopf der Datei, statt dass man ihnen glauben muss. Standort-Blatt: "Teilen" war im Tagmodus unsichtbar - .standort-pille nutzte var(--tile), das Blatt darunter var(--tile-deckend), und die iOS-Auflage setzt im Tagmodus beide auf #FFFFFF. Gemessener Kontrast 1,00:1, weiss auf weiss. Beide Pillen folgen jetzt der Knopfsprache des Panels (.aktion / .aktion.primaer): Umriss fuer die Nebenaktion, var(--fg) gefuellt fuer "Route". Danach 17-21:1 Textkontrast in beiden Themes. Nebenbei ist damit --line-strong - eine Linienfarbe - nicht laenger als Knopffuellung im Einsatz. Geprueft: Import zweimal ueber die echte Oberflaeche im Browser gegen eine in die recorder-DB eingespielte Kunsthistorie (der Testcontainer laeuft nicht, waehrend das Auto faehrt, echte Fahrten liegen dort also nicht vor) - drei Fahrten wie erwartet, die 5-Minuten-Unterbrechung korrekt zu einer 50-Minuten-Fahrt verschmolzen, die 30-Sekunden-Zuendung verworfen, Strecken kilometergenau; zweiter Lauf legte 0 an und meldete 3 als vorhanden. Neuinstallation in einem Wegwerf-Container: nur Profilvorlage und Parser, keine Fahrten-/Tank-/Batteriedatei, null Fehler im Log. install.ps1 gegen Attrappen: -Pruefen schreibt nichts, echter Lauf laesst automations.yaml bytegleich (SHA-256) und fremde Bloecke stehen, Ergebnis parst als gueltiges HA-YAML, zweiter Lauf idempotent, bei fremdem pyscript:/panel_custom: bleibt die Datei bytegleich. tsc --noEmit sauber, companion-app-Tests 106/106, vite build sauber, HA-Configcheck und Start ohne Fehler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
22 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 (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.
Der schnelle Weg: install.sh
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:
bash <(curl -fsSL https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/homeassistant/install.sh)
Liegt das Repository privat (Standard), braucht der Aufruf Zugangsdaten — mit Token oder mit Nutzer und Passwort, beides funktioniert:
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
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.
Alternativ von einem Rechner aus gegen ein eingebundenes config-Verzeichnis:
./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.
Danach bleiben nur noch drei Dinge, alle in der Weboberfläche: neu starten, Sensoren zuordnen (Schritt 4 unten), Fahrzeugdaten eintragen.
Wer lieber jeden Schritt selbst nachvollzieht, folgt der ausführlichen Anleitung ab hier.
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 beiden Zeilen allow_all_imports: true
und hass_is_global: true darin ergänzen statt einen zweiten Block anzulegen.
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.
Der panel_custom:-Block kann schon jetzt mit rein; er wird erst mit dem
Frontend-Baustein wirksam und stört bis dahin nicht.
Datenaufbewahrung — je früher, desto mehr ist zu retten
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.
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.
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.
Schritt 4 — die Sensoren zuordnen
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").
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.
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.
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.
Zwingend, damit die Fahrterkennung läuft:
- Zündung/ACC-Status (
ZUENDUNG_SENSOR) — einbinary_sensor,on= Fahrt läuft. Kommt vom Teltonika FMM003 (z. B.binary_sensor.<gerätename>_engine_ignition_or_acc_status).
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, sieheAGENTS.md(die frühereTommiG1/HA_VAG-EU-Data-Act-Integration liefert diese nicht mehr) - Standort (
STANDORT_LAT_SENSOR/STANDORT_LON_SENSOR, zwei eigenesensor-Entities für Breiten-/Längengrad — flespi liefert Koordinaten so, nicht alslatitude/longitude-Attribute einesdevice_tracker) und Batteriespannung (BATTERIE_SENSOR) — vom FMM003, z. B.sensor.<gerätename>_latitude_coordinate_value/..._longitude_coordinate_valuebzw.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
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.
-
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 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 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 -
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.yamlein 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.
- 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 Sensoren aus Schritt 4 im Setup-Menü zuordnen.
- 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 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.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 | 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) |