Vollaudit: sechs echte Fehler in Backend, Panel und companion-app behoben

- companion-app Batterie.tsx: Generatorspannung zeigte sich faelschlich als
  Ruhespannung/verzerrte den SOH-Trend, Panel-Filter (AGM_RUHE_MAX_V) fehlte
- Manuell angelegte Fahrten/Tankvorgaenge trugen naive Zeitstempel und wurden
  von der Import-Dublettenpruefung stillschweigend uebersprungen; neue
  gemeinsame zeit_normalisiert() in verlauf.py schliesst die Luecke
- Batteriespannungsverlauf fehlte im Backup (sicherung.py)
- Tankvorgangs-Import verlor stillschweigend aeltere Tankvorgaenge vor Beginn
  der Litersensor-Historie; laeuft jetzt zweigleisig (Prozent + Liter)
- Panel-Statistikseite behauptete faelschlich, der Verbrauch je Fahrt komme
  vom Fahrzeug (OBD) - ist eine Naeherung aus dem Tankfuellstand
- companion-app Statistik.tsx: Arbeitsweg-Segment war noch rot statt neutral

Version 2026.8.27.19, OTA-Buendel neu gebaut, im Testcontainer verifiziert.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-28 00:05:58 +02:00
co-authored by Claude Sonnet 5
parent 8ba3519090
commit 90fff7b305
12 changed files with 223 additions and 69 deletions
@@ -27,7 +27,7 @@ from typing import TYPE_CHECKING
from . import screening
from .ablage import neue_id
from .veroeffentlichung import zustand_oder_none
from .verlauf import verlauf_lesen
from .verlauf import verlauf_lesen, zeit_normalisiert
if TYPE_CHECKING:
from .koordinator import Koordinator
@@ -228,8 +228,8 @@ async def manuell_anlegen(k: Koordinator, daten: dict) -> None:
automatischen Zündungs-Erkennung. Alles außer Start- und Endzeitpunkt ist
optional und bleibt leer, wenn es das Screening später selbst ergänzen
soll."""
start_ts = datetime.datetime.fromisoformat(daten["ts_start"])
ende_ts = datetime.datetime.fromisoformat(daten["ts_end"])
start_ts = zeit_normalisiert(daten["ts_start"])
ende_ts = zeit_normalisiert(daten["ts_end"])
hand = _handfelder(
daten.get("start_ort"), daten.get("ziel_ort"),
daten.get("odo_start"), daten.get("odo_end"), daten.get("distanz"),
@@ -264,8 +264,8 @@ async def aktualisieren(k: Koordinator, daten: dict) -> None:
if daten.get("art"):
aenderungen["art"] = daten["art"]
if daten.get("ts_start") and daten.get("ts_end"):
start_ts = datetime.datetime.fromisoformat(daten["ts_start"])
ende_ts = datetime.datetime.fromisoformat(daten["ts_end"])
start_ts = zeit_normalisiert(daten["ts_start"])
ende_ts = zeit_normalisiert(daten["ts_end"])
aenderungen["ts_start"] = start_ts.isoformat()
aenderungen["ts_end"] = ende_ts.isoformat()
aenderungen["duration_s"] = int((ende_ts - start_ts).total_seconds())