Batteriespannung: Diagramm-Y-Achse fest 10-15V, Plausibilitätsgrenze auf 10V angehoben

Die Y-Achse beider Batteriespannungs-Diagramme (Panel und companion-app) war bisher
aus den sichtbaren Punkten berechnet - jetzt fest 10-15V, auf Nutzerwunsch (zunächst
8-15V, dann auf 10-15V korrigiert). SPANNUNG_MIN_V (batterie.py) auf denselben Wert
angehoben, damit die Plausibilitätsgrenze zur Achse passt - historienimport.py
übernimmt den Wert automatisch, da er von dort importiert statt dupliziert wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 18:06:12 +02:00
parent f337820fc8
commit b8e560e75b
7 changed files with 46 additions and 24 deletions
+25
View File
@@ -3209,6 +3209,31 @@ vehicle photos, PWA service worker in this test environment), nothing new. compa
clean, full suite green at 146/146, `npm run build` and `npm run ota` both succeeded (bundle rebuilt at clean, full suite green at 146/146, `npm run build` and `npm run ota` both succeeded (bundle rebuilt at
`2026.8.27.1`). Manifest bumped `2026.8.25.9``2026.8.27.1`. `2026.8.27.1`). Manifest bumped `2026.8.25.9``2026.8.27.1`.
**Same-day follow-up (2026.8.27.2): two smaller items found/requested while verifying the above.**
(1) A stale `min: 0.0` day-entry sat in `batteriespannung.jsonl`, recorded at 09:46 that day - **before**
the 15:12 restart that deployed the 8V plausibility floor (`SPANNUNG_MIN_V`, section T). The floor only
rejects *new* sub-8V readings going forward; it doesn't retroactively purge what was already stored, so the
0V value kept showing until removed. Deleted via the app's own `batterieverlauf_loeschen` service (the same
one the measurement list's swipe-to-delete uses) - not a code fix, a one-off data cleanup; the real instance
would need the same swipe-delete if the same stale-reading symptom ever shows up there.
(2) **Owner request: "Diagram Axis for Voltage: 8V to 15V"** (both battery voltage diagrams - the panel's
zoomable `#bvChart` and companion-app's `Verlaufsdiagramm` in `Batterie.tsx`, neither of which had a fixed
axis before, both computed min/max from the visible data ± padding). Both now draw a fixed Y-axis instead of
the data-driven range they used before - simpler, and the panel's `bvYDomain` no longer needs computing at
all when there's data, it's just a fixed pair of endpoints. Two immediate owner follow-ups the same session
adjusted the endpoints twice more: **8-15V → 10-15V** (`2026.8.27.3`), then **the `SPANNUNG_MIN_V`
plausibility floor itself raised 8.0 → 10.0 in `batterie.py`** to match (`2026.8.27.4`) - `historienimport.py`
imports the constant rather than duplicating it, so it picked up the new floor with no separate edit needed,
consistent with the live/import parity rule elsewhere in this file. The floor's module docstring was softened
from "physikalisch nicht plausibel" (no longer strictly true at 10V, a real if unlikely reading for a failing
battery) to "gilt als unplausibel" (an owner-set threshold, not a hard physical limit). Verified live at each
step: axis labels read `10,0 / 11,7 / 13,3 / 15,0` on the panel after the last change; companion-app confirmed
via `tsc --noEmit` each time (no dedicated visual check - same fixed-endpoint math, no zoom/pan feature to
interact with there); `batterie.py` re-`py_compile`d clean after the floor change. Manifest bumped
`2026.8.27.1``.2``.3``.4`, `npm run ota` rerun for the two frontend-touching steps, `audi_ha_test`
restart confirmed clean via log at every step (single `audi_dashboard` loader warning each time, no
duplicate-domain regression).
--- ---
## Working conventions (observed — keep them) ## Working conventions (observed — keep them)
+5 -4
View File
@@ -154,10 +154,11 @@ function Verlaufsdiagramm({ werte }: { werte: Tageswert[] }) {
const hoehe = 120 const hoehe = 120
const rand = 4 const rand = 4
const alleWerte = werte.flatMap((t) => [t.min, t.max].filter((v): v is number => v != null)) // Feste Achse 10-15V (Nutzerwunsch): deckt den relevanten Bereich ab
const kleinster = Math.min(...alleWerte) - 0.1 // (12V-Bleibatterie, Ladespannung des Alternators mit Reserve).
const groesster = Math.max(...alleWerte) + 0.1 const kleinster = 10
const spanne = Math.max(0.2, groesster - kleinster) const groesster = 15
const spanne = groesster - kleinster
const x = (i: number) => const x = (i: number) =>
rand + (i / Math.max(1, werte.length - 1)) * (breite - 2 * rand) rand + (i / Math.max(1, werte.length - 1)) * (breite - 2 * rand)
+7 -7
View File
@@ -26,10 +26,9 @@ erst beim Anzeigen angewendet: Tage, an denen selbst der Minimalwert über der
Grenze liegt (Fahrzeug nie im Ruhezustand beobachtet, z. B. bei einer sehr Grenze liegt (Fahrzeug nie im Ruhezustand beobachtet, z. B. bei einer sehr
langen Fahrt), tauchen dort nicht in der Statistik auf. langen Fahrt), tauchen dort nicht in der Statistik auf.
Eine Ausnahme von "roh aufzeichnen" gibt es: Werte unter SPANNUNG_MIN_V sind Eine Ausnahme von "roh aufzeichnen" gibt es: Werte unter SPANNUNG_MIN_V gelten
für eine 12V-Bleibatterie physikalisch nicht plausibel (selbst tiefentladen als unplausibel für eine echte Messung an dieser 12V-Bleibatterie und deuten
liegt die Ruhespannung deutlich darüber) und deuten auf einen Sensor-/ eher auf einen Sensor-/Verbindungsfehler hin - sie werden gar nicht erst
Verbindungsfehler statt auf eine echte Messung hin - sie werden gar nicht erst
aufgezeichnet, damit ein einzelner Ausreißer nicht als Tagesminimum in der aufgezeichnet, damit ein einzelner Ausreißer nicht als Tagesminimum in der
Liste und im Diagramm landet. Liste und im Diagramm landet.
@@ -56,9 +55,10 @@ if TYPE_CHECKING:
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
# Physikalisch plausible Untergrenze für eine 12V-Bleibatterie - darunter ist # Plausible Untergrenze für eine 12V-Bleibatterie (vom Nutzer festgelegt) -
# es ein Sensor-/Verbindungsfehler, keine echte Messung (siehe Moduldocstring). # darunter ist es ein Sensor-/Verbindungsfehler, keine echte Messung (siehe
SPANNUNG_MIN_V = 8.0 # Moduldocstring).
SPANNUNG_MIN_V = 10.0
async def pruefen(k: Koordinator) -> None: async def pruefen(k: Koordinator) -> None:
@@ -1 +1 @@
{"version":"2026.8.27.1","sha256":"d7cd168032a93ed8430e3a86ee583c635004fc3518eecf0d1e69abd78741ebc4","bytes":235552,"gebaut":"2026-08-27T15:13:25Z"} {"version":"2026.8.27.3","sha256":"b99d93aae2ff58e58107e04f25edfb590e159f55414c11ba4645e82a36f09108","bytes":235508,"gebaut":"2026-08-27T16:01:36Z"}
@@ -1781,17 +1781,13 @@ function vBatterieverlauf() {
const genug = bvPunkte.length >= 2; const genug = bvPunkte.length >= 2;
bvVollDomain = genug ? [bvPunkte[0].t, bvPunkte[bvPunkte.length - 1].t] : null; bvVollDomain = genug ? [bvPunkte[0].t, bvPunkte[bvPunkte.length - 1].t] : null;
bvDomain = genug ? [...bvVollDomain] : null; bvDomain = genug ? [...bvVollDomain] : null;
// Y-Achse einmalig aus allen Punkten festlegen, nicht bei jedem Zoom/Pan // Y-Achse fest auf 10-15V (Nutzerwunsch) statt aus den Punkten berechnet -
// neu aus den gerade sichtbaren - sonst "streckt" sich die Achse bei jeder // deckt den relevanten Bereich ab (12V-Bleibatterie, Ladespannung des
// Geste neu auf den jeweils sichtbaren Min/Max-Ausschnitt. // Alternators mit Reserve), ohne die Plausibilitätsgrenze SPANNUNG_MIN_V=8V
if (genug) { // (batterie.py) selbst als Achsenskala zu übernehmen. Bleibt dadurch auch
let yMin = Math.min(...bvPunkte.map((p) => p.v)), yMax = Math.max(...bvPunkte.map((p) => p.v)); // bei jedem Zoom/Pan unverändert, nicht nur "einmalig aus allen Punkten"
if (yMax - yMin < 0.4) { const mitte = (yMax + yMin) / 2; yMin = mitte - 0.2; yMax = mitte + 0.2; } // wie zuvor.
const pad = (yMax - yMin) * 0.15; bvYDomain = genug ? [10, 15] : null;
bvYDomain = [yMin - pad, yMax + pad];
} else {
bvYDomain = null;
}
const stufen = bvFarbstufen(); const stufen = bvFarbstufen();
const letzter = bvPunkte.length ? bvPunkte[bvPunkte.length - 1] : null; const letzter = bvPunkte.length ? bvPunkte[bvPunkte.length - 1] : null;
@@ -1,7 +1,7 @@
{ {
"domain": "audi_dashboard", "domain": "audi_dashboard",
"name": "Audi Dashboard", "name": "Audi Dashboard",
"version": "2026.8.27.1", "version": "2026.8.27.4",
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md", "documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues", "issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
"codeowners": ["@paul"], "codeowners": ["@paul"],