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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -26,6 +26,7 @@ function fahrzeug(odo: number, modus = "hersteller"): Fahrzeug {
|
||||
batteriespannung: null,
|
||||
gesichert: null,
|
||||
sicherheitscheck: [],
|
||||
fehlerspeicher: null,
|
||||
zuendung: null,
|
||||
geparktSeit: null,
|
||||
faehrtSeit: null,
|
||||
|
||||
@@ -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. */}
|
||||
<Feld label="Modell">
|
||||
{/* 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. */}
|
||||
<select
|
||||
className="dm-eingabe dm-eingabe--fahrzeug"
|
||||
className="dm-auswahl dm-feld--fahrzeug"
|
||||
value={werte.fahrzeugtitel}
|
||||
onChange={(e) => {
|
||||
aendern({ fahrzeugtitel: e.target.value })
|
||||
@@ -429,7 +434,7 @@ export function Einstellungen({
|
||||
</Feld>
|
||||
<Feld label="Kennzeichen">
|
||||
<input
|
||||
className="dm-eingabe dm-eingabe--fahrzeug"
|
||||
className="dm-eingabe dm-feld--fahrzeug"
|
||||
value={werte.kennzeichen}
|
||||
onChange={(e) => aendern({ kennzeichen: e.target.value })}
|
||||
onBlur={() => sichern()}
|
||||
@@ -437,7 +442,7 @@ export function Einstellungen({
|
||||
</Feld>
|
||||
<Feld label="Erstzulassung">
|
||||
<input
|
||||
className="dm-eingabe dm-eingabe--fahrzeug"
|
||||
className="dm-eingabe dm-feld--fahrzeug"
|
||||
placeholder="TT.MM.JJJJ"
|
||||
value={erstzulassungWert}
|
||||
onChange={(e) => setzeErstzulassung(e.target.value)}
|
||||
@@ -446,7 +451,7 @@ export function Einstellungen({
|
||||
</Feld>
|
||||
<Feld label="Ausführung" last>
|
||||
<input
|
||||
className="dm-eingabe dm-eingabe--fahrzeug"
|
||||
className="dm-eingabe dm-feld--fahrzeug"
|
||||
value={werte.ausfuehrung}
|
||||
onChange={(e) => aendern({ ausfuehrung: e.target.value })}
|
||||
onBlur={() => sichern()}
|
||||
@@ -844,7 +849,13 @@ export function Einstellungen({
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{integrationUpdate && <span className="dm-standmarke">aktuell</span>}
|
||||
{/* 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 && (
|
||||
<span className="dm-standmarke">aktuell</span>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{updateAktionFehler && <p className="dm-fehler">{updateAktionFehler}</p>}
|
||||
@@ -890,11 +901,16 @@ export function Einstellungen({
|
||||
nach dem Neustart etwas. */
|
||||
<p className="dm-erklaerung">Update {otaBuendel.version} vorhanden</p>
|
||||
) : 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. */
|
||||
<span className="dm-standmarke">aktuell</span>
|
||||
/* 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 ? (
|
||||
<span className="dm-standmarke">aktuell</span>
|
||||
) : null
|
||||
) : (
|
||||
<p className="dm-erklaerung">
|
||||
Der Server hat gerade kein Update-Bündel hinterlegt.
|
||||
|
||||
@@ -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 ? <span className="ads-dot" /> : <StatusKreis ok={gesichert} />}
|
||||
{faehrt ? <span className="ads-dot ads-dot--warn" /> : <StatusKreis ok={gesichert} />}
|
||||
<span>{sammelText}</span>
|
||||
</Tile>
|
||||
|
||||
@@ -105,6 +116,15 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void
|
||||
{licht === null ? "Licht unbekannt" : licht ? "Licht ausgeschaltet" : "Licht eingeschaltet"}
|
||||
</span>
|
||||
</div>
|
||||
{/* 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. */}
|
||||
<div className="dm-sicherheitszeile">
|
||||
<StatusKreis ok={fehlerOk} />
|
||||
<span className="dm-sicherheitszeile__text">{fehlerText}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Tile>
|
||||
</>
|
||||
|
||||
@@ -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<Record<string, typeof SymbolOelwechsel>> = {
|
||||
"Ö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)} %` : "–"}
|
||||
</span>
|
||||
</div>
|
||||
<ProgressBar percent={Math.max(0, Math.min(100, fahrzeug.tankPct))} />
|
||||
<ProgressBar
|
||||
percent={Math.max(0, Math.min(100, fahrzeug.tankPct))}
|
||||
className={tankReserve ? "dm-balken--reserve" : ""}
|
||||
/>
|
||||
<span className="ads-eyebrow" style={{ marginTop: "var(--sp-3)" }}>
|
||||
Reichweite
|
||||
</span>
|
||||
|
||||
@@ -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"] {
|
||||
/* Spinner UND Beschriftung in EINEM Knopf: seit dem 05.09.2026 trägt der
|
||||
Knopf der Update-Kachel den laufenden Vorgang selbst, statt dass daneben
|
||||
eine eigene Ladezeile steht (Vorgabe des Eigentümers: „warum nicht den
|
||||
update suchen button dafür verwenden"). */
|
||||
.dm-knopflader {
|
||||
display: inline-flex;
|
||||
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).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user