diff --git a/AGENTS.md b/AGENTS.md index 8d6c30f..931d94a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7770,6 +7770,75 @@ abgleichen, und nur bei bekanntem Wert) live belegt. gespeicherten Zugang; belegt sind sie über `tsc`, die 303 Tests und den Listenvergleich gegen die Panel-Quelle. +### Nachtrag (2026.9.5.36–.39): Fehlerspeicher, Amber, Reservebalken + +**Der Doppelpfeil am Modellfeld war meiner.** Das neue `` braucht diese +Klasse. + +**„Zündung an" ist Amber, nicht Grün.** Ich hatte Grün gesetzt; der Eigentümer: +grün läse sich als „alles in Ordnung und sicher". Unterwegs ist kein guter +Zustand, sondern ein anderer — Übersicht und Sicherheitsseite tragen jetzt +`--warn`. + +**Fehlerspeicher als fünfte Zeile.** Der Dongle liefert +`number_of_diagnostic_trouble_codes` direkt vom CAN (gemessen, 0 im Testwagen). +Neue Rolle `FEHLERSPEICHER_SENSOR`; die Zeile heißt „Keine Fehlermeldungen", +sonst „N Fehlermeldungen", ohne Sensor „Fehlerspeicher unbekannt". + +**Bewusst NICHT im `_sicherheitscheck()`**, sondern als eigenes Feld +`fehlerspeicher`: `gesichert` rechnet ein UND über alle Punkte dieser Liste, +und ein Eintrag im Fehlerspeicher sagt nichts darüber, ob der Wagen +verschlossen dasteht. Live belegt: `sicherheitscheck` bleibt bei 13 Punkten, +`gesichert` unverändert `true`. WELCHER Fehler vorliegt, meldet das Gerät +nicht — ein Reserve- oder Warnsignal existiert ebenfalls nicht (alle 54 +Entitäten geprüft). + +**„aktuell" erst nach einer Prüfung, für beide Abschnitte.** Der App-Abschnitt +zeigte die grüne Marke, sobald ein Bündel vorlag — also unmittelbar nach einem +Update wieder, ohne dass jemand nachgesehen hätte. Beide Marken hängen jetzt an +`geprueft_am`; der eine Knopf prüft beides, also werden beide zusammen grün. + +**Der Tankbalken wird rot ab 90 km Restreichweite.** + +Erst hatte ich das in Prozent umrechnen wollen, mit dem Argument, eine +km-Schwelle löse je nach Fahrweise bei unterschiedlichen Füllständen aus. Der +Eigentümer hat das verworfen, und zu Recht: „90km sind absolute 90km", und +„falls der verbrauch sich verdoppelt wird der balken einfach früher schon rot" +— genau das ist der Zweck. Die Reichweite ist die Aussage, um die es geht, und +das Fahrzeug rechnet die Fahrweise darin bereits ein. + +Zur Schwelle selbst, damit sie nicht als Messung gilt: **sie ist eine +Festlegung.** Belegt ist nur eine Untergrenze — das Bildschirmfoto der +myAudi-App zeigt 70 km rot; ein höherer Wert wurde nie im grauen Zustand +festgehalten. Aus unseren Daten ist die Schwelle der myAudi-App nicht +ableitbar. Gemessen wurde dabei immerhin die Umrechnung, aus 494 Wertepaaren +über 45 Tage: **10,46 km je Liter** (Median, 1,71 bis 12,53) und 0,613 l je +Prozentpunkt, also ein rechnerischer Tank von **61,3 l** — das Fahrzeugprofil +trägt 58 l. + +Farbe: **`--red` (#F50537, Audi-CI-Rot)**, nicht `--bad-flaeche` (#D70015). +Letzteres ist Apples dunkles Rot und so gewählt, dass weiße Schrift darauf +lesbar bleibt; auf dem Balken steht keine Schrift, der Grund fällt weg. Vom +Eigentümer als „weniger dunkel" gemeldet. Rot als Fläche ist sonst +zerstörenden Aktionen vorbehalten — hier eine benannte Ausnahme, weil es kein +Bedienelement ist, sondern eine Warnung. Live gemessen: `rgb(245, 5, 55)` auf +`rgba(120,120,128,.16)`, 6 px, voll gerundet. + +**Offen:** die Ziffern der Reichweite wirken in der myAudi-App dicker. Unsere +`.fig` steht auf Audi Type Wide **300** — und das ist der einzige Wide-Schnitt +im Repo (`audi-type-wide-300.woff2`; daneben nur `audi-type-400` und +`audi-type-extended-400-italic`). Ein dickerer Wide-Schnitt lässt sich damit +nicht setzen, und synthetisches Fetten verschmiert die Striche. Braucht +entweder die Schriftdatei vom Eigentümer oder die Entscheidung, für diese eine +Zahl auf „Audi Type" 400 zu wechseln. + ## Working conventions (observed — keep them) - German is the project language: identifiers, comments, commits, UI texts. Exceptions: diff --git a/companion-app/src/api/types.ts b/companion-app/src/api/types.ts index 9bb8d6d..d6c2c31 100644 --- a/companion-app/src/api/types.ts +++ b/companion-app/src/api/types.ts @@ -127,6 +127,9 @@ export interface Fahrzeugstatus { batteriespannung?: number | null; gesichert?: boolean | null; sicherheitscheck?: SicherheitsPunkt[]; + /** Diagnosecodes im Fehlerspeicher. Getrennt vom Sicherheitscheck, weil ein + Eintrag nichts darueber sagt, ob der Wagen verschlossen dasteht. */ + fehlerspeicher?: { anzahl: number | null; ok: boolean | null } | null; /** Zustand des Zündungssensors — ausdrücklich nicht „fährt": es gibt keinen Bewegungssensor, und die Zündung meldet an auch bei Zubehörstellung oder im Stand. `null`/fehlend heißt „kein Zündungssensor zugeordnet", also diff --git a/companion-app/src/daten/profilAdapter.ts b/companion-app/src/daten/profilAdapter.ts index b9aff49..de3fa44 100644 --- a/companion-app/src/daten/profilAdapter.ts +++ b/companion-app/src/daten/profilAdapter.ts @@ -66,6 +66,9 @@ export interface Fahrzeug { batteriespannung: number | null gesichert: boolean | null sicherheitscheck: SicherheitsPunkt[] + /** Diagnosecodes im Fehlerspeicher; `null` heisst "kein Sensor zugeordnet + oder er meldet nichts" - nie als "keine Fehler" deuten. */ + fehlerspeicher: { anzahl: number | null; ok: boolean | null } | null /** Zustand des Zündungssensors — nicht „fährt": ohne Bewegungssensor sagt an nur, dass die Zündung an ist. `null` heißt „kein Zündungssensor zugeordnet", also unbekannt — nicht „steht". */ @@ -181,6 +184,7 @@ export function profilZuFahrzeug(profil: Profil, status: Fahrzeugstatus): Fahrze batteriespannung: status.batteriespannung ?? null, gesichert: status.gesichert ?? null, sicherheitscheck: status.sicherheitscheck ?? [], + fehlerspeicher: status.fehlerspeicher ?? null, zuendung: status.zuendung ?? null, geparktSeit: (status.geparkt_seit as string | null) ?? null, faehrtSeit: (status.faehrt_seit as string | null) ?? null, diff --git a/companion-app/src/daten/service.test.ts b/companion-app/src/daten/service.test.ts index 532d92d..9cb2c3f 100644 --- a/companion-app/src/daten/service.test.ts +++ b/companion-app/src/daten/service.test.ts @@ -26,6 +26,7 @@ function fahrzeug(odo: number, modus = "hersteller"): Fahrzeug { batteriespannung: null, gesichert: null, sicherheitscheck: [], + fehlerspeicher: null, zuendung: null, geparktSeit: null, faehrtSeit: null, diff --git a/companion-app/src/screens/Einstellungen.tsx b/companion-app/src/screens/Einstellungen.tsx index f378a39..92b1670 100644 --- a/companion-app/src/screens/Einstellungen.tsx +++ b/companion-app/src/screens/Einstellungen.tsx @@ -412,8 +412,13 @@ export function Einstellungen({ gesucht. Die Liste selbst steht in daten/fahrzeugmodelle.ts und wird von einem Test gegen die Panel-Fassung geprüft. */} + {/* dm-auswahl, NICHT dm-eingabe: nur dort steht `appearance: none`. + Der Aufklapp-Pfeil kommt als Hintergrundbild aus dem + Design-System (.ads-feld select); ohne den Reset zeichnet der + Browser seinen eigenen daneben — vom Eigentümer am 05.09.2026 + als „Doppelpfeil" gemeldet. */} aendern({ kennzeichen: e.target.value })} onBlur={() => sichern()} @@ -437,7 +442,7 @@ export function Einstellungen({ setzeErstzulassung(e.target.value)} @@ -446,7 +451,7 @@ export function Einstellungen({ aendern({ ausfuehrung: e.target.value })} onBlur={() => sichern()} @@ -844,7 +849,13 @@ export function Einstellungen({ ) : ( <> - {integrationUpdate && aktuell} + {/* Nur nach einer Prüfung. „aktuell" ohne Prüfung wäre eine + Behauptung ohne Grundlage — dieselbe Bedingung trägt der + App-Abschnitt darunter, damit beide gemeinsam grün werden + (Vorgabe des Eigentümers, 05.09.2026). */} + {integrationUpdate?.geprueft_am && ( + aktuell + )} )} {updateAktionFehler &&

{updateAktionFehler}

} @@ -890,11 +901,16 @@ export function Einstellungen({ nach dem Neustart etwas. */

Update {otaBuendel.version} vorhanden

) : otaBuendel ? ( - /* Dieselbe grüne Marke wie bei der Integration, statt eines - Satzes - Vorgabe des Eigentümers, 05.09.2026. Ohne Zeitpunkt: - anders als bei der Integration wird hier nicht auf Knopfdruck - geprüft, das Bündel meldet der Server beim Laden mit. */ - aktuell + /* Dieselbe grüne Marke wie bei der Integration - und an + dieselbe Bedingung geknüpft: erst nach einer Prüfung. Das + Bündel meldet der Server zwar bei jedem Laden mit, aber + „aktuell" stand damit schon unmittelbar nach einem Update + wieder da, ohne dass jemand nachgesehen hätte (vom Eigentümer + am 05.09.2026 bemerkt). Der eine Knopf unten prüft beides, + also werden auch beide zusammen grün. */ + integrationUpdate?.geprueft_am ? ( + aktuell + ) : null ) : (

Der Server hat gerade kein Update-Bündel hinterlegt. diff --git a/companion-app/src/screens/Fahrzeugstatus.tsx b/companion-app/src/screens/Fahrzeugstatus.tsx index a6f77c7..b7dbed2 100644 --- a/companion-app/src/screens/Fahrzeugstatus.tsx +++ b/companion-app/src/screens/Fahrzeugstatus.tsx @@ -44,6 +44,17 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void Schlosssensoren melden — nur die Überschrift darf nicht „abgestellt" behaupten, während die Zündung an ist. */ const faehrt = standortZustand(fahrzeug).faehrt + const fehlerAnzahl = + typeof fahrzeug.fehlerspeicher?.anzahl === "number" ? fahrzeug.fehlerspeicher.anzahl : null + const fehlerOk = fehlerAnzahl === null ? null : fehlerAnzahl === 0 + const fehlerText = + fehlerAnzahl === null + ? "Fehlerspeicher unbekannt" + : fehlerAnzahl === 0 + ? "Keine Fehlermeldungen" + : fehlerAnzahl === 1 + ? "1 Fehlermeldung" + : `${fehlerAnzahl} Fehlermeldungen` const sammelText = faehrt ? "Zündung an - Fahrzeug in Betrieb" : gesichert === null @@ -68,7 +79,7 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void {/* Während der Fahrt weder Haken noch Kreuz noch Fragezeichen, sondern derselbe Punkt wie im Standortmenü — der Zustand ist dann nicht „geprüft", sondern schlicht ein anderer. */} - {faehrt ? : } + {faehrt ? : } {sammelText} @@ -105,6 +116,15 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void {licht === null ? "Licht unbekannt" : licht ? "Licht ausgeschaltet" : "Licht eingeschaltet"} + {/* Der Fehlerspeicher des Fahrzeugs. Steht bewusst NICHT im + Sicherheitscheck und geht damit auch nicht in „sicher + abgestellt" ein — ein Eintrag sagt nichts darüber, ob der Wagen + verschlossen dasteht (siehe _fehlerspeicher() im Backend). + WELCHER Fehler vorliegt, meldet das Gerät nicht. */} +

+ + {fehlerText} +
diff --git a/companion-app/src/screens/Uebersicht.tsx b/companion-app/src/screens/Uebersicht.tsx index 065b955..a386ce9 100644 --- a/companion-app/src/screens/Uebersicht.tsx +++ b/companion-app/src/screens/Uebersicht.tsx @@ -29,6 +29,8 @@ import { Typenschild, schildErkennen } from "./Typenschild" // links der Kennzahl - deckungsgleich mit ART_ICON im Panel (vHome()). Die // Hauptuntersuchung hat kein Restkilometer-Ziel und zeigt stattdessen den // Art-Namen selbst unter dem (gleich großen) Datum. +const RESERVE_KM = 90 + const SERVICE_SYMBOL: Partial> = { "Ölwechsel": SymbolOelwechsel, "Inspektion": SymbolInspektion, @@ -102,9 +104,30 @@ export function Uebersicht({ geheZu }: { geheZu: (name: SeitenName, id?: string) Wortlaut wie im Standortmenü: „Zündung an", nicht „fährt" — einen Bewegungssensor gibt es nicht, die Zündung steht auch im Stand mit laufendem Motor auf an. Deckungsgleich mit vHome() im Panel. */ + /* Ab wann der Tankbalken rot wird - in KILOMETERN Restreichweite, nicht in + Prozent. Die Reichweite ist die Aussage, um die es geht ("wie weit komme ich + noch"), und das Fahrzeug rechnet die Fahrweise darin bereits ein; eine + Prozentschwelle haette bei 1,71 bis 12,53 km je Liter (in 45 Tagen gemessen) + bei ganz unterschiedlichen Restreichweiten ausgeloest. + + 90 km ist die Zahl des Eigentuemers, an der myAudi-App beobachtet. Belegt ist + daraus nur eine Untergrenze: sein Bildschirmfoto zeigt 70 km rot, ein Wert + darueber wurde nie im grauen Zustand festgehalten. Der Dongle liefert kein + Reserve- oder Warnsignal (alle 54 Entitaeten geprueft), die Schwelle der + myAudi-App steht also in keinen Daten, die wir haben - dies ist eine + Festlegung, keine Messung. + + Ohne bekannte Reichweite bleibt der Balken neutral: eine Warnung aus + fehlenden Daten waere geraten. */ + const tankReserve = + typeof fahrzeug.reichweite === "number" && fahrzeug.reichweite <= RESERVE_KM + const faehrt = standortZustand(fahrzeug).faehrt + /* Amber, nicht grün: „Zündung an" ist kein guter Zustand, sondern ein + anderer — grün läse sich als „alles in Ordnung und sicher" (Vorgabe des + Eigentümers, 05.09.2026). */ const sicherheitsstatus = faehrt - ? "ok" + ? "warn" : fahrzeug.gesichert === true ? "ok" : fahrzeug.gesichert === false @@ -190,7 +213,10 @@ export function Uebersicht({ geheZu }: { geheZu: (name: SeitenName, id?: string) {fahrzeug.tankBekannt ? `${de(fahrzeug.tankPct)} %` : "–"} - + Reichweite diff --git a/companion-app/src/stile/screens.css b/companion-app/src/stile/screens.css index 44c20a4..966d823 100644 --- a/companion-app/src/stile/screens.css +++ b/companion-app/src/stile/screens.css @@ -37,7 +37,8 @@ Oberflächen: das längste Label ("Erstzulassung") lässt in der App nur 183px fürs Feld, im Panel 196px. 180 passt in beiden mit etwas Luft und hält sie zugleich untereinander gleich. */ -.ads-feld input.dm-eingabe--fahrzeug { +.ads-feld input.dm-feld--fahrzeug, +.ads-feld select.dm-feld--fahrzeug { width: 180px; flex: 0 0 auto; max-width: none; @@ -2383,3 +2384,17 @@ input[type="range"] { align-items: center; gap: 10px; } + +/* Tankbalken in der Reserve: das Audi-CI-Rot (--red, #F50537), nicht + --bad-flaeche (#D70015). Letzteres ist Apples dunkles Rot und ist so + gewaehlt, dass WEISSE SCHRIFT darauf lesbar bleibt - hier steht keine + Schrift auf der Flaeche, der Grund faellt also weg. Der Balken bildet die + myAudi-App nach, und deren Rot ist das der Marke (vom Eigentuemer am + 05.09.2026 als "weniger dunkel" gemeldet). + + Rot als FLAECHE ist in diesem Projekt sonst zerstoerenden Aktionen + vorbehalten. Hier ist es kein Bedienelement, sondern eine Warnung - eine + bewusste, benannte Ausnahme. Wortgleich mit dem Panel. */ +.dm-balken--reserve .ads-balken > i { + background: var(--red); +} diff --git a/custom_components/audi_dashboard/einstellungen.py b/custom_components/audi_dashboard/einstellungen.py index b5aad46..4a4e539 100644 --- a/custom_components/audi_dashboard/einstellungen.py +++ b/custom_components/audi_dashboard/einstellungen.py @@ -163,6 +163,12 @@ class Sensorzuordnung: # veroeffentlichung.py. DACH_SENSOR: str = "" LICHT_SENSOR: str = "" + # Anzahl der im Fehlerspeicher stehenden Diagnosecodes (OBD/CAN). 0 heisst + # "keine Fehlermeldungen"; jeder Wert darueber ist einer. Der Sensor sagt + # NICHT, welcher Fehler vorliegt - das steht nicht im Datensatz des + # Geraets. Zaehlt bewusst nicht in "sicher abgestellt" hinein: ein Auto + # mit einem Eintrag im Fehlerspeicher steht trotzdem verschlossen da. + FEHLERSPEICHER_SENSOR: str = "" # Vom Fahrzeug selbst gemeldete Service-Fälligkeit (ergänzt die # App-eigene, aus dem Servicebuch berechnete Prognose). @@ -322,6 +328,11 @@ FELDER: list[dict] = [ "domains": ["binary_sensor"], "device_classes": ["light"], "units": [], "liste": False, "pflicht": False, "beispiel": "parking_lights", "stichworte": ["licht", "standlicht", "light", "parking lights"]}, + {"key": "FEHLERSPEICHER_SENSOR", "label": "Fehlerspeicher", "gruppe": "sicherheit", + "hinweis": "Anzahl der Diagnosecodes (DTC). 0 = keine Fehlermeldungen.", + "domains": ["sensor"], "device_classes": [], "units": [], "liste": False, "pflicht": False, + "beispiel": "number_of_diagnostic_trouble_codes", + "stichworte": ["dtc", "fehler", "diagnostic", "trouble", "codes", "fault"]}, {"key": "NAECHSTER_OELWECHSEL_SENSOR", "label": "Nächster Ölwechsel", "gruppe": "uebersicht", "hinweis": "Vom Fahrzeug selbst gemeldete Fälligkeit, ergänzt die App-eigene Servicebuch-Prognose.", "domains": ["sensor"], "device_classes": ["date", "timestamp"], "units": [], "liste": False, "pflicht": False, diff --git a/custom_components/audi_dashboard/frontend/app/bundle.json b/custom_components/audi_dashboard/frontend/app/bundle.json index 5b20db9..c42e66d 100644 --- a/custom_components/audi_dashboard/frontend/app/bundle.json +++ b/custom_components/audi_dashboard/frontend/app/bundle.json @@ -1 +1 @@ -{"version":"2026.9.5.35","sha256":"8873fddf9a976ff3317fb16cf4ed708ac19ef76dbf8faf4ff29189e2a5f83a75","bytes":324134,"gebaut":"2026-09-05T15:01:50Z"} \ No newline at end of file +{"version":"2026.9.5.39","sha256":"1a78c65f9a96298f7ed97a8595e6505cf91f00a71620b068b4afcfdd14020483","bytes":324341,"gebaut":"2026-09-05T15:29:32Z"} \ No newline at end of file diff --git a/custom_components/audi_dashboard/frontend/app/bundle.zip b/custom_components/audi_dashboard/frontend/app/bundle.zip index 1b52a1d..5800312 100644 Binary files a/custom_components/audi_dashboard/frontend/app/bundle.zip and b/custom_components/audi_dashboard/frontend/app/bundle.zip differ diff --git a/custom_components/audi_dashboard/frontend/audi-dashboard-app.js b/custom_components/audi_dashboard/frontend/audi-dashboard-app.js index b0df8e1..2251ffb 100644 --- a/custom_components/audi_dashboard/frontend/audi-dashboard-app.js +++ b/custom_components/audi_dashboard/frontend/audi-dashboard-app.js @@ -232,6 +232,8 @@ function profilZuCar(p, status) { reichweite: status.reichweite_km, batteriespannung: status.batteriespannung, gesichert: status.gesichert, + // Getrennt vom Sicherheitscheck, siehe _fehlerspeicher() im Backend. + fehlerspeicher: status.fehlerspeicher ?? null, sicherheitscheck: status.sicherheitscheck || [], zuendung: status.zuendung ?? null, geparktSeit: status.geparkt_seit ?? null, @@ -2298,6 +2300,25 @@ function standAlterTicken() { const sy = $("#sync span"); if (sy) sy.textContent = standAlterText(); } +/* Ab wann der Tankbalken rot wird - in KILOMETERN Restreichweite, nicht in + Prozent. Die Reichweite ist die Aussage, um die es geht ("wie weit komme ich + noch"), und das Fahrzeug rechnet die Fahrweise darin bereits ein; eine + Prozentschwelle haette bei 1,71 bis 12,53 km je Liter (in 45 Tagen gemessen) + bei ganz unterschiedlichen Restreichweiten ausgeloest. + + 90 km ist die Zahl des Eigentuemers, an der myAudi-App beobachtet. Belegt ist + daraus nur eine Untergrenze: sein Bildschirmfoto zeigt 70 km rot, ein Wert + darueber wurde nie im grauen Zustand festgehalten. Der Dongle liefert kein + Reserve- oder Warnsignal (alle 54 Entitaeten geprueft), die Schwelle der + myAudi-App steht also in keinen Daten, die wir haben - dies ist eine + Festlegung, keine Messung. + + Ohne bekannte Reichweite bleibt der Balken neutral: eine Warnung aus + fehlenden Daten waere geraten. */ +const RESERVE_KM = 90; +function tankReserve() { + return typeof CAR.reichweite === "number" && CAR.reichweite <= RESERVE_KM; +} function vHome() { const g = CAR.gesichert; /* Faehrt der Wagen, kann er nicht gleichzeitig "sicher abgestellt" sein - @@ -2319,7 +2340,10 @@ function vHome() { const statusText = faehrt ? "Zündung an" : g === null ? "Status unbekannt" : g ? "Sicher abgestellt" : "Nicht sicher abgestellt"; - const statusDot = faehrt ? "" : g === null ? "warn" : g ? "" : "bad"; + /* Amber, nicht gruen: "Zuendung an" ist kein guter Zustand, sondern ein + anderer - gruen laese sich als "alles in Ordnung und sicher" (Vorgabe des + Eigentuemers, 05.09.2026). */ + const statusDot = faehrt ? "warn" : g === null ? "warn" : g ? "" : "bad"; const pct = CAR.tankPct; const t = naechsterTermin(); /* C2/C5/D1: Reihenfolge der myAudi-App - randloses Fahrzeugbild, Name und @@ -2345,7 +2369,7 @@ function vHome() {
${CAR.reichweite != null ? de(CAR.reichweite) : "–"}km
${CAR.tankBekannt ? pct + " %" : "–"} -
+
Reichweite ${(() => { @@ -2436,6 +2460,30 @@ function sicherheitsGruppe(gruppe) { return { eintraege, ok }; } +/* Der Fehlerspeicher des Fahrzeugs, als eigene Zeile unter den vier + Sammelzeilen. Er steht bewusst NICHT im Sicherheitscheck und geht damit + auch nicht in "sicher abgestellt" ein: ein Eintrag im Fehlerspeicher sagt + nichts darueber, ob der Wagen verschlossen dasteht (siehe + _fehlerspeicher() im Backend). + + Die Anzahl wird genannt, sobald sie groesser als null ist - "es liegt etwas + vor" ohne Zahl waere weniger, als der Sensor hergibt. WELCHER Fehler es + ist, steht nicht im Datensatz des Geraets und kann hier deshalb auch nicht + stehen. */ +function fehlerzeile() { + const f = CAR.fehlerspeicher || {}; + const anzahl = typeof f.anzahl === "number" ? f.anzahl : null; + const ok = anzahl === null ? null : anzahl === 0; + const text = anzahl === null + ? "Fehlerspeicher unbekannt" + : anzahl === 0 + ? "Keine Fehlermeldungen" + : anzahl === 1 + ? "1 Fehlermeldung" + : `${anzahl} Fehlermeldungen`; + return `
${statusKreis(ok)} + ${esc(text)}
`; +} function vSicherheit() { const g = CAR.gesichert; const verriegelt = sicherheitsGruppe("verriegelt"); @@ -2464,7 +2512,7 @@ function vSicherheit() { return `
${bildMitPlatzhalter(bildAdresse("draufsicht.webp"), "draufsicht.webp", "Draufsicht", "carfix klein")}
- ${faehrt ? '' : statusKreis(g)} + ${faehrt ? '' : statusKreis(g)} ${esc(sammelText)}
@@ -2472,6 +2520,7 @@ function vSicherheit() { ${zeile("Türen und Klappen geschlossen", tuerenKlappen.ok, "Türen oder Klappen offen", "Türen/Klappen unbekannt", "tuerenklappen")} ${zeile("Fenster und Dach geschlossen", fensterDach.ok, "Fenster oder Dach offen", "Fenster/Dach unbekannt")} ${zeile("Licht ausgeschaltet", licht.ok, "Licht eingeschaltet", "Licht unbekannt")} + ${fehlerzeile()}
`; } @@ -3833,7 +3882,9 @@ function vEinst() {
${esc(u.version)}${u.geprueft_am ? `geprüft ${dezeitpunkt(new Date(u.geprueft_am))}` : ""}
`; } - return u ? `aktuell` : ""; + // Nur nach einer Pruefung - "aktuell" ohne Pruefung waere eine + // Behauptung ohne Grundlage. Wortgleich mit der App. + return u && u.geprueft_am ? `aktuell` : ""; })()} ${INTEGRATION_UPDATE && INTEGRATION_UPDATE.fehler && !INTEGRATION_UPDATE_LAEUFT ? `${esc(INTEGRATION_UPDATE.fehler)}` diff --git a/custom_components/audi_dashboard/manifest.json b/custom_components/audi_dashboard/manifest.json index 610234d..506cbe1 100644 --- a/custom_components/audi_dashboard/manifest.json +++ b/custom_components/audi_dashboard/manifest.json @@ -1,7 +1,7 @@ { "domain": "audi_dashboard", "name": "Audi Dashboard", - "version": "2026.9.5.35", + "version": "2026.9.5.39", "documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md", "issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues", "codeowners": [ diff --git a/custom_components/audi_dashboard/veroeffentlichung.py b/custom_components/audi_dashboard/veroeffentlichung.py index 943760c..73ecb14 100644 --- a/custom_components/audi_dashboard/veroeffentlichung.py +++ b/custom_components/audi_dashboard/veroeffentlichung.py @@ -190,6 +190,26 @@ def _sicherheitscheck(hass: HomeAssistant, werte: Sensorzuordnung) -> list[dict] return eintraege +def _fehlerspeicher(hass: HomeAssistant, werte: Sensorzuordnung) -> dict: + """Wie viele Diagnosecodes im Fehlerspeicher stehen. + + BEWUSST NICHT Teil von _sicherheitscheck(): dort steht ausschliesslich, + was zu oder verriegelt ist, und daraus rechnet "gesichert" ein UND ueber + alle Punkte. Ein Fehlerspeichereintrag sagt nichts darueber, ob der Wagen + sicher abgestellt ist - er wuerde die Aussage still verfaelschen. + + "anzahl" ist None, solange kein Sensor zugeordnet ist oder er nichts + meldet; die Oberflaechen zeigen das als "unbekannt" und raten nicht auf + "keine Fehler". + """ + roh = zustand_oder_none(hass, werte.FEHLERSPEICHER_SENSOR) + anzahl = _zu_zahl(roh) + if anzahl is None: + return {"anzahl": None, "ok": None} + ganz = int(anzahl) + return {"anzahl": ganz, "ok": ganz == 0} + + def fahrzeugstatus( hass: HomeAssistant, werte: Sensorzuordnung, @@ -238,6 +258,8 @@ def fahrzeugstatus( "batteriespannung": spannung, "gesichert": gesichert, "sicherheitscheck": sicherheitscheck, + # Getrennt vom Sicherheitscheck, siehe _fehlerspeicher(). + "fehlerspeicher": _fehlerspeicher(hass, werte), # Fährt das Fahrzeug gerade? Kommt aus derselben Zündungs-Entität, die # auch die Fahrterkennung als maßgebliches Signal für Fahrtbeginn und # -ende nimmt - damit sagen Anzeige und Erfassung zwangsläufig