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
+6 -2
View File
@@ -35,6 +35,7 @@ from typing import TYPE_CHECKING
from . import shell_beleg_parser
from .tankerkennung import leerer_tankvorgang
from .veroeffentlichung import zustand_oder_none
from .verlauf import zeit_normalisiert
if TYPE_CHECKING:
from .koordinator import Koordinator
@@ -199,9 +200,11 @@ async def tankvorgang_manuell(k: Koordinator, daten: dict) -> None:
# deshalb immer Vorrang vor der Berechnung.
distanz = await k.ablage.distanz_seit_letzter_tankung(odometer_km)
ts_roh = daten.get("ts")
ts = zeit_normalisiert(ts_roh) if ts_roh else datetime.datetime.now(datetime.UTC)
receipt_key = daten.get("receipt_key")
tankvorgang = leerer_tankvorgang(
daten.get("ts") or datetime.datetime.now(datetime.UTC).isoformat(),
ts.isoformat(),
"beleg" if receipt_key else "manual",
)
tankvorgang.update({
@@ -241,8 +244,9 @@ async def tankvorgang_aktualisieren(k: Koordinator, daten: dict) -> None:
liter = daten.get("liter")
kosten = daten.get("kosten")
ts_normalisiert = zeit_normalisiert(daten.get("ts"))
aenderungen = {
"ts": daten.get("ts"),
"ts": ts_normalisiert.isoformat() if ts_normalisiert else daten.get("ts"),
"liters": liter,
"fuel_total_eur": kosten,
"price_per_l": preis_je_liter(kosten, liter),