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:
2026-08-11 00:10:53 +02:00
commit e1d570992e
151 changed files with 18162 additions and 0 deletions
+449
View File
@@ -0,0 +1,449 @@
# Bauauftrag: Fahrzeug-Dashboard in Home Assistant
**Stand 05.08.2026 · privates Projekt, keine Veröffentlichung**
*Überarbeitung: §10 vollständig geklärt; Änderungen in §4.2, §5.6, §6.1, §7.1, §7.2, §7.4, §7.5, §7.7, §9, §10, §13, §14.*
---
## 1. Der Auftrag in einem Satz
Zu bauen ist ein Fahrzeug-Dashboard in Home Assistant, das die Ende 2026 abgeschaltete App
*Audi connect plug & play* ersetzt: Fahrzeugstatus, Fahrtenbuch, Tankmonitor, Service, Kosten und
Versicherung für einen Audi RS 4 Avant competition — in einer Oberfläche, die sich an der Audi-App
orientiert.
---
## 2. Was mitgeliefert wird
| Datei | Inhalt |
|---|---|
| `dashboard-muster-ohne-bilder.html` | Dieselbe Anwendung mit referenzierten statt eingebetteten Bildern, 184 statt 770 KB — die Fassung, mit der gearbeitet wird |
| `bilder/` | Die aufbereiteten Bilddateien, elf Stück, zusammen 435 KB |
| `dashboard-muster.html` | **Vollständig bedienbarer Prototyp.** Eine einzelne HTML-Datei, alle Ansichten, alle Interaktionen, Beispieldaten. Das ist die verbindliche Vorlage für Aufbau, Verhalten und Gestaltung |
| `audi-connect-nach-homeassistant.md` | Projektbeschreibung mit allen Entscheidungen und ihren Begründungen |
| `shell_beleg_parser.py` | Getesteter Parser für Shell-Tankbelege, gegen zwei echte Belege geprüft |
| Schriften, Ringe, Typenschild, Fahrzeugbilder | im Prototyp eingebettet, separat verfügbar |
**Der Prototyp ist keine Skizze.** Er läuft, alle Wege sind begehbar. Wo dieser Auftrag und der
Prototyp voneinander abweichen, gilt der Prototyp — außer bei den unter §10 genannten Punkten.
---
## 3. Systemumgebung
- **Home Assistant**, bestehende Installation
- **Fahrzeugdaten:** HACS-Integration `TommiG1/HA_VAG-EU-Data-Act`, bereits eingerichtet und liefernd
- **Positionsdaten:** Home Assistant Companion App auf einem iPhone
- **Zugriff von außen:** Tailscale, kein Portforwarding, kein Funnel
- **Fahrzeug:** Audi RS 4 Avant competition, FIN WUAZZZF48PA902804, Erstzulassung 08/2023
---
## 4. Datenquellen
### 4.1 EU-Data-Act-Portal über die HACS-Integration
Liefert Kilometerstand, Tankfüllstand, Reichweite, Serviceintervalle, Türen- und Fensterstatus,
Verriegelung. **Kein GPS.** Aktualisierung im 15-Minuten-Takt und nur, wenn das Fahrzeug in diesem
Fenster Daten hochgeladen hat. Leere Zyklen sind normal.
**Konsequenzen, die im Entwurf bereits berücksichtigt sind:**
- Keine Live-Telemetrie. Momentanverbrauch, Drehzahl, Geschwindigkeit gibt es nicht.
- Der Kilometerstand steht nach dem Abstellen erst verzögert bereit → zweistufiger Fahrtabschluss (§7.2).
- Der Sensor ist zeitweise `unavailable` → betrifft den Reifenzähler (§7.5).
### 4.2 iPhone
Positionen über die Companion App. Fahrtstart und Fahrtende über die WLAN-Verbindung zum Fahrzeug
(Companion-App-Sensor für das verbundene Netz), **nicht** über CarPlay — CarPlay ist nicht immer
verbunden. Bluetooth wurde verworfen: iOS meldet Bluetooth-Verbindungswechsel im Hintergrund über
Region-Monitoring, das mehrere Minuten verzögern kann; die WLAN-Verbindung zum Fahrzeug baut sich
nach bisheriger Erfahrung zuverlässig sofort auf und ab. Der WLAN-Name (`Audi_MMI_2804_5GHz`) ist
fahrzeugspezifisch, liegt im Fahrzeugprofil (§6.1) und ist in den Einstellungen änderbar (§5.6).
### 4.3 Shell-Tankbelege
PDF per Upload in der App (§5.5, §7.7) — kein Postfachzugriff. Parser liegt bei. Belegnummer ist
**nicht** eindeutig; Schlüssel ist der minutengenaue Zeitstempel aus der Belegkopfzeile.
### 4.4 Manuelle Eingaben
Stammdaten, Versicherung, Steuer, Reifendaten, Servicebuch, Werkstatt, Fahrten und Tankvorgänge
ohne Beleg.
---
## 5. Aufbau der Oberfläche
Fünf Menüpunkte in einer festen Leiste unten, Symbole mit Beschriftung:
```
Übersicht · Mein Audi · Fahrten · Statistik · Tanken
```
Einstellungen liegen hinter den Audi-Ringen oben rechts.
### 5.1 Übersicht
Fahrzeugbild (Frontansicht, fest), Typenschild mit Kennzeichen, Zustandszeile „Sicher abgestellt"
mit grünem oder rotem Punkt, Reichweite als große Zahl mit Balken und Prozentwert, Kilometerstand
und nächster Service als Kachelpaar, darunter letzte Fahrt und letzter Tankvorgang als Anrisse.
### 5.2 Mein Audi
Bildergalerie zum Durchtippen, Typenschild, dann Kacheln mit Sprung auf eigene Seiten:
| Kachel | Unterseite |
|---|---|
| Identität | Fahrzeugdaten, technische Daten, Ausstattung |
| Zustand | Kilometerstand, Tankfüllung, Batteriespannung |
| Service | Termine, Servicebuch, Autohaus, Terminvereinbarung |
| Kosten | Jahreskosten, Aufteilung, je Kilometer |
| Versicherung und Steuer | Beitrag, Vertrag, Notruf, Schutzbrief, Kfz-Steuer |
| Reifen | beide Sätze, Umschalter, Wechseltermin, Anzugsmoment |
### 5.3 Fahrten
Dreistufig aufklappbar: Jahr → Monat → Fahrt. Detailseite mit Karte, Start, Ziel, Start- und
Endkilometer, Distanz, Dauer, Ø-Geschwindigkeit, Kraftstoffkosten, Art der Fahrt. Erfassung von
Hand über eine Schaltfläche unter der Liste.
### 5.4 Statistik
Aufklappbare Kacheln: Distanz und Fahrzeit, getankte Menge und Kosten, Durchschnittsverbrauch,
Tag/Nacht, Art der Fahrten. Aufschlüsselung je Jahr, Monat, Woche, Tag.
### 5.5 Tanken
Jahr → Monat → Tankvorgang, mit mengengewichtetem Durchschnittspreis je Ebene. Detailseite mit
Karte der Tankstelle, Kosten, Preis je Liter, SmartDeal-Ersparnis, abgeleiteter Volltankung und
Verbrauch. Erfassung von Hand und Beleg-Upload.
### 5.6 Einstellungen
Tag- und Nachtmodus, Beschriftung der Menüleiste, Fahrbahn unter dem Fahrzeug, Übersichtsbild,
WLAN-Name des Fahrzeugs (Textfeld mit Übernehmen-Knopf für das aktuell verbundene Netz),
Fahrten-Pausenzeit, SmartDeal mit Ablaufdatum, Ölwechsel-Intervall, Fahrzeugprofil sichern und
laden, CSV-Ausgabe, Sicherung, Versionsangaben.
---
## 6. Datenhaltung
### 6.1 Drei getrennte Bestände
| Bestand | Form | Begründung |
|---|---|---|
| **Fahrzeugprofil** | eine JSON-Datei | alles Fahrzeugspezifische an einem Ort, für Portierung austauschbar |
| **Fahrten** | JSON Lines, eine Zeile je Fahrt | wächst laufend, überlebt Purge und Neuinstallation |
| **Tankvorgänge** | JSON Lines | dito |
Servicebuch, Versicherung, Steuer, Reifen und Werkstatt gehören ins **Profil**, nicht in die
Archive — sie beschreiben das Fahrzeug, nicht seine Bewegung. Der WLAN-Name des Fahrzeugs gehört
aus demselben Grund ebenfalls ins Profil.
### 6.2 Portierbarkeit ist Anforderung, nicht Zugabe
Die Anwendung muss ohne Codeänderung für ein anderes Fahrzeug nutzbar sein. Das heißt: **keine
fahrzeugbezogene Angabe außerhalb des Profils**, auch keine Bezeichnungen in Texten. Bilder werden
referenziert, nicht eingebettet.
Drei Wege der Bearbeitung sind zu unterstützen: in der Oberfläche, über Sichern und Laden der
Datei, und direkt im Dateisystem.
### 6.3 Fahrten-Schema
`trip_id`, `ts_start`, `ts_end`, `duration_s`, `distance_km`, `km_quelle` (`odometer` | `gps`),
`odo_start`, `odo_end`, `avg_speed_kmh`, `start_lat/lon`, `end_lat/lon`, `start_address`,
`end_address`, `art` (`privat` | `arbeitsweg`), `route` (GeoJSON oder `null`), `pausen`,
`source` (`ha` | `manual` | `audi_connect`), `status` (`offen` | `vollständig`).
### 6.4 Tankvorgang-Schema
`tank_id`, `receipt_key` (Zeitstempel, minutengenau), `receipt_no`, `tse_beleg_nr`, `ts`,
`ts_payment`, `ts_tse`, `station_id`, `station_name`, `station_address`, `article_no`,
`product_name`, `fuel_type`, `liters`, `list_price_per_l`, `discount`, `discount_per_l`,
`fuel_total_eur`, `receipt_total_eur`, `price_per_l`, `net_eur`, `vat_eur`, `odometer_km`,
`level_before_pct`, `level_after_pct`, `full_tank`, `source`, `status`, `receipt_file`,
`edited_fields`.
---
## 7. Kernlogik
Diese sieben Punkte sind der eigentliche Auftrag. Die Oberfläche ist im Prototyp gelöst; hier liegt
die Arbeit.
### 7.1 Fahrterkennung
- **Start:** iPhone verbindet sich mit dem hinterlegten Fahrzeug-WLAN (Companion-App-Sensor, Name
in den Einstellungen hinterlegt, §5.6)
- **Ende:** WLAN-Verbindung bricht ab und kommt nicht zurück
- **Pausenregel:** Kommt die Verbindung binnen *n* Minuten zurück (Vorgabe 15, einstellbar), gilt
die Fahrt als fortgesetzt. Der Datensatz wird deshalb **erst nach Ablauf der Wartezeit**
geschrieben, nicht beim Abriss. Dieselbe Wartezeit löst danach auch das
Kilometerstand-Screening aus (§7.2).
### 7.2 Zweistufiger Fahrtabschluss
1. Bei Fahrtende (WLAN-Verbindung länger als die Pausenzeit weg, §7.1): Datensatz aus GPS und
Uhrzeit, Status `offen`
2. Screening: In der Recorder-Historie des Kilometerstand-Sensors wird nach dem Wert gesucht,
dessen Zeitstempel am nächsten am Verbindungsabbruch liegt — auch aus während der Fahrt
gemeldeten Werten, nicht nur aus dem letzten vor Fahrtende. Wird ein passender Wert gefunden:
Start- und Endkilometer nachtragen, Status `vollständig`
3. Wird keiner gefunden, bleibt der Status `offen`. Das Screening läuft erneut, sobald ein neuer
Kilometerstand eintrifft — auch wenn das erst mit der nächsten Fahrt geschieht, da der
Kilometerstand laut Datenquelle nicht sicher mit Fahrtende, sondern teils erst mit Beginn oder
während der folgenden Fahrt übermittelt wird
Bleibt der Wert dauerhaft aus, greift ersatzweise die GPS-Strecke, kenntlich über `km_quelle`. Das
betrifft insbesondere Fahrten, die in kurzem Abstand aufeinanderfolgen, bevor ein neuer
Kilometerstand eintrifft: nur die erste und letzte Fahrt einer solchen Kette lassen sich über den
Kilometerstand abgrenzen, die dazwischenliegenden fallen auf GPS zurück.
Technische Voraussetzung: Zugriff auf die Recorder-Historie (nicht nur den aktuellen Zustand) und
eine ausreichende Aufbewahrungsdauer des Recorders.
### 7.3 Strecke aus dem Kilometerstand
`km = Odometer(nach) Odometer(vor)`. Das GPS liefert Route und Adressen, **nicht** die Distanz.
Dadurch ist eine lückenhafte Positionsaufzeichnung unschädlich.
### 7.4 Volltankung ableiten
Nicht abfragen. Füllstand nach dem Tanken ≥ 97 % → Volltankung. Bei Teilbetankung wird **kein**
Verbrauch ausgewiesen. Der Tankgeber meldet den Füllstand bereits unterhalb des Ausdehnungsraums —
100 % sind also tatsächlich 100 %, die Schwelle braucht keine Korrektur dafür. Die Auflösung des
Sensors ist ganzzahlig.
### 7.5 Reifenzähler
Kein `utility_meter` — stattdessen direkte Berechnung: Zähler = aktueller (absoluter)
Kilometerstand Startwert des aktiven Satzes. Der Startwert je Satz ist als Stammdatum im
Fahrzeugprofil hinterlegt. Das vermeidet die Abhängigkeit von `total_increasing` und von
`utility_meter`-internem Zustand, der bei zeitweise `unavailable` Quellsensoren (§4.1) Strecke
verschlucken kann — die Subtraktion braucht nur den zuletzt bekannten Absolutwert, keinen
fortgeschriebenen Zählerstand.
### 7.6 Serviceprognose
Termine werden **nicht gespeichert, sondern berechnet**: letzter passender Servicebuch-Eintrag plus
Intervall. Gespeichert wird nur der vereinbarte Werkstatttermin.
Die Fahrleistung mischt zwei Zeiträume: den gesamten bekannten Verlauf und den Zeitraum seit dem
letzten Service, gewichtet über etwa 180 Tage. Damit wird die Vorhersage genauer, je näher das Ziel
rückt, und startet nach jedem Service neu.
Ein eingestelltes Intervall darf die Herstellervorgabe nicht überschreiten.
### 7.7 Belegverarbeitung
Beleg-Upload in der App (§5.5) → Parser → Datensatz. Ersetzt den in §4.3 ursprünglich vorgesehenen
Weg über ein Postfach — kein IMAP, keine Zugangsdaten nötig. Regeln:
1. Schlüssel ist der Zeitstempel aus der Kopfzeile, minutengenau
2. Liter, Preis und Betrag kommen vom Beleg, der Kilometerstand vom Fahrzeug
3. Manuell geänderte Felder werden nie von einem Import überschrieben
4. Nicht zuordenbare Fahrzeugereignisse bleiben als `beleg_fehlt` stehen
5. Der Gesamtbetrag kann Shop-Käufe enthalten — Kraftstoffanteil separat rechnen
6. Ohne Beleg: manuelle Eingabe von Liter und Preis als Fallback, bereits als Erfassungsweg unter
„Tanken" vorgesehen
---
## 7a. Bilder
Bilder werden **nicht** eingebettet, sondern referenziert. Sie kommen am Ende dazu; die Anwendung
muss ohne sie vollständig bedienbar sein.
**Ordner `bilder/`, feste Dateinamen:**
| Datei | Verwendung |
|---|---|
| `seitenansicht.webp`, `front-schraeg.webp`, `frontansicht.webp`, `heckansicht.webp`, `scheinwerfer.webp`, `cockpit.webp`, `sitze.webp` | Galerie in „Mein Audi", eine davon als Übersichtsbild |
| `seitenansicht-winter.webp` | Seitenansicht mit montierten Winterrädern |
| `rad-sommer.webp`, `rad-winter.webp` | Radbilder in der Reifenansicht |
| `fahrbahn-schnee.webp` | Untergrund bei montierten Winterrädern |
**Drei Bedingungen, damit das Nachreichen ohne Nacharbeit gelingt:**
1. **Die Flächen behalten ihre Maße.** Bildfläche 206 px hoch, auf der Übersicht 165 px, Radbilder
78 × 78 px. Platzhalter belegen dieselben Maße. Andernfalls springt das Layout, sobald die Bilder
kommen — und zwar in jeder Ansicht gleichzeitig.
2. **Die Namen stehen vorher fest.** Das Übersichtsbild wird über seinen Namen ausgewählt, nicht
über eine Position. Ein späterer Namenswechsel bricht die Konfiguration.
3. **Die Bildaufbereitung ist ein eigenes Arbeitspaket**, kein Nebenprodukt. Sie umfasst:
Freistellen des weißen Hintergrunds über eine Flutfüllung vom Rand — nicht über eine
Helligkeitsschwelle, sonst verschwinden Kennzeichen und Tagfahrlicht —, Montage der Winterräder
in die Seitenansicht, kreisrunde Maskierung der Radbilder und Zuschnitt der Fahrbahn mit
ausgeblendeter Oberkante.
Der beiliegende Prototyp enthält alle Bilder bereits aufbereitet; sie können übernommen werden.
## 8. Gestaltung
Verbindlich ist der Prototyp. Die Regeln dahinter:
| | |
|---|---|
| Fläche | Nacht `#161b23`, Kacheln `#1f2733` — Tag `#FFFFFF`, Kacheln `#f2f2f2` |
| Text | Nacht `#FFFFFF`, sekundär `#9aa1ad`, Beschriftungen `#657081` — Tag `#000000`, sekundär `#4c4c4c`, Beschriftungen `#666666` |
| Akzent | Progressive Red `#F50537`, sparsam (theme-unabhängig) |
| Signalfarben | Nacht: Grün `#15da15`, Gelb `#ffaa00`, Rot `#fd2c4e` — Tag: Grün `#0DA20D`, Gelb `#ffaa00`, Rot `#eb0d3f` |
| Radien | Kacheln 20 px, Schaltflächen vollrund. Ausnahme: kleine funktionale Elemente (Formularfelder, Mini-Bildboxen, Kürzel-Badges) dürfen 612 px nutzen, wo die volle Kachelrundung optisch zu grob wirkt |
| Schrift | Audi Type: Normal für die Oberfläche, Wide Light für Kennzahlen, Extended Italic für den Fahrzeugtitel. Nur die Schnitte Light (300) und Normal (400) sind eingebunden — kein `font-weight:600` oder höher verwenden, der Browser würde sonst synthetisch fetten |
| Zahlen | durchgehend Tausenderpunkt, Tabellenziffern |
Tag- und Nachtmodus sind umschaltbar, alle Farben liegen als Rollen vor (CSS-Variablen), nie als
Literalwerte in Komponenten. Keine Schatten, keine Verläufe außer der Fahrbahn unter dem Fahrzeug.
**Rechtlich:** Audi Type, Ringe und Typenschild sind lizenz- beziehungsweise markenrechtlich
geschützt und ausschließlich für diese private, nicht veröffentlichte Installation freigegeben.
---
## 9. Nicht-funktionale Anforderungen
- **Erreichbarkeit:** über Tailscale. Kein Funnel, keine Subnetz-Routen, kein Exit Node. Das iPhone
darf ausschließlich Home Assistant auf Port 8123 erreichen. Schlüsselablauf für das HA-Gerät
deaktivieren — andernfalls fällt der Zugang nach Monaten still aus. Verbindungsaufbau über
„VPN On Demand" (ab Tailscale 1.48 für iOS), Regel „Only On" gebunden an das Fahrzeug-WLAN —
kein dauerhaft aktiver Tunnel, geringerer Akkuverbrauch, und der Tunnel steht genau dann, wenn
auch die Fahrterkennung anspringt. Die WLAN-Zuordnung liegt in der Tailscale-App selbst und muss
bei einer Änderung des WLAN-Namens (§5.6) dort separat nachgezogen werden.
- **Ausfall der Datenquelle:** Veraltete Werte müssen als solche erkennbar sein. Die Anzeige
„Sicher abgestellt" hat drei Zustände: grün, rot und **unbekannt** mit Zeitstempel. Kein grünes
Häkchen auf Basis alter Daten.
- **Sicherung:** Profil und Archive müssen gesichert und wiederhergestellt werden können,
automatisch und von Hand.
- **Ausgabe:** Fahrten, Tankvorgänge und Servicebuch als CSV mit Semikolon und deutschem
Zahlenformat.
- **Kalender:** Service- und Reifenwechseltermine als Eintrag in den iOS-Kalender, mit Vorwarnung.
- **Karten:** Leaflet mit dem tatsächlich aufgezeichneten Track, nicht mit einer berechneten Route.
Kachelquelle wechselt mit dem Modus.
- **Notrufnummern** müssen auch dann erreichbar sein, wenn die Anwendung nicht lädt.
---
## 10. Vor Baubeginn zu klären
Diese Punkte waren bewusst offen und betreffen die Umsetzung in Home Assistant. Sie sind inzwischen
geklärt; Fragestellung und Entscheidung stehen im Folgenden jeweils zusammen.
1. **Einbindung der Oberfläche.** Eigenes Panel, eingebettete Seite, eigene Lovelace-Karte oder
Add-on? Der Prototyp ist eine einzelne HTML-Datei — welche Form davon trägt im Dauerbetrieb, und
wie kommt die Oberfläche an Zustände und Dienste?
**Entscheidung:** `panel_custom` — Home Assistants eingebaute Panel-Integration, per YAML
registriert, kein Add-on und keine eigene Integration nötig. Das JS-Custom-Element aus dem
Prototyp bekommt automatisch das `hass`-Objekt injiziert (Live-Zustände per WebSocket,
`callService()` für Aktionen); die bestehenden Render-Funktionen (`vHome()`, `vTrips()` usw.)
bleiben erhalten, nur die Datenquelle wechselt von den Beispielarrays auf `hass.states`.
2. **Zurückschreiben von Daten.** Wie schreibt die Oberfläche Dateien im Home-Assistant-Dateisystem?
Eigene Integration, AppDaemon, pyscript, Skript im Add-on? Diese Entscheidung bestimmt den
gesamten Aufbau.
**Entscheidung:** `pyscript` für die gesamte Logik — Fahrterkennung, Fahrtabschluss,
Belegverarbeitung, Dateizugriff. Läuft installationsunabhängig (Core, Container, OS,
Supervised), im HA-Python-Kontext, mit `@service` für aufrufbare Aktionen und
`@time_trigger`/`task.sleep` für die Wartezeit-Logik aus §7.1.
3. **Bluetooth- und WLAN-Erkennung unter iOS.** Meldet die Companion App die Verbindung zum
Fahrzeug zuverlässig genug für die Fahrterkennung, oder braucht es Kurzbefehle? **Das ist die
riskanteste Annahme des Entwurfs** — trägt sie nicht, muss die Fahrterkennung anders gelöst
werden.
**Entscheidung:** WLAN statt Bluetooth, Kurzbefehle entfallen. Die WLAN-Verbindung zum Fahrzeug
baut sich nach bisheriger Erfahrung zuverlässig sofort auf und ab; Bluetooth-Region-Monitoring
unter iOS wäre dagegen mit mehrminütiger Verzögerung riskant gewesen. Trigger ist der
Companion-App-Sensor für das verbundene WLAN (§4.2, §7.1).
4. **Verzögerung des Kilometerstands.** Wie lange dauert es nach dem Abstellen tatsächlich, bis der
Wert nachkommt? Bestimmt die Wartezeit im zweistufigen Abschluss.
**Entscheidung:** kein fester Wartewert — der Kilometerstand kommt nicht sicher mit Fahrtende,
sondern teils erst mit Beginn oder während der nächsten Fahrt. Der Fahrtabschluss läuft deshalb
ereignisgesteuert über ein Screening der Recorder-Historie statt über einen Timeout (§7.2).
5. **Auflösung des Tankfüllstands.** Prozentgenau oder gerastert? Bestimmt, ob die 97-Prozent-Regel
für die Volltankung trägt.
**Entscheidung:** ganzzahlig. Der Tankgeber meldet den Stand bereits unterhalb des
Ausdehnungsraums, 100 % sind also tatsächlich 100 % — die 97-Prozent-Schwelle bleibt
unverändert (§7.4).
6. **Meldet die Integration den Kilometerstand als `total_increasing`?** Falls nicht, ist ein
vorgeschalteter Template-Sensor nötig, sonst funktioniert der Reifenzähler nicht.
**Entscheidung:** Frage erübrigt sich — kein `utility_meter`, kein Template-Sensor. Der
Reifenzähler rechnet direkt mit dem absoluten Kilometerstand gegen den im Profil hinterlegten
Startwert je Satz (§7.5).
7. **Abholung der Belege aus dem Postfach.** Welcher Weg, und wo läuft der Parser?
**Entscheidung:** kein Postfach. Belege werden als PDF direkt in der App hochgeladen (§4.3,
§5.5, §7.7); ohne Beleg ersatzweise manuelle Eingabe von Liter und Preis.
8. **Verhalten des Tailscale-Tunnels beim Losfahren.** Steht er rechtzeitig für den Fahrtstart?
**Entscheidung:** Tailscale „VPN On Demand" mit Regel „Only On", gebunden an das Fahrzeug-WLAN
(§9). Der Tunnel baut sich damit zeitgleich mit der Fahrterkennung auf, kein dauerhaft aktiver
Tunnel nötig.
---
## 11. Abnahmekriterien
1. Eine Fahrt wird ohne Zutun erfasst, mit korrekten Kilometern aus dem Fahrzeug, und erscheint
vollständig in der Liste.
2. Ein Tankstopp mitten in einer Fahrt erzeugt **eine** Fahrt, nicht zwei.
3. Ein hochgeladener Shell-Beleg erzeugt einen vollständigen Tankvorgang. Derselbe Beleg ein
zweites Mal hochgeladen erzeugt keinen zweiten.
4. Eine manuelle Korrektur überlebt den nächsten Import.
5. Ein Eintrag im Servicebuch verschiebt die zugehörige Fälligkeit.
6. Das Umschalten der Reifen leitet die Kilometer auf den anderen Satz um und verliert bei einem
Neustart nichts.
7. Fällt die Datenquelle aus, zeigt die Oberfläche das an, statt alte Werte als aktuell auszugeben.
8. Ein Fahrzeugprofil lässt sich ausgeben, in einem Texteditor ändern und wieder einlesen.
9. Die Oberfläche ist über Tailscale erreichbar, ohne dass Home Assistant öffentlich steht.
---
## 12. Ausdrücklich nicht Bestandteil
- Fernsteuerung des Fahrzeugs — der Data-Act-Zugang ist ausschließlich lesend
- Fehlerspeicher und Live-Telemetrie über OBD
- Fahrstil- oder Effizienzbewertung
- Höchstgeschwindigkeit je Fahrt
- Mehrbenutzerbetrieb
- Veröffentlichung, Weitergabe oder Verwendung der Marken- und Schriftlizenzen außerhalb dieser
Installation
---
## 13. Was noch zu liefern ist
Vom Auftraggeber, vor oder während des Baus:
- Bilder der Winterräder in höherer Auflösung
- Fälligkeitsdatum der Kfz-Steuer
- Reifendaten je Satz: Hersteller, Modell, DOT, bisherige Laufleistung
Entfallen gegenüber der ursprünglichen Liste: Zugangsdaten und Postfach für die Belegabholung
(Beleg-Upload statt Mailanbindung, §7.7) und Bestätigung des Bluetooth-Gerätenamens des MMI
(Fahrterkennung läuft über WLAN, §7.1) — der WLAN-Name ist bereits bekannt
(`Audi_MMI_2804_5GHz`) und in den Einstellungen hinterlegt (§5.6).
---
## 14. Zeitlicher Rahmen
**Eine Frist ist hart:** Die Alt-App wird Ende 2026 abgeschaltet. Der Export des vorhandenen
Fahrtenbuchs muss vorher erfolgen — unabhängig vom Baufortschritt und als Erstes. Was danach
verloren ist, ist nicht wiederherstellbar.
Der **Import** der exportierten Daten in das neue System ist davon unabhängig und wird bewusst
zurückgestellt, bis die App sich im laufenden Betrieb bewährt hat. Die Frist betrifft nur die
Sicherung der Daten, nicht ihre Weiterverarbeitung.
Alles Übrige lässt sich auch nach der Abschaltung bauen.
---
## 15. Backlog
Punkte, die vorgemerkt, aber noch nicht umgesetzt sind.
- **Kühlwasserstand- und Ölstand-Messung und -Auswertung** (vorgemerkt 09.08.2026): analog zur
Batteriespannungs-Aufzeichnung (§5.2 „Zustand" → Batteriespannung — Verlauf, Tagesminimum/-maximum
samt Zeitstempel) — sofern die Fahrzeug-Integration entsprechende Sensoren liefert.