e1d570992e
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>
450 lines
23 KiB
Markdown
450 lines
23 KiB
Markdown
# 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 6–12 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.
|