Regler stellt den Schlaf-Timeout des Dongles (2026.9.3.10)
Der Regler "Fahrt beenden" ist jetzt eine Zahl fuer zwei Dinge: unsere eigene
Wartezeit bis zum Fahrtende und der Schlaf-Timeout des FMM003 (103). So lange
bleibt der Dongle wach und wartet darauf, dass es gleich weitergeht; danach
schlaeft er. Die 180 s Ignition OFF Delay laufen davor und bleiben unsichtbar -
sie werden nur von der Fahrtdauer abgezogen. Der Regler geht deshalb von 1 bis
60 in Einerschritten; das Geraet kennt kein Timeout 0.
flespi.py liest und schreibt die Geraete-Konfiguration. Drei Annahmen sind an
der echten API gefallen und stehen als Messung im Modulkopf: der Wert liegt in
current (nicht value), die Einstellung heisst sleep_mode mit dem Wert eine Ebene
tiefer unter mode, und ein PUT braucht {"properties": ..., "address": ...}.
Die eigene Auftrags-Warteschlange ist wieder entfallen. Sie war fuer "das Geraet
schlaeft" gebaut - das gilt aber nur fuer das Geraet, nicht fuer die
Schnittstelle: die vollstaendige Konfiguration kam herein, waehrend das Fahrzeug
seit dem Vortag stand. flespi puffert selbst (pending + address=connection), ein
zweites Auftragsbuch waere eine zweite Warteschlange fuer dieselbe Aufgabe.
Gegengelesen wird nach jedem Schreiben; als Erfolg zaehlt current ODER pending -
letzteres ist bei stehendem Fahrzeug der Normalfall.
Live gegen den echten Account belegt: Token sieht genau ein Geraet, 127
Einstellungen bei parkendem Fahrzeug gelesen, Regler 15 geschrieben und als
pending bestaetigt (Nachbarfelder unveraendert), zweiter Neustart ohne erneute
Anfrage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -485,18 +485,47 @@ async def _spaetes_aus(
|
||||
ende = await _geraetezeit(k, ereigniszeit, jetzt)
|
||||
echt = ende - datetime.timedelta(seconds=ZUENDUNG_NACHLAUF_S)
|
||||
|
||||
juengste = None
|
||||
# Zwei verschiedene Fragen, deshalb zwei Suchen ueber denselben Bestand:
|
||||
#
|
||||
# juengstes_ende beantwortet "gehoert das Aus zur zuletzt geschlossenen
|
||||
# Fahrt?" - das ist der Verwerfen-Zweig unten.
|
||||
#
|
||||
# kandidat beantwortet "gibt es eine von Hand beendete Fahrt, deren Ende
|
||||
# dieses Aus nachtraegt?". Bewusst NICHT auf die juengste Fahrt beschraenkt:
|
||||
# trifft das gepufferte Aus erst ein, nachdem schon eine weitere Fahrt
|
||||
# aufgezeichnet wurde, waere die vorlaeufige sonst fuer immer zu kurz. Es
|
||||
# gewinnt die vorlaeufige Fahrt, deren Ende dem Aus am naechsten VOR ihm
|
||||
# liegt - jede spaetere kann nicht gemeint sein.
|
||||
fahrten = await k.ablage.fahrten_lesen()
|
||||
juengstes_ende = None
|
||||
for fahrt in await k.ablage.fahrten_lesen():
|
||||
kandidat = None
|
||||
kandidat_ende = None
|
||||
for fahrt in fahrten:
|
||||
roh = fahrt.get("ts_end")
|
||||
if not roh:
|
||||
continue
|
||||
ts = zeit_normalisiert(roh)
|
||||
if juengstes_ende is None or ts > juengstes_ende:
|
||||
juengste, juengstes_ende = fahrt, ts
|
||||
juengstes_ende = ts
|
||||
if fahrt.get("ende_vorlaeufig") and ts < echt:
|
||||
if kandidat_ende is None or ts > kandidat_ende:
|
||||
kandidat, kandidat_ende = fahrt, ts
|
||||
|
||||
if juengste is not None and await _vorlaeufiges_ende_korrigieren(
|
||||
k, juengste, juengstes_ende, echt
|
||||
# Eine Fahrt darf nicht ueber eine andere hinweg verlaengert werden. Faengt
|
||||
# zwischen dem vorlaeufigen Ende und dem Aus eine Fahrt an, gehoert das Aus
|
||||
# zu ihr oder zu etwas Spaeterem - jedenfalls nicht mehr zur vorlaeufigen,
|
||||
# und zwei sich ueberlappende Fahrten waeren schlimmer als eine zu kurze.
|
||||
if kandidat is not None and _fahrt_dazwischen(fahrten, kandidat, kandidat_ende, echt):
|
||||
_LOGGER.info(
|
||||
"Zuendungs-Aus (Geraetezeit %s) koennte die vorlaeufige Fahrt %s "
|
||||
"verlaengern, aber dazwischen liegt bereits eine andere Fahrt - "
|
||||
"nicht korrigiert",
|
||||
echt.isoformat(), kandidat["trip_id"],
|
||||
)
|
||||
kandidat = None
|
||||
|
||||
if kandidat is not None and await _vorlaeufiges_ende_korrigieren(
|
||||
k, kandidat, kandidat_ende, echt
|
||||
):
|
||||
return
|
||||
|
||||
@@ -517,6 +546,25 @@ async def _spaetes_aus(
|
||||
)
|
||||
|
||||
|
||||
def _fahrt_dazwischen(
|
||||
fahrten: list[dict],
|
||||
kandidat: dict,
|
||||
kandidat_ende: datetime.datetime,
|
||||
echt: datetime.datetime,
|
||||
) -> bool:
|
||||
"""Faengt zwischen dem vorlaeufigen Ende und dem Aus eine andere Fahrt an?"""
|
||||
for fahrt in fahrten:
|
||||
if fahrt.get("trip_id") == kandidat.get("trip_id"):
|
||||
continue
|
||||
roh = fahrt.get("ts_start")
|
||||
if not roh:
|
||||
continue
|
||||
beginn = zeit_normalisiert(roh)
|
||||
if kandidat_ende < beginn <= echt:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
async def _vorlaeufiges_ende_korrigieren(
|
||||
k: Koordinator,
|
||||
fahrt: dict,
|
||||
@@ -532,10 +580,17 @@ async def _vorlaeufiges_ende_korrigieren(
|
||||
verworfen.
|
||||
|
||||
Drei Bedingungen, jede aus einem eigenen Grund: nur eine als vorlaeufig
|
||||
gekennzeichnete Fahrt (eine regulaer geschlossene ist bereits richtig),
|
||||
nur ein SPAETERES Ende (frueher waere kein Nachtrag, sondern eine
|
||||
Verkuerzung), und nur innerhalb von KORREKTUR_FENSTER_S (sonst gehoert das
|
||||
Aus wahrscheinlich zu einer ganz anderen Fahrt).
|
||||
gekennzeichnete Fahrt (eine regulaer geschlossene ist bereits richtig - ihr
|
||||
Ende IST dieses Signal, ein zweites waere nur die gepufferte Kopie), nur ein
|
||||
SPAETERES Ende (frueher waere kein Nachtrag, sondern eine Verkuerzung), und
|
||||
nur innerhalb von KORREKTUR_FENSTER_S.
|
||||
|
||||
Zum Fenster: gemessen wird zwischen dem vorlaeufigen Ende und der
|
||||
GERAETEZEIT des Aus - nicht zwischen Knopfdruck und Eintreffen. Ein
|
||||
Datensatz, der eine Woche in der Tiefgarage liegt, traegt trotzdem seinen
|
||||
eigenen Zeitstempel von damals (siehe verlauf.geraetezeit); das Fenster
|
||||
begrenzt also, wie lange nach dem letzten Lebenszeichen noch gefahren
|
||||
worden sein kann, nicht wie lange das Geraet puffern darf.
|
||||
|
||||
ts_end wandert bewusst NICHT in edited_fields: das Feld ist keine
|
||||
Handeingabe, und dort eingetragen wuerde es genau diese Korrektur beim
|
||||
|
||||
Reference in New Issue
Block a user