Fahrten, Statistik, Trip-Timer (2026.8.31.3)
Der 15-Minuten-Timer war doppelt: der FMM003 wartet laut Konfiguration (Trip \ Odometer, Ignition OFF Timeout) selbst 900 s, die App noch einmal 15 Minuten. Zusammen eine halbe Stunde. Die Pausenregel ist damit entfallen - in der Live-Erkennung, im Historienimport und in beiden Oberflaechen. Der Schwellwert "ab wann ist es ein Parkplatz" hing an derselben Einstellung, hat damit aber nichts zu tun und steht jetzt als eigene Zahl. Hoechst- und Durchschnittsgeschwindigkeit je Fahrt. Der Durchschnitt folgt aus Strecke und Dauer, vmax aus der neuen Rolle GESCHWINDIGKEIT_SENSOR - laut Konfiguration liest das Geraet die Geschwindigkeit vom OBD/CAN. Es ist der groesste gemeldete Wert, nicht die tatsaechliche Spitze: alle zehn Sekunden ein Datensatz. So ist es auch beschriftet. Der Langzeitverbrauch war um einen ganzen Tankinhalt zu hoch. Gemessen wird die Strecke ZWISCHEN erstem und letztem Tankstop; verbraucht wurde darauf, was ab dem ZWEITEN hineinkam - der erste fuellte die Strecke davor. Bei 13 Tankvorgaengen rund 8 Prozent, im Testfall 16,7 statt 8,3 l/100 km. Der Test hatte die falsche Rechnung festgeschrieben und ist mitkorrigiert. Eine negative Strecke (falscher Kilometerstand an einem Tankvorgang) gilt jetzt als unplausibel statt als Null ohne Erklaerung. Verbrauch je Fahrt bekommt Grenzen: am Sensor nachgemessen loest can_fuel_volume 0,1 l auf, ein Schritt entspricht also 10/Strecke l/100 km Fehler. Unter 3 km sagt die Differenz nichts mehr, ueber 60 l/100 km ist es kein Verbrauch. Statistik: zusaetzlich "Absolut", und die Einheit steht jetzt in eckigen Klammern an der Rubrik statt vier Mal am Zeitraum. Fuenf Spalten passen auf einem Telefon nicht nebeneinander, das Raster bricht um. Radfoto in Reifen war ein reines <Bild> - Ersetzen und Loeschen von dort aus gar nicht erreichbar. Jetzt BildMitMenue wie im Panel. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -25,6 +25,7 @@ from typing import TYPE_CHECKING
|
||||
from .verlauf import (
|
||||
UNPLAUSIBLE_KMH,
|
||||
durchschnitt_kmh,
|
||||
hoechstwert_im_fenster,
|
||||
naechster_wert,
|
||||
route_aus_verlauf,
|
||||
verbrauch_aus_literstaenden,
|
||||
@@ -109,6 +110,26 @@ async def durchfuehren(k: Koordinator) -> None:
|
||||
for fahrt in ohne_position:
|
||||
await _position_screenen(k, lat_sensor, lon_sensor, fahrt)
|
||||
|
||||
# Durchschnitt braucht keinen Sensor - er folgt aus Strecke und Dauer,
|
||||
# die beide schon dastehen. Deshalb vor dem Geschwindigkeitssensor und
|
||||
# unabhaengig davon, ob einer zugeordnet ist.
|
||||
for fahrt in fahrten:
|
||||
if fahrt.get("avg_speed_kmh") is not None:
|
||||
continue
|
||||
schnitt = durchschnitt_kmh(fahrt.get("distance_km"), fahrt.get("duration_s"))
|
||||
if schnitt is None:
|
||||
continue
|
||||
await k.ablage.fahrt_aktualisieren(
|
||||
fahrt["trip_id"], {"avg_speed_kmh": schnitt}
|
||||
)
|
||||
fahrt["avg_speed_kmh"] = schnitt
|
||||
|
||||
tempo_sensor = k.zuordnung.werte.GESCHWINDIGKEIT_SENSOR
|
||||
if tempo_sensor:
|
||||
ohne_vmax = [f for f in fahrten if f.get("vmax_kmh") is None]
|
||||
for fahrt in ohne_vmax:
|
||||
await _vmax_screenen(k, tempo_sensor, fahrt)
|
||||
|
||||
tank_liter_sensor = k.zuordnung.werte.TANK_LITER_SENSOR
|
||||
if tank_liter_sensor:
|
||||
ohne_verbrauch = [
|
||||
@@ -229,6 +250,34 @@ async def _verbrauch_screenen(
|
||||
fahrt["verbrauch_l_100km"] = verbrauch
|
||||
|
||||
|
||||
async def _vmax_screenen(k: Koordinator, tempo_sensor: str, fahrt: dict) -> None:
|
||||
"""Trägt die Höchstgeschwindigkeit der Fahrt nach.
|
||||
|
||||
Anders als beim Kilometerstand wird hier nicht der nächstgelegene Wert
|
||||
gesucht, sondern der größte innerhalb des Fahrtfensters - und ohne
|
||||
Suchfenster drumherum, weil ein Wert von vor oder nach der Fahrt nicht
|
||||
zu ihr gehört.
|
||||
|
||||
Unplausible Werte werden verworfen statt angezeigt: dieselbe Grenze wie
|
||||
beim Durchschnitt (UNPLAUSIBLE_KMH), denn ein Sensorsprung sieht in
|
||||
beiden Fällen gleich aus."""
|
||||
start = _als_zeit(fahrt.get("ts_start"))
|
||||
ende = _als_zeit(fahrt.get("ts_end"))
|
||||
if start is None or ende is None:
|
||||
return
|
||||
|
||||
verlauf = await verlauf_lesen(k.hass, tempo_sensor, start, ende)
|
||||
if not verlauf:
|
||||
return
|
||||
|
||||
vmax = hoechstwert_im_fenster(verlauf, start, ende)
|
||||
if vmax is None or vmax <= 0 or vmax > UNPLAUSIBLE_KMH:
|
||||
return
|
||||
|
||||
await k.ablage.fahrt_aktualisieren(fahrt["trip_id"], {"vmax_kmh": vmax})
|
||||
fahrt["vmax_kmh"] = vmax
|
||||
|
||||
|
||||
async def _lueckenlos_verketten(k: Koordinator) -> None:
|
||||
"""Fahrt-Ende(N) == Fahrt-Start(N+1), solange dazwischen nicht gefahren
|
||||
wurde.
|
||||
|
||||
Reference in New Issue
Block a user