Pausenregel rechnet in Geraetezeit - zwei Fahrten bleiben zwei

Am 04.09.2026 war der Dongle von 18:25 bis 23:36 ohne Verbindung. Als er
sich meldete, kamen das Zuendungs-Aus der ersten Fahrt und das Ein der
zweiten in DERSELBEN Sekunde bei Home Assistant an - ihre Geraetezeiten
lagen 5 Stunden 12 auseinander (18:23:32 und 23:35:43).

Die Pausenregel mass an der Ankunft: 0 Sekunden, also dieselbe Fahrt.
Ergebnis war ein Eintrag von 18:10 bis 23:42 ueber 5 h 33 ohne Strecke,
und die Fahrt um 23:30 gab es gar nicht.

Zwei Stellen im Code trugen dazu bei:
- zuendung_geaendert() rief bedingungslos warte_ende_ab_abbrechen(); das
  "an" loeschte damit das wartende Ende des "aus" derselben Sekunde.
- Der Fall "an, waehrend eine Fahrt laeuft" fiel wortlos durch alle drei
  Zweige von _signalwechsel(). Dazu steht seit dem 02.09. ein Kommentar im
  Code - damals wurde eine Sperre eingebaut, die die Reihenfolge richtig
  stellt, aber nicht den Ausgang.

Neu entscheidet _zuendung_kehrt_zurueck() in Geraetezeit. Der Koordinator
fuehrt mit, welches Ende gerade seine Pausenzeit absitzt (ende_wartet).
Liegt zwischen dem echten Ende und dem neuen "an" mehr als die Pausenzeit,
wird die alte Fahrt auf ihr berechnetes Ende geschlossen und eine neue
begonnen. Gemessen wird ab dem echten Ende, nicht ab dem Signal. Ohne
wartendes Ende passiert nichts - ein Schnitt auf Verdacht waere schlimmer
als eine zu lange Fahrt.

Das behebt die Verspaetung nicht, es macht sie harmlos.

Die Tests mussten zwei Dinge trennen, die vorher eine Zahl waren: PAUSE_S
(900, das Fenster der Regel) und WARTEN (0,15 s, die Wanduhrzeit des Tests).

18 Tests in test_zuendungspause.py (von 14), py_compile sauber,
audi_ha_test auf 2026.9.4.24 ohne Traceback. Gegenprobe am alten Stand:
2 der 4 neuen Tests scheitern dort, mit der Korrektur laufen alle 18.
This commit is contained in:
2026-09-05 00:40:59 +02:00
parent b0ec8b4982
commit 242312441d
8 changed files with 337 additions and 15 deletions
+113
View File
@@ -11117,3 +11117,116 @@ Standort-Blatt sei fehlerhaft, weil "Route" und "Teilen" hinter der Tab-Leiste
liegen. Das war falsch - die 96-px-Vorschau ist Absicht, aufgezogen sitzt das
Blatt sauber 30 px ueber der Leiste. Mein Klick-Test war der Fehler, nicht die
App: das Blatt hoert auf Zeigerereignisse, nicht auf `click`.
## CQ. Zwei Fahrten wurden zu einer, weil die Pausenregel an der Wanduhr hing (2026.9.4.24)
Gemeldet als "erneut Fehler/Einschlafen unterwegs". Die Untersuchung hat drei
meiner eigenen Erklaerungen widerlegt, bevor die richtige uebrig blieb - die
falschen stehen hier mit, weil sie der lehrreiche Teil sind.
### Was NICHT die Ursache war
* **"Der Dongle schlaeft unterwegs ein."** Nachgerechnet: das Geraet war nach
dem Abstellen noch rund zwoelf Minuten wach (Schlaf-Timeout `103` = 15 Min.
ab Zuendungs-Aus) und hatte einen Datensatz hoher Prioritaet in der Hand.
Es hat in dieser Zeit keine Verbindung aufgebaut. Nicht der Schlaf.
* **"`close_code 17` ist neu, das kommt vom frisch gesetzten Ping."** Ueber
alle 4190 Protokolleintraege gezaehlt: erstmals **11.08.2026**, 23 Mal.
Nichts Neues.
* **"Der Sendetakt im Stand steht auf 24 h."** Das stand in flespis `current` -
und `current` ist, was das Geraet ZULETZT GEMELDET hat. Die aufgespielte
Konfiguration hat dort 0. Der Eigentuemer hat es richtiggestellt: **"die
gelesenen werte sind veraltet"**.
**Merkposten:** `flespi.INTERESSANT` vergleicht `trip_scenario.ign_off_timeout`
gegen unsere Konstante `NACHLAUF_S`. Es las 900, unsere Konstante ist 900, also
meldete der Waechter `abweichung: false`. Das Geraet hat dort **0** - das
Trip-Szenario ist abgeschaltet. Der Waechter, der genau dieses Auseinanderlaufen
melden soll, ist auf einen veralteten Wert hereingefallen, weil er nie fragt,
wie alt `current` ist. **Ein stiller Gleichstand mit einem veralteten Wert ist
schlimmer als gar kein Vergleich.** (Noch offen.)
### Was die Ursache war - gemessen, nicht erschlossen
Das Geraet war von 18:25 bis 23:36 ohne Verbindung (fest im geparkten Auto,
niemand hat etwas angefasst). Als es sich meldete, kamen zwei Zuendungs-
ereignisse in **derselben Sekunde** bei Home Assistant an:
| Ankunft | Geraetezeit | Rueckstand |
|---|---|---|
| 23:36:50 | **18:23:32** | 5 h 13 - das Aus der ersten Fahrt |
| 23:36:50 | **23:35:43** | 67 s - das Ein der zweiten |
Die Pausenregel fragt: "kommt die Zuendung innerhalb von 15 Minuten zurueck?"
Sie mass das an der **Ankunft**. Nach Ankunft: 0 Sekunden, also dieselbe Fahrt.
Nach **Geraetezeit**: 5 Stunden 12, also zwei Fahrten.
Ergebnis: **ein Eintrag von 18:10 bis 23:42, 5 h 33, ohne Strecke** - und die
Fahrt um 23:30 gab es gar nicht. Sie steckte darin.
Dazu kamen zwei Stellen im Code:
1. `zuendung_geaendert()` rief **bedingungslos** `warte_ende_ab_abbrechen()`.
Das "an" loeschte damit das wartende Ende des "aus" derselben Sekunde.
2. Der Fall "**an, waehrend eine Fahrt laeuft**" fiel durch alle drei Zweige
von `_signalwechsel()` - wortlos.
Zu 2. steht im Code seit dem 02.09. ein langer Kommentar: damals hat genau das
"eine ganze Fahrt gekostet". Eingebaut wurde daraufhin eine **Sperre**, damit
die Ereignisse sich nicht ueberholen. Die Reihenfolge stimmt seither - **der
Ausgang nicht.** Die Sperre hat das Symptom behandelt.
### Die Korrektur
`_zuendung_kehrt_zurueck()` entscheidet jetzt in **Geraetezeit**:
* Der Koordinator fuehrt mit, welches Ende gerade seine Pausenzeit absitzt
(`ende_wartet`, Beginn und Ende beide in Geraetezeit). Ohne diese Angabe
konnte der Beobachter nur abbrechen.
* Liegt zwischen dem echten Ende und dem neuen "an" **mehr** als die
Pausenzeit, wird die alte Fahrt auf ihr bereits berechnetes Ende geschlossen
und eine neue begonnen. Sonst bleibt es wie bisher dieselbe Fahrt.
* Gemessen wird ab dem **echten Ende** (Zuendungs-Aus minus Nachlauf), nicht ab
dem Signal - sonst waere die Grenze um 180 s verschoben.
* Ohne wartendes Ende passiert weiterhin nichts. Fehlt das "aus" ganz, waere
ein Schnitt auf Verdacht schlimmer als eine zu lange Fahrt.
Der bedingungslose Abbruch ist weg; abgebrochen wird jetzt in jedem Zweig
einzeln, dort wo die Geraetezeit bekannt ist.
**Das behebt die Verspaetung nicht - es macht sie harmlos.** Ein fuenf Stunden
zu spaet gelieferter Stapel ergibt jetzt zwei richtige Fahrten statt einer
falschen.
### Die Tests mussten zwei Dinge trennen
`PAUSE = 0.15` war bisher beides zugleich: das Fenster der Pausenregel und die
Wanduhrzeit, die der Test absitzt. Seit die Regel in Geraetezeit rechnet, geht
das nicht mehr - mit 0,15 s als Fenster haette der Test etwas anderes geprueft
als der Betrieb tut. Jetzt: `PAUSE_S = 900` fuer die Entscheidung,
`WARTEN = 0.15` fuer das Warten (ueber ein kurzes `_nach_pause_beenden`).
### Verifiziert
**18 Tests** in `test_zuendungspause.py` (von 14), dazu 5 + 13 in den beiden
anderen Dateien - alle gruen. `py_compile` sauber. `audi_ha_test` auf
`2026.9.4.24`, **0 Tracebacks**.
**Gegenprobe am alten Stand gelaufen** (der neue Zweig durch das alte
`warte_ende_ab_abbrechen()` ersetzt): **2 der 4 neuen Tests scheitern**, mit der
Korrektur laufen alle 18. Die beiden anderen neuen Tests sind Gegenproben in
die andere Richtung (kurze Rueckkehr, fehlendes "aus") und gruen in beiden
Staenden - so sollen sie sein.
### Was offen bleibt
* Der flespi-Waechter meldet Gleichstand gegen veraltete Werte (oben).
* `NACHLAUF_S = 900` ist als "Trip: Ignition OFF Timeout" beschriftet; das
Geraet hat dort 0. Die 900, die es wirklich gibt, sind der Schlaf-Timeout -
ein anderer Parameter.
* **Am Dongle wurde nichts geaendert.** Der Eigentuemer hat am Morgen des
04.09. `1003` (Network Ping) von 0 auf 60 und `1004` (Ack Type) auf 1
gesetzt; zugestellt wurden sie um 18:08, mitten in der ersten Fahrt. Bei der
zweiten Fahrt hielt die Sitzung 18 Minuten durch und schloss normal, der
Rueckstand lag durchgehend bei 1-3 Sekunden. **Das wirkt** - die
Zustellluecke selbst ist damit aber noch nicht als behoben bewiesen.