Batteriespannung: 8V-Plausibilitätsgrenze; Fahrten: echte Start-/Zielposition und Streckenlinie
Batteriespannung: Werte unter 8V (Sensor-/Verbindungsfehler, nicht physikalisch
plausibel für eine 12V-Bleibatterie) werden nicht mehr erfasst - live und beim
Import. "Neue Räder anlegen"-Knopf sitzt jetzt auf derselben Zeile wie "Montiert".
Fahrten: start_lat/-lon, end_lat/-lon und route wurden bisher nur beim
rückwirkenden Import befüllt, nie bei live erkannten Fahrten (dem Normalfall) -
Screening trägt sie jetzt aus dem GPS-Verlauf nach, unabhängig vom
Kilometerstand-Status. fakeTrack() (eine erfundene Linie) ist entfernt, die
Karte zeichnet jetzt die echte Route oder eine ehrliche Gerade zwischen den
bekannten Punkten. CARTOs anonyme Kartenkacheln verlangen inzwischen einen
API-Schlüssel ("API key required" auf jeder Karte in beiden Apps) - auf
schlüssellose OpenStreetMap-Kacheln umgestellt. Start/Ziel zeigen jetzt Datum
und Uhrzeit über der Adresse; die fehlerhafte "Status"-Zeile ist entfernt.
Batteriespannungs-Diagramm nutzt auf großen Bildschirmen die volle
Spaltenbreite statt einer festen 400px-Deckelung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ import datetime
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .verlauf import naechster_wert, verlauf_lesen
|
||||
from .verlauf import naechster_wert, route_aus_verlauf, verlauf_lesen
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .koordinator import Koordinator
|
||||
@@ -56,18 +56,31 @@ def _vollstaendig(aenderungen: dict, fahrt: dict) -> dict:
|
||||
|
||||
|
||||
async def durchfuehren(k: Koordinator) -> None:
|
||||
"""Versucht, alle offenen Fahrten zu vervollständigen."""
|
||||
"""Versucht, alle offenen Fahrten zu vervollständigen, und trägt allen
|
||||
Fahrten ohne Standortdaten Start-/Zielposition sowie eine Streckenlinie
|
||||
nach - unabhängig vom Kilometerstand-Status, da beide Datenquellen
|
||||
unabhängig voneinander verspätet eintreffen können."""
|
||||
km_sensor = k.zuordnung.werte.KM_SENSOR
|
||||
fahrten = await k.ablage.fahrten_lesen()
|
||||
offene = [f for f in fahrten if f.get("status") == "offen"]
|
||||
if not offene:
|
||||
if not fahrten:
|
||||
return
|
||||
offene.sort(key=lambda f: f.get("ts_start", ""))
|
||||
|
||||
offene = [f for f in fahrten if f.get("status") == "offen"]
|
||||
if km_sensor:
|
||||
offene.sort(key=lambda f: f.get("ts_start", ""))
|
||||
for fahrt in offene:
|
||||
await _fahrt_screenen(k, km_sensor, fahrt)
|
||||
|
||||
lat_sensor = k.zuordnung.werte.STANDORT_LAT_SENSOR
|
||||
lon_sensor = k.zuordnung.werte.STANDORT_LON_SENSOR
|
||||
if lat_sensor and lon_sensor:
|
||||
ohne_position = [
|
||||
f for f in fahrten
|
||||
if f.get("start_lat") is None or f.get("end_lat") is None or f.get("route") is None
|
||||
]
|
||||
for fahrt in ohne_position:
|
||||
await _position_screenen(k, lat_sensor, lon_sensor, fahrt)
|
||||
|
||||
await _lueckenlos_verketten(k)
|
||||
await k.fahrten_veroeffentlichen()
|
||||
|
||||
@@ -105,6 +118,49 @@ async def _fahrt_screenen(k: Koordinator, km_sensor: str, fahrt: dict) -> None:
|
||||
await k.ablage.fahrt_aktualisieren(fahrt["trip_id"], _vollstaendig(aenderungen, fahrt))
|
||||
|
||||
|
||||
async def _position_screenen(
|
||||
k: Koordinator, lat_sensor: str, lon_sensor: str, fahrt: dict
|
||||
) -> None:
|
||||
"""Trägt Start-/Zielposition und eine echte Streckenlinie nach, sobald der
|
||||
GPS-Verlauf sie hergibt - unabhängig vom Kilometerstand-Status.
|
||||
|
||||
Dieselbe "Fahrt gehört der Vergangenheit an" wie bei den Kilometerständen:
|
||||
kein Live-Zustand zum Fahrtbeginn/-ende wird herangezogen (der wäre bei
|
||||
einer Funklücke des Trackers unzuverlässig, siehe fahrterkennung.py), nur
|
||||
der aufgezeichnete Verlauf im Fahrtfenster."""
|
||||
start = _als_zeit(fahrt.get("ts_start"))
|
||||
ende = _als_zeit(fahrt.get("ts_end"))
|
||||
if start is None or ende is None:
|
||||
return
|
||||
|
||||
lat_verlauf = await verlauf_lesen(k.hass, lat_sensor, start - SUCHFENSTER, ende + SUCHFENSTER)
|
||||
lon_verlauf = await verlauf_lesen(k.hass, lon_sensor, start - SUCHFENSTER, ende + SUCHFENSTER)
|
||||
if not lat_verlauf or not lon_verlauf:
|
||||
return
|
||||
|
||||
aenderungen: dict = {}
|
||||
if fahrt.get("start_lat") is None:
|
||||
lat = naechster_wert(start, lat_verlauf)
|
||||
lon = naechster_wert(start, lon_verlauf)
|
||||
if lat is not None and lon is not None:
|
||||
aenderungen["start_lat"] = lat
|
||||
aenderungen["start_lon"] = lon
|
||||
if fahrt.get("end_lat") is None:
|
||||
lat = naechster_wert(ende, lat_verlauf)
|
||||
lon = naechster_wert(ende, lon_verlauf)
|
||||
if lat is not None and lon is not None:
|
||||
aenderungen["end_lat"] = lat
|
||||
aenderungen["end_lon"] = lon
|
||||
if fahrt.get("route") is None:
|
||||
route = route_aus_verlauf(lat_verlauf, lon_verlauf, start, ende)
|
||||
if route is not None:
|
||||
aenderungen["route"] = route
|
||||
|
||||
if aenderungen:
|
||||
await k.ablage.fahrt_aktualisieren(fahrt["trip_id"], aenderungen)
|
||||
fahrt.update(aenderungen)
|
||||
|
||||
|
||||
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