Files
audi-app/custom_components/audi_dashboard/strings.json
T
tobias d8b12da36d 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>
2026-08-23 23:53:56 +02:00

175 lines
8.9 KiB
JSON

{
"config": {
"step": {
"user": {
"title": "Audi Dashboard",
"description": "Richtet das Panel \"Mein Audi\" ein. Welcher Sensor welche Rolle im Fahrzeug spielt, wird danach im Setup-Menü der App selbst zugeordnet (Einstellungen → Fahrzeug einrichten → Setup)."
}
},
"abort": {
"single_instance_allowed": "Audi Dashboard ist bereits eingerichtet."
}
},
"services": {
"jetzt_aktualisieren": {
"name": "Jetzt aktualisieren",
"description": "Stößt eine sofortige Neuabfrage beim Fahrzeug an und veröffentlicht den Fahrzeugstatus neu."
},
"screening_jetzt": {
"name": "Screening jetzt",
"description": "Versucht sofort, offene Fahrten mit Start- und Endkilometerstand zu vervollständigen."
},
"backup_jetzt": {
"name": "Sicherung jetzt",
"description": "Legt sofort eine Sicherung von Profil, Fahrten, Tankvorgängen und Sensor-Zuordnung an."
},
"profil_schreiben": {
"name": "Profil schreiben",
"description": "Überschreibt das komplette Fahrzeugprofil.",
"fields": {
"profil_json": { "name": "Profil", "description": "Das vollständige Fahrzeugprofil als JSON." }
}
},
"entitaeten_schreiben": {
"name": "Sensor-Zuordnung schreiben",
"description": "Speichert die Zuordnung von Home-Assistant-Entitäten zu den Rollen der App und wendet sie sofort an.",
"fields": {
"zuordnung_json": { "name": "Zuordnung", "description": "Feldname zu Entity-ID als JSON." }
}
},
"fahrt_manuell_anlegen": {
"name": "Fahrt anlegen",
"description": "Legt eine Fahrt von Hand an, unabhängig von der automatischen Zündungs-Erkennung.",
"fields": {
"ts_start": { "name": "Beginn", "description": "Zeitpunkt des Fahrtbeginns (ISO)." },
"ts_end": { "name": "Ende", "description": "Zeitpunkt des Fahrtendes (ISO)." },
"art": { "name": "Art", "description": "privat oder arbeitsweg." },
"start_ort": { "name": "Startort", "description": "Freitext." },
"ziel_ort": { "name": "Zielort", "description": "Freitext." },
"odo_start": { "name": "Kilometerstand bei Beginn", "description": "Leer lassen, wenn das Screening ihn ergänzen soll." },
"odo_end": { "name": "Kilometerstand bei Ende", "description": "Leer lassen, wenn das Screening ihn ergänzen soll." },
"distanz": { "name": "Strecke", "description": "Nur nötig, wenn keine Kilometerstände vorliegen." }
}
},
"fahrt_aktualisieren": {
"name": "Fahrt bearbeiten",
"description": "Ändert eine bestehende Fahrt.",
"fields": {
"trip_id": { "name": "Fahrt", "description": "trip_id der Fahrt." },
"ts_start": { "name": "Beginn", "description": "Zeitpunkt des Fahrtbeginns (ISO)." },
"ts_end": { "name": "Ende", "description": "Zeitpunkt des Fahrtendes (ISO)." },
"art": { "name": "Art", "description": "privat oder arbeitsweg." },
"start_ort": { "name": "Startort", "description": "Freitext." },
"ziel_ort": { "name": "Zielort", "description": "Freitext." },
"odo_start": { "name": "Kilometerstand bei Beginn", "description": "Von Hand gesetzt, wird vom Screening nicht mehr überschrieben." },
"odo_end": { "name": "Kilometerstand bei Ende", "description": "Von Hand gesetzt, wird vom Screening nicht mehr überschrieben." },
"distanz": { "name": "Strecke", "description": "Von Hand gesetzt." }
}
},
"fahrt_loeschen": {
"name": "Fahrt löschen",
"description": "Löscht eine Fahrt unwiderruflich.",
"fields": {
"trip_id": { "name": "Fahrt", "description": "trip_id der Fahrt." }
}
},
"beleg_hochladen": {
"name": "Beleg hochladen",
"description": "Liest einen Tankbeleg (PDF) und trägt ihn in einen bestehenden Tankvorgang nach oder gibt die Werte an die Oberfläche zurück.",
"fields": {
"pdf_base64": { "name": "PDF", "description": "Der Beleg als Base64." },
"dateiname": { "name": "Dateiname", "description": "Unter diesem Namen wird der Beleg abgelegt." },
"tank_id": { "name": "Tankvorgang", "description": "Leer lassen, um nur zu lesen, ohne etwas zu speichern." }
}
},
"tankvorgang_manuell": {
"name": "Tankvorgang anlegen",
"description": "Erfasst einen Tankvorgang von Hand.",
"fields": {
"ts": { "name": "Zeitpunkt", "description": "ISO-Zeitstempel; leer = jetzt." },
"liter": { "name": "Liter", "description": "Getankte Menge." },
"kosten": { "name": "Betrag", "description": "Der real bezahlte, bereits rabattierte Betrag." },
"km": { "name": "Kilometerstand", "description": "Leer = aus dem zugeordneten Sensor." },
"ersparnis": { "name": "Ersparnis", "description": "Rabatt in Euro." },
"station": { "name": "Station", "description": "Name der Tankstelle." },
"distanz": { "name": "Gefahrene Strecke", "description": "Leer = aus der Differenz zum letzten Tankvorgang." },
"kraftstoff": { "name": "Kraftstoff", "description": "Sorte." },
"receipt_key": { "name": "Beleg-Schlüssel", "description": "Aus einem zuvor gelesenen Beleg." },
"receipt_file": { "name": "Belegdatei", "description": "Pfad zur abgelegten PDF." }
}
},
"tankvorgang_aktualisieren": {
"name": "Tankvorgang bearbeiten",
"description": "Ändert einen bestehenden Tankvorgang.",
"fields": {
"tank_id": { "name": "Tankvorgang", "description": "tank_id des Vorgangs." },
"ts": { "name": "Zeitpunkt", "description": "ISO-Zeitstempel." },
"liter": { "name": "Liter", "description": "Getankte Menge." },
"kosten": { "name": "Betrag", "description": "Der real bezahlte, bereits rabattierte Betrag." },
"km": { "name": "Kilometerstand", "description": "Kilometerstand beim Tanken." },
"ersparnis": { "name": "Ersparnis", "description": "Rabatt in Euro." },
"station": { "name": "Station", "description": "Name der Tankstelle." },
"distanz": { "name": "Gefahrene Strecke", "description": "Seit dem letzten Tankvorgang." },
"kraftstoff": { "name": "Kraftstoff", "description": "Sorte." },
"receipt_key": { "name": "Beleg-Schlüssel", "description": "Aus einem zuvor gelesenen Beleg." },
"receipt_file": { "name": "Belegdatei", "description": "Pfad zur abgelegten PDF." }
}
},
"tankvorgang_loeschen": {
"name": "Tankvorgang löschen",
"description": "Löscht einen Tankvorgang unwiderruflich.",
"fields": {
"tank_id": { "name": "Tankvorgang", "description": "tank_id des Vorgangs." }
}
},
"bild_hochladen": {
"name": "Fahrzeugbild hochladen",
"description": "Legt ein Fahrzeugfoto unter einem der erwarteten Namen ab.",
"fields": {
"dateiname": { "name": "Dateiname", "description": "Einer der von der App erwarteten Namen." },
"daten_base64": { "name": "Bild", "description": "Die Bilddaten als Base64." }
}
},
"bild_loeschen": {
"name": "Fahrzeugbild löschen",
"description": "Entfernt ein zuvor hochgeladenes Fahrzeugfoto.",
"fields": {
"dateiname": { "name": "Dateiname", "description": "Einer der von der App erwarteten Namen." }
}
},
"reifen_wechseln": {
"name": "Reifensatz wechseln",
"description": "Schaltet den aktiven Reifensatz um.",
"fields": {
"satz": { "name": "Satz", "description": "sommer oder winter." }
}
},
"reifen_km_setzen": {
"name": "Reifen-Kilometerstand setzen",
"description": "Korrigiert den gezählten Kilometerstand eines Reifensatzes von Hand.",
"fields": {
"satz": { "name": "Satz", "description": "sommer oder winter." },
"km": { "name": "Kilometer", "description": "Der neue Zählerstand." }
}
},
"backup_wiederherstellen": {
"name": "Sicherung wiederherstellen",
"description": "Überschreibt Profil, Fahrten, Tankvorgänge und Sensor-Zuordnung mit einer zuvor exportierten Sicherung.",
"fields": {
"profil_json": { "name": "Profil", "description": "Fahrzeugprofil als JSON." },
"fahrten_json": { "name": "Fahrten", "description": "Fahrten als JSON-Liste." },
"tankvorgaenge_json": { "name": "Tankvorgänge", "description": "Tankvorgänge als JSON-Liste." },
"entitaeten_json": { "name": "Sensor-Zuordnung", "description": "Optional; fehlt sie, bleibt die aktuelle Zuordnung unangetastet." }
}
},
"historie_importieren": {
"name": "Daten aus dem Verlauf importieren",
"description": "Leitet Fahrten, Tankvorgänge und Batteriewerte rückwirkend aus dem aufgezeichneten Verlauf ab.",
"fields": {
"start": { "name": "Von", "description": "Beginn des Zeitraums (ISO, Ortszeit erlaubt)." },
"ende": { "name": "Bis", "description": "Ende des Zeitraums (ISO, Ortszeit erlaubt)." }
}
}
}
}