Batteriespannung-Fallback: zeigt letzte Ruhespannungsmessung ueber Neustarts hinweg

Der RAM-only Fallback fuer die Zustand-Kachel wurde bei jedem Neustart
geleert und zeigte "unbekannt", solange seit dem Neustart keine echte
Live-Messung eintraf (Dongle bei ausgeschaltetem Fahrzeug erwartungsgemaess
immer offline). spannung_cache_vorladen() laedt ihn jetzt beim Start aus
der gespeicherten Historie vor, begrenzt auf den vereinbarten Bereich
10,0-13,0 V (SPANNUNG_MIN_V bis AGM_RUHE_MAX_V) - eine Generatorspannung
(z.B. 15,4 V) soll dort nie als Batteriespannung erscheinen.

Version 2026.8.27.21, im Testcontainer verifiziert (12,149 V statt
"unbekannt", trotz Dongle weiterhin 0 V live).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-28 00:23:16 +02:00
parent 90fff7b305
commit f4222b715f
5 changed files with 126 additions and 11 deletions
+55 -3
View File
@@ -3853,9 +3853,61 @@ Verified: all five touched backend files (`verlauf.py`, `historienimport.py`, `f
changed), `npm run ota` rerun (companion-app source changed, `Batterie.tsx`/`Statistik.tsx`), `audi_ha_test`
restarted and confirmed clean via log (`Audi Dashboard 2026.8.27.19 eingerichtet`, no traceback; the only
`ReferenceError: bvRuhePunkte` lines in the post-restart log predate the setup-complete line and come from a
stale browser tab's cached pre-restart script, not a new regression). **Not yet committed/pushed** - per
this file's own binding lesson from earlier the same day (section W), that should happen before any
self-update/install run is suggested or allowed; ask the owner before running one.
stale browser tab's cached pre-restart script, not a new regression). Committed and pushed the same day
(`90fff7b`), per this file's own binding lesson from section W.
## Z. Battery-voltage fallback didn't survive a restart - now seeded from disk (2026.8.27.20)
Owner report right after the section Y fixes: "batteriespannung is still unbekannt!" - live investigation
(browser session against `audi_ha_test` at `:18123`, confirmed reachable per section W's note) found this
was NOT a regression from section Y: the FMM003 dongle was genuinely reporting `external_power_voltage: 0`
live (confirmed via `hass.states` in the browser console), and `_letzte_gueltige_spannung`
(`veroeffentlichung.py`, the RAM-only "last known good voltage" fallback added in section W) had been wiped
by the container restarts done while verifying section Y's fixes - it had no valid reading to fall back to
since the last restart, so "unbekannt" was the technically-correct result of the existing design.
Owner's response: **"wait. I want to see the last measured voltage!"**, then, pre-empting a staleness
concern before it was raised: **"no lifedate! The dongle will be always offline when car is off"** - i.e.
the RAM-only, resets-on-restart design (deliberately chosen in section W to avoid "resurrecting a possibly
very old value") no longer matches what's wanted: the dongle being offline is the *expected* steady state
whenever the car is parked, so the fallback needs to survive restarts, and its age must never be a reason to
hide it - an old real reading is still better than "unbekannt".
Fixed by seeding the RAM cache from the already-persisted `batteriespannung.jsonl` history once, at startup,
instead of changing the cache to a Store (would duplicate data already saved elsewhere for a different
purpose - the day-level battery history). New `spannung_cache_vorladen(verlauf)` in `veroeffentlichung.py`,
called once from `Koordinator.starten()` (`koordinator.py`) right before the first `alles_veroeffentlichen()`
so even the very first publish after a restart already carries the seeded value instead of a transient
"unbekannt". `fahrzeugstatus()` itself (the per-tick publish function) is untouched - it already reads
`_letzte_gueltige_spannung["wert"]` as its fallback, this just means that value is no longer empty
immediately after a restart.
**First version was wrong - owner caught it: "you got me wrong". "last measured voltage" pulled from the
raw `min`/`max` of the last day entry regardless of value - which on this container's real data meant
15,4 V, the day's *max*, i.e. generator/charging voltage (`batterie.py`'s own docstring documents that
min/max are stored raw, unfiltered by any resting-voltage border - see section N/T history).** A 15,4 V
"Batteriespannung" reading is misleading - that's not the battery's own state. Owner: **"last measured
voltage - but within the agreed borders! confirm me the border!"** - confirmed and agreed: **10,0 V
(`SPANNUNG_MIN_V`, the existing plausibility floor) to 13,0 V (`AGM_RUHE_MAX_V`, the existing
resting-vs-generator ceiling)** - the same two borders already governing the live reading itself
(`fahrzeugstatus()`) and the frontend's diagram/trend filtering (section X), just not previously shared
into the backend as a named constant. Added `AGM_RUHE_MAX_V = 13.0` to `batterie.py` (backend's own copy,
next to `SPANNUNG_MIN_V` - `veroeffentlichung.py` imports both locally inside the function to avoid the
same circular-import risk `SPANNUNG_MIN_V` already routes around). `spannung_cache_vorladen()` rewritten to
scan the ENTIRE stored history (not just the last day), collect every `min`/`max` reading that falls inside
`[SPANNUNG_MIN_V, AGM_RUHE_MAX_V]`, and seed the cache with the chronologically most recent one - so a day
where the car was never at rest (both min and max above 13,0 V) is correctly skipped in favor of the most
recent day that does have a genuine resting-range reading.
Verified: `py_compile` clean on all touched files, manifest bumped `2026.8.27.20``2026.8.27.21`,
`audi_ha_test` restarted twice and confirmed clean via log both times (`... eingerichtet`, no traceback) with
the dongle still reporting `0 V` live throughout. First (unfiltered) version showed **15,4 V** live - correct
per that version's own logic, wrong per the actual requirement, caught by the owner before being accepted.
Corrected version confirmed live via the published entity's own `daten.batteriespannung` attribute:
**12,149 V** - the most recent stored reading that actually falls within 10,0-13,0 V (2026-08-27's daily
minimum, `12.149` at `09:44:00Z`), correctly skipping that same day's `15.439` maximum and every one of the
three preceding fully-out-of-border days (`2026-08-23`/`24`/`25`, both min and max pinned at `13.988`, always
excluded).
---