Fehlerspeicher, Amber statt Gruen, Tankbalken rot ab 90 km
- Neue Sensorrolle FEHLERSPEICHER_SENSOR (number_of_diagnostic_trouble_codes vom CAN) und eine fuenfte Zeile auf der Sicherheitsseite: "Keine Fehlermeldungen". Bewusst NICHT im _sicherheitscheck(): "gesichert" rechnet ein UND ueber diese Liste, und ein Eintrag im Fehlerspeicher sagt nichts darueber, ob der Wagen verschlossen dasteht. - "Zuendung an" ist Amber statt Gruen. Gruen las sich als "alles in Ordnung und sicher"; unterwegs ist kein guter Zustand, sondern ein anderer. - Das Modell-Auswahlfeld bekam dm-eingabe statt dm-auswahl - nur letzteres setzt appearance:none, deshalb zeichnete der Browser seinen nativen Pfeil neben den des Design-Systems. Die Breitenregel heisst jetzt dm-feld--fahrzeug und gilt fuer input und select. - "aktuell" erscheint erst nach einer Pruefung, und fuer beide Abschnitte gemeinsam. Der App-Abschnitt zeigte die Marke schon, sobald ein Buendel vorlag - also unmittelbar nach einem Update wieder. - Der Tankbalken wird rot ab 90 km Restreichweite, in Kilometern und nicht in Prozent: die Reichweite ist die Aussage, um die es geht, und das Fahrzeug rechnet die Fahrweise darin bereits ein. Farbe --red (Audi-CI, #F50537), nicht --bad-flaeche - letzteres ist fuer weisse Schrift darauf gewaehlt, und hier steht keine drauf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":"2026.9.5.35","sha256":"8873fddf9a976ff3317fb16cf4ed708ac19ef76dbf8faf4ff29189e2a5f83a75","bytes":324134,"gebaut":"2026-09-05T15:01:50Z"}
|
||||
{"version":"2026.9.5.39","sha256":"1a78c65f9a96298f7ed97a8595e6505cf91f00a71620b068b4afcfdd14020483","bytes":324341,"gebaut":"2026-09-05T15:29:32Z"}
|
||||
Binary file not shown.
@@ -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() {
|
||||
<div class="fig" style="font-size:60px">${CAR.reichweite != null ? de(CAR.reichweite) : "–"}<span class="unit">km</span></div>
|
||||
<span class="pct">${CAR.tankBekannt ? pct + " %" : "–"}</span>
|
||||
</div>
|
||||
<div class="balken"><i style="width:${pct}%;background:var(--fg)"></i></div>
|
||||
<div class="balken"><i style="width:${pct}%;background:var(${tankReserve() ? "--red" : "--fg"})"></i></div>
|
||||
<span class="label" style="margin-top:12px">Reichweite</span>
|
||||
</div>
|
||||
${(() => {
|
||||
@@ -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 `<div class="row sicherheitszeile">${statusKreis(ok)}
|
||||
<span class="sicherheitszeile-text">${esc(text)}</span></div>`;
|
||||
}
|
||||
function vSicherheit() {
|
||||
const g = CAR.gesichert;
|
||||
const verriegelt = sicherheitsGruppe("verriegelt");
|
||||
@@ -2464,7 +2512,7 @@ function vSicherheit() {
|
||||
return `
|
||||
<div class="szene bleed schmal"><div class="carbox">${bildMitPlatzhalter(bildAdresse("draufsicht.webp"), "draufsicht.webp", "Draufsicht", "carfix klein")}</div></div>
|
||||
<div class="tile" style="display:flex;align-items:center;gap:12px;padding:16px 20px">
|
||||
${faehrt ? '<span class="dot"></span>' : statusKreis(g)}
|
||||
${faehrt ? '<span class="dot warn"></span>' : statusKreis(g)}
|
||||
<span style="font-size:15px;color:var(--fg)">${esc(sammelText)}</span>
|
||||
</div>
|
||||
<div class="tile sicherheitsliste">
|
||||
@@ -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()}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -3833,7 +3882,9 @@ function vEinst() {
|
||||
<dd>${esc(u.version)}${u.geprueft_am ? `<small>geprüft ${dezeitpunkt(new Date(u.geprueft_am))}</small>` : ""}</dd></div></dl>
|
||||
`;
|
||||
}
|
||||
return u ? `<span class="standmarke">aktuell</span>` : "";
|
||||
// Nur nach einer Pruefung - "aktuell" ohne Pruefung waere eine
|
||||
// Behauptung ohne Grundlage. Wortgleich mit der App.
|
||||
return u && u.geprueft_am ? `<span class="standmarke">aktuell</span>` : "";
|
||||
})()}
|
||||
${INTEGRATION_UPDATE && INTEGRATION_UPDATE.fehler && !INTEGRATION_UPDATE_LAEUFT
|
||||
? `<span class="label" style="margin-top:10px;color:var(--red)">${esc(INTEGRATION_UPDATE.fehler)}</span>`
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user