Fahrtzeiten vom Geraet, Trip und Zuendung getrennt (2026.9.1.3)
Enthaelt 2026.9.1.2, das nie einzeln ausgeliefert wurde. FAHRT- UND TANKZEITEN KOMMEN VOM GERAET Fahrtbeginn war datetime.now() - die Uhrzeit, zu der Home Assistant den Wechsel verarbeitet. Hat das Geraet gepuffert (Funkloch, Tiefgarage, Tiefschlaf), liegt die Wahrheit beliebig weit davor. Gemessen: ein Datensatz mit Fahrtende trug die Geraetezeit 07:29:04 und kam um 07:35:23 an. Neue Sensorrolle MELDEZEIT_SENSOR (message_timestamp, Unix-Sekunden). Der Wert ist UTC, keine Ortszeit - nachgemessen lag der Versatz zur UTC-Uhr von HA bei Sekunden, nicht bei zwei Stunden; eine Zeitzonenumrechnung baute einen Zwei-Stunden-Fehler ein. geraetezeit() liegt in verlauf.py, weil Fahrt- und Tankerkennung denselben Zeitstempel bestimmen muessen. tankerkennung._automatisch_anlegen() stempelte bisher ebenfalls mit now(); ein aus einem gepufferten Datensatz erkannter Tankvorgang trug damit die Uhrzeit des Auftauchens. Die flespi-Integration setzt die Entitaeten eines Datensatzes nacheinander - gemessen Zuendung 07:35:23.633, zugehoerige Meldezeit 2 ms spaeter. Wer sofort liest, bekommt den vorigen Datensatz: beim Fahren zehn Sekunden daneben, im Stand Stunden (On Stop Min Period = 43200 s). geraetezeit() wartet deshalb bis zu 2 s auf den passenden Wert. Zwei Notbremsen, beide live ausgeloest: Zeitstempel in der Zukunft und Ende vor dem Beginn. TRIP UND ZUENDUNG SIND ZWEI ROLLEN ZUENDUNG_SENSOR zeigte auf das Trip-Signal; im Setup stand "Zuendung/ACC" ueber einer Trip-Entitaet und die echte Zuendung war nirgends zugeordnet. Neu: TRIP_SENSOR loest Fahrten aus, ZUENDUNG_SENSOR liefert nur noch die Anzeige "faehrt/steht". verlauf.fahrtsignal() ist die eine Stelle, die entscheidet - Trip-Status wenn zugeordnet, sonst Zuendung, damit bestehende Installationen unveraendert weiterlaufen und Livepfad und Rueckblick nicht auseinanderlaufen. VERIFIZIERT in audi_ha_test, jeder Weg einzeln: - Fahrtbeginn 08:30:03 (Geraetezeit) statt 08:38:27 (Ankunft) - Fahrtende 08:04:40 -> 08:09:22 statt 08:11:04 -> 08:11:24 - Tankvorgang 08:18:45 statt 08:38:51 - 20 Minuten frueher - Meldezeit in der Zukunft und Ende vor Beginn: Warnung, Ankunft genommen - Zuendung schalten legt keine Fahrt mehr an, Trip-Signal schon Der Livetest fing dabei einen NameError, den py_compile nicht sehen konnte: der Import von geraetezeit in tankerkennung.py fehlte. Kompiliert ist nicht verifiziert. Alle Testdatensaetze wurden ueber die eigenen Dienste wieder entfernt; Bestand unveraendert 11 Fahrten, 13 Tankvorgaenge, keine offene Fahrt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
# AGENTS.md — Project state, review findings, open items, and working rules
|
||||
|
||||
**Last updated: 2026-09-01** (Phantomfahrten beim Neustart abgestellt, Tankstand auf `wert_bei()`
|
||||
**Last updated: 2026-09-01** (Fahrtbeginn und -ende kommen jetzt vom Gerät (`MELDEZEIT_SENSOR`),
|
||||
Manifest `2026.9.1.3`, siehe Abschnitt AY: dazu die Trennung von
|
||||
Trip- und Zündungsrolle und die Gerätezeit für Tankvorgänge. Davor am selben Tag: Phantomfahrten beim Neustart abgestellt, Tankstand auf `wert_bei()`
|
||||
nachgezogen, zwölf Nullfahrten gelöscht, „Open items" von vier MQTT-Karteileichen befreit;
|
||||
Manifest `2026.9.1.1`, siehe Abschnitt AX. Davor am 2026-08-31: Streckenberechnung: `wert_bei()`
|
||||
statt `naechster_wert()` und
|
||||
@@ -6393,6 +6395,129 @@ am 2026-09-01 die zwölf Fahrten mit `distance_km == 0` gelöscht — über den
|
||||
Das ist eine Abkehr von der Linie in Abschnitt W und AV, wo Nullfahrten bewusst stehen blieben.
|
||||
Sie gilt, weil der Eigentümer sie ausdrücklich getroffen hat — nicht als neue Gewohnheit.
|
||||
|
||||
## AY. Der Dongle ist jetzt führend für Fahrtbeginn und -ende (2026.9.1.2)
|
||||
|
||||
Bis hierher war der Fahrtbeginn `datetime.now()` — die Uhrzeit, zu der Home Assistant den
|
||||
Zustandswechsel *verarbeitet*. Hat das Gerät gepuffert (Funkloch, Tiefgarage, Tiefschlaf), liegt
|
||||
die Wahrheit beliebig weit davor. Am 01.09.2026 gemessen: der Datensatz mit dem Fahrtende trug
|
||||
die Gerätezeit **07:29:04** und kam um **07:35:23** an — sechs Minuten und 19 Sekunden später.
|
||||
|
||||
Neue Sensorrolle **`MELDEZEIT_SENSOR`** (`…_message_timestamp`, Unix-Sekunden). Ist sie
|
||||
zugeordnet, stammen Beginn und Ende der Fahrt daraus statt aus der Ankunftszeit.
|
||||
|
||||
### Die Zeitzonenfrage, gemessen statt vermutet
|
||||
|
||||
Der Zeitstempel ist **UTC**, keine Ortszeit. Der Versatz zur UTC-Uhr von Home Assistant lag bei
|
||||
Sekunden (1,3 s / 2,3 s / 232,8 s nach einer Funklücke), nicht bei zwei Stunden. Eine
|
||||
Zeitzonenumrechnung wäre nicht nur unnötig — sie baute einen Zwei-Stunden-Fehler ein. Die
|
||||
Gerätekonfiguration stützt das: `107 = After Time Sync` (das Gerät speichert erst, wenn seine
|
||||
Uhr steht), NTP-Resync alle drei Stunden.
|
||||
|
||||
### Die Wartezeit, und warum sie da sein muss
|
||||
|
||||
Die flespi-Integration setzt die Entitäten eines Datensatzes **nacheinander**: gemessen stand die
|
||||
Zündung um 07:35:23.633 und die zugehörige Meldezeit 2 ms später um 07:35:23.635. Wer sofort
|
||||
liest, bekommt den Zeitstempel des *vorigen* Datensatzes — beim Fahren zehn Sekunden daneben, im
|
||||
Stand aber möglicherweise **Stunden**, weil das Gerät dort nur alle paar Stunden einen Satz
|
||||
schreibt (siehe die Data-Acquisition-Werte unten).
|
||||
|
||||
`_geraetezeit()` wartet deshalb bis zu `MELDEZEIT_FRIST_S = 2.0` in 50-ms-Schritten darauf,
|
||||
dass `last_updated` der Meldezeit den Zeitpunkt des Zündungswechsels erreicht. Dafür reicht der
|
||||
Koordinator die Ereigniszeit jetzt mit durch (`zuendung_geaendert(..., ereigniszeit)`).
|
||||
|
||||
Zwei Notbremsen, beide live ausgelöst und im Protokoll nachgewiesen:
|
||||
|
||||
- **Zukunft** (mehr als 5 Minuten voraus) → verworfen, Ankunftszeit gilt. Eine falsch gestellte
|
||||
Geräteuhr darf die Auswertung nicht mitreißen.
|
||||
- **Ende vor dem Beginn** → verworfen, Ankunftszeit gilt.
|
||||
|
||||
### Live nachgewiesen, alle vier Wege
|
||||
|
||||
| Fall | Ergebnis |
|
||||
|---|---|
|
||||
| Beginn mit Gerätezeit | Fahrt beginnt `08:04:40`, Ankunft war `08:11:04` — 6:24 früher |
|
||||
| Ende mit Gerätezeit | Fahrt `08:04:40 → 08:09:22`, 282 s; Ankunft war `08:11:24` |
|
||||
| Meldezeit vor dem Beginn | Warnung, Ankunft genommen, danach von `MINDESTDAUER_S` verworfen |
|
||||
| Meldezeit in der Zukunft | Warnung, Ankunft genommen |
|
||||
|
||||
Geprüft über den echten Dienst `entitaeten_schreiben` (Rolle zugeordnet, alle übrigen 35
|
||||
Einträge unangetastet); die dabei entstandene Testfahrt wurde über `fahrt_loeschen` wieder
|
||||
entfernt. Bestand danach unverändert 11 Fahrten, keine mit 0 km, keine offene Fahrt.
|
||||
|
||||
### Was das NICHT löst — die Gerätekonfiguration
|
||||
|
||||
Die `.cfg` vom 01.09.2026 (gzip-gepackte Klartext-Parameterliste, mit `gunzip` lesbar) erklärt
|
||||
den Rest, und er liegt nicht im Code:
|
||||
|
||||
| ID | Bedeutung | Wert | Standard |
|
||||
|---|---|---|---|
|
||||
| 102 / 103 | Sleep settings / Timeout | Deep Sleep / 15 min | Deep Sleep / 1 min |
|
||||
| 10000 | *On Stop* Min Period | **43.200 s (12 h)** | 3.600 s |
|
||||
| 10005 | *On Stop* Send Period | **86.400 s (24 h)** | 120 s |
|
||||
| 10050 / 10055 | *Moving* Min Period / Send Period | 10 s / 60 s | 300 s / — |
|
||||
| 11800 | Trip-Szenario | **1 = Low priority** | 0 |
|
||||
| 11803 / 11804 | Start speed / Ignition off timeout | 3 km/h / 900 s | 5 / 60 |
|
||||
| 11806 | Odometer Calculation source | **1 = OBD** | 0 = GNSS |
|
||||
| 101 | Ignition settings | 8 = Engine RPM | 4 = Power Voltage |
|
||||
|
||||
Zwei Werte bestimmen alles Weitere:
|
||||
|
||||
1. **`11800 = Low priority`.** Laut Teltonika-Wiki macht Low priority „an additional record",
|
||||
High priority dagegen „sends event packet **immediately** to the server using GPRS". Fahrtbeginn
|
||||
und -ende warten also auf das nächste Sendefenster — im Stand bis zu 24 Stunden.
|
||||
2. **`11806 = OBD`.** Der Kilometerzähler des Geräts ist damit eine Kopie des Fahrzeugwerts und
|
||||
kann nie feiner sein als der: **ganze Kilometer**. Mit `GNSS` lieferte er nachweislich
|
||||
Meterauflösung (209177,016 → ,019 → ,022). Gemessen an allen vom CAN gelesenen Streckenwerten
|
||||
dieses Fahrzeugs gibt es **keinen** mit einer Nachkommastelle: Distanz seit Tanken, Distanz seit
|
||||
Fehlerlöschung und Reichweite springen in ganzen Kilometern, die Servicedistanz in
|
||||
Zehnerschritten. `segment_mileage` (die Strecke seit dem letzten Datensatz, `11802 = Between
|
||||
records`) folgt derselben Quelle: mit GNSS Meter, mit OBD ganze Kilometer.
|
||||
|
||||
### Trip und Zündung sind zwei Rollen, nicht eine (2026.9.1.3)
|
||||
|
||||
Bis hierher zeigte `ZUENDUNG_SENSOR` auf das Trip-Signal — im Setup stand dann „Zündung/ACC-Status"
|
||||
über einer Trip-Entität, und die echte Zündung war nirgends mehr zugeordnet. Der Eigentümer hat das
|
||||
getrennt haben wollen, zu Recht: es sind zwei verschiedene Aussagen.
|
||||
|
||||
- **`TRIP_SENSOR`** (neu) — löst Fahrtbeginn und -ende aus. Das gefilterte Signal des Geräts.
|
||||
- **`ZUENDUNG_SENSOR`** — nur noch die Anzeige „fährt/steht" im Fahrzeugstatus und auf der
|
||||
Standortkarte. Am Gerät steht die Zündungsquelle jetzt auf `101 = 8` (Engine RPM); ACC und
|
||||
Bordspannung sind raus, weil unzuverlässig. Der Entitätsname trägt „acc" weiterhin im Text, der
|
||||
Inhalt kommt aber aus der Drehzahl.
|
||||
|
||||
`verlauf.fahrtsignal(werte)` ist die eine Stelle, die entscheidet, was Fahrten auslöst: der
|
||||
Trip-Status, wenn zugeordnet, sonst die Zündung. Damit laufen bestehende Installationen unverändert
|
||||
weiter, und Livepfad (`fahrterkennung.py`, `koordinator.py`) und Rückblick
|
||||
(`historienimport.py`) können nicht auseinanderlaufen — dieselbe Regel wie bei
|
||||
`UNPLAUSIBLE_KMH` und `MINDESTDAUER_S`.
|
||||
|
||||
Der Koordinator beobachtet beide: das Fahrtsignal für die Erkennung, die Zündung nur, um den Status
|
||||
sofort neu zu veröffentlichen. Zeigen beide auf dieselbe Entität, entfällt der zweite Beobachter.
|
||||
|
||||
### Auch der Tankvorgang trägt jetzt die Gerätezeit
|
||||
|
||||
`tankerkennung._automatisch_anlegen()` stempelte mit `datetime.now()` — derselbe Fehler wie bei
|
||||
den Fahrten, nur unbemerkt. `geraetezeit()` liegt deshalb jetzt in `verlauf.py` und wird von
|
||||
beiden benutzt; `fahrterkennung._geraetezeit()` ist nur noch eine Weiterleitung.
|
||||
|
||||
Live nachgewiesen: ein aus einem gepufferten Datensatz erkannter Tankvorgang trägt `08:18:45`,
|
||||
während Home Assistant ihn um `08:38:51` verarbeitet hat — **20 Minuten früher**.
|
||||
|
||||
**Der Livetest hat dabei einen echten Fehler gefangen**, den `py_compile` nicht sehen konnte: der
|
||||
Import von `geraetezeit` in `tankerkennung.py` fehlte, und der `NameError` trat erst beim
|
||||
Anlegen auf. Ein weiterer Beleg für die Regel dieses Projekts — kompiliert ist nicht verifiziert.
|
||||
|
||||
### Was am Gerät noch offen ist
|
||||
|
||||
`11800` steht jetzt auf High priority (Fahrtgrenzen werden sofort gesendet), `11806` wird auf
|
||||
GNSS umgestellt. **Damit ist die Streckenrechnung noch nicht angepasst:** geplant ist, die Strecke
|
||||
aus dem GNSS-Zähler zu nehmen (Meterauflösung) und den CAN-Kilometerstand als Anker zu behalten, an
|
||||
dem sich Drift erkennen lässt. Noch nicht gebaut — erst messen, wenn das Gerät wirklich GNSS liefert,
|
||||
sonst testet man gegen ganze Kilometer.
|
||||
|
||||
`11807` (Odometer Value) steht auf 0. Für die geplante Rechnung ist das gleichgültig, weil sie mit
|
||||
Zuwächsen arbeitet; wer den absoluten Wert lesbar haben will, trägt dort den echten Kilometerstand ein.
|
||||
|
||||
## Working conventions (observed — keep them)
|
||||
|
||||
- German is the project language: identifiers, comments, commits, UI texts. Exceptions:
|
||||
|
||||
Reference in New Issue
Block a user