diff --git a/AGENTS.md b/AGENTS.md
index e16fa0e..8d6c30f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,6 +1,6 @@
# AGENTS.md — Project state, review findings, open items, and working rules
-**Last updated: 2026-09-04** (Tankstelle zweizeilig und antippbar, die Belegkarte sagt bei
+**Last updated: 2026-09-05** (Tankstelle zweizeilig und antippbar, die Belegkarte sagt bei
fehlender Position die Wahrheit statt einen toten Knopf zu zeigen, der Regler bekommt einen
Speichern-Knopf, und die Share-Erweiterung trug eine andere Versionsnummer als die App;
dazu die Kopfmarke statt der Firmierung des Betreibers und ein
@@ -7633,6 +7633,143 @@ verwerfen - was sie fangen soll, liegt Jahrzehnte daneben.
An acht Faellen geprueft: Epoche, beide ID-Verwechslungen und 366 Tage
verworfen; jetzt, 2 Tage und 364 Tage angenommen.
+## DA. Ein Knopf statt drei, abgestellt schließt fahrend aus, und zwei Tankvorgänge aus einem Datensatz (2026.9.5.35)
+
+### Die Update-Kachel hat genau einen Knopf
+
+Rückfrage des Eigentümers: *„update installieren ist ein separater button unter
+integration. warum nicht den update suchen button dafür verwenden und nur die
+optik und schrift zur installation anpassen?"* — berechtigt: über dem Suchknopf
+stand je nach Zustand ein zweiter, gleich aussehender Knopf.
+
+Der eine Knopf am Kachelende trägt jetzt in jedem Zustand den **nächsten
+fälligen Schritt**, Beschriftung und Füllung wechseln mit:
+
+| Zustand | Knopf |
+|---|---|
+| läuft gerade | Kreisel im Knopf, „Installiere …" / „Home Assistant startet neu …" / „Prüfe …" |
+| installiert, Neustart nötig | „Installation abschließen und neu starten" (gefüllt) |
+| installiert, nur Oberfläche (Panel) | „Seite neu laden" (gefüllt) |
+| Update verfügbar | „Update installieren" (gefüllt) |
+| sonst | „Auf Update prüfen" |
+
+Die Reihenfolge ist eine **Rangfolge, keine Auswahl**: liegt ein Neustart an,
+ist das der nächste Schritt, egal was sonst bereitliegt. Ein gleichzeitiges
+Integrations- UND App-Update gibt es dabei praktisch nicht — `buendelPasst()`
+bietet ein Bündel erst an, wenn es zur laufenden Serverfassung passt, also nach
+der Integration.
+
+Die Abschnitte darüber behalten ihre Werte- und Meldungszeilen und verlieren nur
+ihre Knöpfe. Der Abstand unter der Trennlinie war 28 px (16 px `padding` plus
+12 px `margin` der Werteliste, die wegen des `padding` **nicht** kollabieren) —
+`.dm-kachelabschnitt > :first-child { margin-top: 0 }` lässt nur noch das
+`padding` zählen.
+
+### Modell ist auch in der App ein Auswahlfeld
+
+Vom Eigentümer bemerkt: *„einrichten/modell ist in der app kein dropdown"*. Das
+Panel hatte seit jeher ein `
-
- void updateNeustartAusloesen()}>
- Installation abschließen und neu starten
-
-
>
) : (
<>
@@ -877,11 +873,6 @@ export function Einstellungen({
Lädt die Oberfläche neu und startet die App neu. Fahrzeugprofil, Fahrten und
Tankvorgänge sind davon nicht betroffen — die liegen in Home Assistant.
-
}
>
) : otaBuendel &&
@@ -912,18 +903,59 @@ export function Einstellungen({
)}
- {/* Ein Suchknopf für die ganze Kachel, ganz unten: er steht damit unter
- beiden Abschnitten und legt nahe, was er tut - nach Neuem für
- Integration UND App sehen (Vorgabe des Eigentümers, 05.09.2026).
+ {/* EIN Knopf für die ganze Kachel, ganz unten: er steht unter beiden
+ Abschnitten und trägt in jedem Zustand den nächsten fälligen
+ Schritt - suchen, installieren, Neustart. Bis zum 05.09.2026 stand
+ darüber noch ein zweiter Knopf im jeweiligen Abschnitt; der
+ Eigentümer: „warum nicht den update suchen button dafür verwenden
+ und nur die optik und schrift zur installation anpassen?" - genau
+ das passiert hier, Beschriftung und Füllung wechseln mit dem
+ Zustand. Wortgleich mit dem Panel (updateKnopf()).
- Er ist in JEDEM Zustand da. Vorher sass er nur im Zweig "ist
- aktuell", und daneben brauchte es ein zweites "Erneut prüfen", damit
- man eine womöglich wochenalte Zahl überhaupt auffrischen konnte,
- solange ein Update angeboten wurde. Das erübrigt sich hier. */}
+ Die Reihenfolge ist eine Rangfolge, keine Auswahl: liegt ein
+ Neustart an, ist das der nächste Schritt, egal was sonst noch
+ bereitliegt. Integrations- UND App-Update gleichzeitig gibt es
+ dabei praktisch nicht - das Bündel wird erst angeboten, wenn es zur
+ laufenden Serverfassung passt (buendelPasst), also nach der
+ Integration. */}
{/* Der Zeitpunkt gehört zum Suchvorgang, nicht zu einem der beiden
Abschnitte - er stand bis zum 05.09.2026 an der grünen Marke der
diff --git a/companion-app/src/screens/Fahrzeugstatus.tsx b/companion-app/src/screens/Fahrzeugstatus.tsx
index 71ab933..a6f77c7 100644
--- a/companion-app/src/screens/Fahrzeugstatus.tsx
+++ b/companion-app/src/screens/Fahrzeugstatus.tsx
@@ -17,6 +17,7 @@ import { useDaten } from "../daten/DatenKontext"
import type { SeitenName } from "../navigation"
import { gruppenErgebnis, Leerzustand, StatusKreis } from "./bausteine"
import { Bild } from "./Bild"
+import { standortZustand } from "./Standort"
export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void }) {
const { fahrzeug } = useDaten()
@@ -37,8 +38,15 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void
const fensterDach = gruppenErgebnis(punkte.filter((p) => p.gruppe === "fenster_dach"))
const licht = gruppenErgebnis(punkte.filter((p) => p.gruppe === "licht"))
const gesichert = fahrzeug.gesichert
- const sammelText =
- gesichert === null
+ /* Dieselbe Regel wie auf der Übersicht: unterwegs ist der Wagen nicht
+ abgestellt (Vorgabe des Eigentümers, 05.09.2026). Die vier Sammelzeilen
+ darunter bleiben stehen und zeigen weiter, was die Tür-, Fenster- und
+ Schlosssensoren melden — nur die Überschrift darf nicht „abgestellt"
+ behaupten, während die Zündung an ist. */
+ const faehrt = standortZustand(fahrzeug).faehrt
+ const sammelText = faehrt
+ ? "Zündung an - Fahrzeug in Betrieb"
+ : gesichert === null
? "Zustand nicht vollständig bekannt"
: gesichert
? "Fahrzeug ist sicher abgestellt"
@@ -57,7 +65,10 @@ export function Fahrzeugstatus({ geheZu }: { geheZu: (name: SeitenName) => void
Kreis-Häkchen-Symbol wie die vier Zeilen unten (nicht der generische
StatusRow-Punkt), keine Zeitangabe - das Panel zeigt dort keine. */}
-
+ {/* 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 ? : }
{sammelText}
diff --git a/companion-app/src/screens/Standort.tsx b/companion-app/src/screens/Standort.tsx
index 24df691..24def78 100644
--- a/companion-app/src/screens/Standort.tsx
+++ b/companion-app/src/screens/Standort.tsx
@@ -124,7 +124,7 @@ const PARKPLATZ_AB_MIN = 15
Kein Rueckfall auf die Fahrtenliste: null heisst unbekannt, und das wird
auch so angezeigt. Eine falsche Zahl ist schlechter als keine. */
-function standortZustand(
+export function standortZustand(
fahrzeug: Fahrzeug,
): { faehrt: boolean; unbekannt: boolean; seitTs: number | null; geparkt: boolean } {
const roh = fahrzeug.geparktSeit ? new Date(fahrzeug.geparktSeit).getTime() : NaN
diff --git a/companion-app/src/screens/Uebersicht.tsx b/companion-app/src/screens/Uebersicht.tsx
index a80f7df..065b955 100644
--- a/companion-app/src/screens/Uebersicht.tsx
+++ b/companion-app/src/screens/Uebersicht.tsx
@@ -21,7 +21,7 @@ import { Blattzeile, Leerzustand } from "./bausteine"
import { strecke } from "./Fahrten"
import { Bild } from "./Bild"
import type { ServicebuchEintrag } from "./Service"
-import { StandortVorschau } from "./Standort"
+import { StandortVorschau, standortZustand } from "./Standort"
import { SymbolInspektion, SymbolOelwechsel } from "../symbole"
import { Typenschild, schildErkennen } from "./Typenschild"
@@ -87,12 +87,32 @@ export function Uebersicht({ geheZu }: { geheZu: (name: SeitenName, id?: string)
.slice()
.sort((a, b) => new Date(b.ts).getTime() - new Date(a.ts).getTime())[0]
- const sicherheitsstatus =
- fahrzeug.gesichert === true ? "ok" : fahrzeug.gesichert === false ? "bad" : "warn"
- // Wortlaut deckungsgleich mit vHome() im Panel (g === null ? "Status unbekannt" :
- // g ? "Sicher abgestellt" : "Nicht sicher abgestellt").
- const sicherheitstext =
- fahrzeug.gesichert === true
+ /* Fährt der Wagen, kann er nicht gleichzeitig „sicher abgestellt" sein —
+ abgestellt und unterwegs schließen einander aus (Vorgabe des Eigentümers,
+ 05.09.2026: „es kann nicht sein dass das fahrzeug sicher abgestellt ist und
+ zeitgleich fährt").
+
+ Die beiden Aussagen kommen aus verschiedenen Quellen: Tür-, Fenster- und
+ Schlossmeldungen liefert der EU Data Act mit spürbarer Verzögerung, die
+ Zündung meldet der Dongle in Sekunden. Die schnellere Quelle hat hier
+ Vorrang — nicht weil die andere falsch wäre (verriegelt ist der Wagen
+ während der Fahrt tatsächlich), sondern weil das WORT „abgestellt" dann
+ nicht stimmt.
+
+ 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. */
+ const faehrt = standortZustand(fahrzeug).faehrt
+ const sicherheitsstatus = faehrt
+ ? "ok"
+ : fahrzeug.gesichert === true
+ ? "ok"
+ : fahrzeug.gesichert === false
+ ? "bad"
+ : "warn"
+ const sicherheitstext = faehrt
+ ? "Zündung an"
+ : fahrzeug.gesichert === true
? "Sicher abgestellt"
: fahrzeug.gesichert === false
? "Nicht sicher abgestellt"
diff --git a/companion-app/src/stile/screens.css b/companion-app/src/stile/screens.css
index 6503f80..44c20a4 100644
--- a/companion-app/src/stile/screens.css
+++ b/companion-app/src/stile/screens.css
@@ -1700,6 +1700,16 @@ button.dm-listenzeile {
/* Die Ueberschrift eines Abschnitts ist kein direktes Kind der Kachel, die
Regel .ads-tile > .ads-eyebrow:first-child greift hier also nicht. */
+/* Der Strich zwischen zwei Abschnitten und die erste Zeile darunter standen
+ 28px auseinander: 16px padding-top der Regel oben PLUS die 12px margin-top
+ der Werteliste - die kollabieren wegen des padding nicht miteinander. Vom
+ Eigentümer bemerkt (05.09.2026: „abstand zwischen app und version und dem
+ darüberliegendem strich ist zu groß"). Jetzt zählt nur noch das padding,
+ in beiden Abschnitten gleich. */
+.dm-kachelabschnitt > :first-child {
+ margin-top: 0;
+}
+
.dm-kachelabschnitt > .ads-eyebrow:first-child {
display: block;
margin-bottom: 14px;
@@ -2363,3 +2373,13 @@ select.dm-auswahl {
input[type="range"] {
min-height: 44px;
}
+
+/* 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;
+}
diff --git a/custom_components/audi_dashboard/flespi.py b/custom_components/audi_dashboard/flespi.py
index 2da73db..73a3a8b 100644
--- a/custom_components/audi_dashboard/flespi.py
+++ b/custom_components/audi_dashboard/flespi.py
@@ -678,4 +678,30 @@ async def jetzt_lesen(k: Koordinator) -> None:
await k.flespi_stand_setzen(stand)
# Ein frischer Stand kann eine Abweichung erst sichtbar machen - dann gehört
# sie gleich behoben, statt bis zum nächsten Speichern zu warten.
- await wunsch_uebernehmen(k)
+ #
+ # ABER nur, wenn nach dem Leeren überhaupt schon ein Gerätewert
+ # zurückgekommen ist. Schläft der Dongle, ist der Wert nicht abweichend,
+ # sondern schlicht unbekannt - ein Schreibversuch scheitert dann am Schutz
+ # in schlaf_timeout_schreiben() und ersetzte den eben gelesenen Stand durch
+ # eine Fehlermeldung. Am 05.09.2026 genau so passiert: nach "Jetzt lesen"
+ # stand in der Kachel nur noch "Der Schlafmodus des Geräts ist gerade
+ # unbekannt", statt der Werte.
+ if _schlafwert_bekannt(stand):
+ await wunsch_uebernehmen(k)
+ else:
+ _LOGGER.debug(
+ "Nach dem Leeren liegt noch kein Gerätewert vor - kein Abgleich,"
+ " bis der Dongle sich meldet."
+ )
+
+
+def _schlafwert_bekannt(stand: dict) -> bool:
+ """Ob der Anzeigestand einen Schlaf-Timeout vom Gerät kennt.
+
+ Ein ausstehender Wert (`offen`) zählt mit: er ist unterwegs, und das
+ dazugehörige `mode`-Objekt liegt dann in flespi vor."""
+ for zeile in stand.get("werte", []):
+ if zeile.get("schluessel") != SCHLAF_SCHLUESSEL:
+ continue
+ return zeile.get("geraet") is not None or zeile.get("offen") is not None
+ return False
diff --git a/custom_components/audi_dashboard/frontend/app/bundle.json b/custom_components/audi_dashboard/frontend/app/bundle.json
index 8486c88..5b20db9 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.34","sha256":"0de4c2af3534ef74c4bda98de122419e2f4d4c2741a175e73722d757344a3f6b","bytes":324629,"gebaut":"2026-09-05T14:40:28Z"}
\ No newline at end of file
+{"version":"2026.9.5.35","sha256":"8873fddf9a976ff3317fb16cf4ed708ac19ef76dbf8faf4ff29189e2a5f83a75","bytes":324134,"gebaut":"2026-09-05T15:01:50Z"}
\ 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 e546fcf..1b52a1d 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 d77a870..b0df8e1 100644
--- a/custom_components/audi_dashboard/frontend/audi-dashboard-app.js
+++ b/custom_components/audi_dashboard/frontend/audi-dashboard-app.js
@@ -2300,8 +2300,26 @@ function standAlterTicken() {
function vHome() {
const g = CAR.gesichert;
- const statusText = g === null ? "Status unbekannt" : g ? "Sicher abgestellt" : "Nicht sicher abgestellt";
- const statusDot = g === null ? "warn" : g ? "" : "bad";
+ /* Faehrt der Wagen, kann er nicht gleichzeitig "sicher abgestellt" sein -
+ abgestellt und unterwegs schliessen einander aus (Vorgabe des
+ Eigentuemers, 05.09.2026: "es kann nicht sein dass das fahrzeug sicher
+ abgestellt ist und zeitgleich faehrt").
+
+ Die beiden Aussagen kommen aus verschiedenen Quellen: Tuer-, Fenster- und
+ Schlossmeldungen liefert der EU Data Act mit spuerbarer Verzoegerung, die
+ Zuendung meldet der Dongle in Sekunden. Die schnellere Quelle hat hier
+ Vorrang - nicht weil die andere falsch waere (verriegelt ist der Wagen
+ waehrend der Fahrt tatsaechlich), sondern weil das WORT "abgestellt" dann
+ nicht stimmt.
+
+ Wortlaut wie im Standortmenue: "Zuendung an", nicht "faehrt" - einen
+ Bewegungssensor gibt es nicht, die Zuendung steht auch im Stand mit
+ laufendem Motor auf an. */
+ const faehrt = standortZustand().faehrt;
+ const statusText = faehrt
+ ? "Zündung an"
+ : g === null ? "Status unbekannt" : g ? "Sicher abgestellt" : "Nicht sicher abgestellt";
+ const statusDot = faehrt ? "" : g === null ? "warn" : g ? "" : "bad";
const pct = CAR.tankPct;
const t = naechsterTermin();
/* C2/C5/D1: Reihenfolge der myAudi-App - randloses Fahrzeugbild, Name und
@@ -2424,7 +2442,14 @@ function vSicherheit() {
const tuerenKlappen = sicherheitsGruppe("tueren_klappen");
const fensterDach = sicherheitsGruppe("fenster_dach");
const licht = sicherheitsGruppe("licht");
- const sammelText = g === null ? "Zustand nicht vollständig bekannt" : g ? "Fahrzeug ist sicher abgestellt" : "Bitte prüfen";
+ /* Dieselbe Regel wie in vHome(): unterwegs ist der Wagen nicht abgestellt.
+ Die vier Sammelzeilen darunter bleiben stehen und zeigen weiter, was die
+ Tuer-, Fenster- und Schlosssensoren melden - nur die Ueberschrift darf
+ nicht "abgestellt" behaupten, waehrend die Zuendung an ist. */
+ const faehrt = standortZustand().faehrt;
+ const sammelText = faehrt
+ ? "Zündung an - Fahrzeug in Betrieb"
+ : g === null ? "Zustand nicht vollständig bekannt" : g ? "Fahrzeug ist sicher abgestellt" : "Bitte prüfen";
const zeile = (label, ok, labelBad, labelWarn, route) => {
const text = ok === null ? labelWarn : ok ? label : labelBad;
const klickbar = !!route;
@@ -2439,7 +2464,7 @@ function vSicherheit() {
return `
@@ -3559,6 +3584,36 @@ function dongleStand(w) {
return tage >= 1 ? `bestätigt ${wann} (${tage} T. alt)` : `bestätigt ${wann}`;
}
+/* Der EINE Knopf der Update-Kachel. Er traegt in jedem Zustand den naechsten
+ faelligen Schritt - suchen, installieren, Neustart, Neuladen - statt dass
+ ueber dem Suchknopf noch ein zweiter Knopf im Abschnitt steht (Vorgabe des
+ Eigentuemers, 05.09.2026: "warum nicht den update suchen button dafuer
+ verwenden und nur die optik und schrift zur installation anpassen?").
+
+ Die Reihenfolge ist eine Rangfolge, keine Auswahl: liegt ein Neustart an,
+ ist das der naechste Schritt, egal was sonst noch bereitliegt. Ein
+ gleichzeitiges Integrations- UND App-Update gibt es dabei praktisch nicht -
+ das Buendel wird erst angeboten, wenn es zur laufenden Serverfassung passt
+ (buendelPasst), also nach der Integration. Das Panel kennt den App-Teil
+ ohnehin nicht: es laedt seine Dateien bei jedem Aufruf frisch vom Server. */
+function updateKnopf() {
+ const u = INTEGRATION_UPDATE;
+ const laeuft = INTEGRATION_UPDATE_LAEUFT;
+ const laufend = (text) => ``;
+ if (laeuft === "installieren") return laufend("Installiere …");
+ if (laeuft === "neustart") return laufend("Home Assistant startet neu …");
+ if (laeuft === "pruefen") return laufend("Prüfe …");
+ const knopf = (text, aktion, primaer) =>
+ ``;
+ if (u && u.installiert && u.neustart_noetig === false && String(CSS_VERSION) !== String(APP_VERSION))
+ return knopf("Seite neu laden", "neuladen", true);
+ if (u && u.installiert && u.neustart_noetig !== false)
+ return knopf("Installation abschließen und neu starten", "neustart", true);
+ if (u && u.verfuegbar) return knopf("Update installieren", "installieren", true);
+ return knopf("Auf Update prüfen", "pruefen", false);
+}
function vEinst() {
return `
Fahrzeug einrichten
@@ -3761,12 +3816,12 @@ function vEinst() {
if (u.neustart_noetig === false) {
return `
Version ${esc(u.version)} installiert - nur Oberflächendateien, kein Neustart nötig.
- `;
+`;
}
return `
Version ${esc(u.version)} installiert - die neue Fassung wird erst nach einem Neustart
geladen.
- `;
+`;
}
if (u && u.verfuegbar) {
/* Zeitstempel und ein zweiter Pruefknopf gehoeren hierher, nicht nur in
@@ -3776,19 +3831,22 @@ function vEinst() {
sie aufzufrischen, solange ueberhaupt ein Update angeboten wurde. */
return `
- `;
+`;
}
return u ? `aktuell` : "";
})()}
${INTEGRATION_UPDATE && INTEGRATION_UPDATE.fehler && !INTEGRATION_UPDATE_LAEUFT
? `${esc(INTEGRATION_UPDATE.fehler)}`
: ""}
-
-
+
+ ${updateKnopf()}
${INTEGRATION_UPDATE && INTEGRATION_UPDATE.geprueft_am
diff --git a/custom_components/audi_dashboard/manifest.json b/custom_components/audi_dashboard/manifest.json
index 166e98c..610234d 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.34",
+ "version": "2026.9.5.35",
"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/tankerkennung.py b/custom_components/audi_dashboard/tankerkennung.py
index ba48791..d11c2b0 100644
--- a/custom_components/audi_dashboard/tankerkennung.py
+++ b/custom_components/audi_dashboard/tankerkennung.py
@@ -116,11 +116,14 @@ async def fuellstand_geaendert(
# (siehe tankvolumen_geaendert) - genauer, weil ohne den Umweg über das im
# Fahrzeugprofil hinterlegte Tankvolumen. Beide gleichzeitig auswerten
# würde denselben Tankvorgang zweimal anlegen.
+ # Reihenfolge wie bei tankvolumen_geaendert() - erst der Tiefststand, dann
+ # das Anlegen, sonst legen zwei dicht aufeinanderfolgende Wechsel denselben
+ # Tankvorgang zweimal an.
+ await k.tiefststand_setzen(aktuell)
if not k.zuordnung.werte.TANK_LITER_SENSOR:
await _automatisch_anlegen(
k, f"Füllstandsanstieg {round(anstieg, 1)} Prozentpunkte", ereigniszeit=ereigniszeit
)
- await k.tiefststand_setzen(aktuell)
async def tankvolumen_geaendert(
@@ -144,13 +147,22 @@ async def tankvolumen_geaendert(
if anstieg < LITER_SCHWELLE:
return
+ # Der Tiefststand wird VOR dem Anlegen gesetzt, nicht danach.
+ # _automatisch_anlegen() wartet auf Geraetezeit und Ablage; in dieser Zeit
+ # kommt der naechste Zustandswechsel dran und liest oben noch den ALTEN
+ # Tiefststand - beide legen denselben Tankvorgang an. Genau so entstanden
+ # am 04.09.2026 um 21:37:04 zwei Eintraege ueber 29,8 l und 29,7 l, als der
+ # Dongle einen gepufferten Schwung Datensaetze auf einmal ablieferte und
+ # can_fuel_volume in derselben Sekunde 36,8 und 36,7 meldete.
+ # tiefststand_liter_setzen() belegt das Feld als erste Anweisung, also
+ # bevor es selbst wartet - danach sieht der zweite Wechsel den neuen Wert.
+ await k.tiefststand_liter_setzen(aktuell)
await _automatisch_anlegen(
k,
f"Tankvolumenanstieg {round(anstieg, 1)} l",
liter_schaetzung=anstieg,
ereigniszeit=ereigniszeit,
)
- await k.tiefststand_liter_setzen(aktuell)
async def distanz_seit_tankung(