GNSS-Rollen vorbereitet, "Geparkt seit" von der Zuendung (2026.9.1.5/.6)
GNSS-STRECKENROLLEN, NOCH OHNE VERBRAUCHER 11806 steht seit dem 01.09. auf GNSS. Zwei neue Sensorrollen angelegt, damit nach der ersten echten Fahrt nur noch gemessen und nicht mehr zugeordnet werden muss: GNSS_KM_SENSOR (total_calculated_mileage, der robustere fuer eine Fahrtstrecke - ein verlorener Datensatz verfaelscht die Differenz nicht) und GNSS_TEILSTRECKE_SENSOR (segment_mileage, zeigt WO Strecke fehlt, taugt als Gegenprobe). Kein Code liest sie; die Zuordnung aendert nichts. KM_SENSOR bleibt der Anker - er ist der Tacho des Fahrzeugs und driftet nicht. Der alte Warnhinweis dort zeigt jetzt auf die neue Rolle statt ins Leere. "GEPARKT SEIT" KOMMT VON DER ZUENDUNG Die Anzeige rechnete "jetzt minus ts_end der juengsten Fahrt". Das ist keine Aussage ueber das Parken, sondern ueber die Fahrterkennung: am 01.09. stand dort "Geparkt seit 2 Tg. 16 Std.", waehrend am Vorabend 7 km gefahren wurden - die Fahrt fehlte im Bestand, weil trip_status festhing. Der Koordinator merkt sich jetzt den Zeitpunkt, zu dem die Zuendung zuletzt ausging, in der Zeit des Geraets. Er liegt im Laufzeit-Store neben fahrt_start_ts und ueberlebt einen Neustart. Kein Rueckfall auf die Fahrtenliste: null heisst unbekannt und wird auch so angezeigt - ausdrueckliche Ansage des Eigentuemers, eine falsche Zahl ist schlechter als keine. Beim Ausliefern fiel derselbe Neustart-Fehler auf wie bei der Phantomfahrt: der Zuhoerer las die Registrierung der Entitaet als Wechsel und stempelte den Parkbeginn bei jedem Neustart neu. if alt is None: return behebt es. Merkposten fuer dieses Projekt: jeder neue Zustandszuhoerer braucht diese Pruefung. VERIFIZIERT in audi_ha_test: Neustart laesst 09:34:15 unveraendert; Zuendung an -> null; Zuendung aus mit Geraetezeit von vor 40 Minuten -> 09:04:57 statt jetzt. Companion-App gleichgezogen, tsc --noEmit sauber, 165/165 Tests gruen. NOTIERT, NICHT GEBAUT: der GNSS-Zaehler driftet im Stand. Die 0,034 km waren GPS-Rauschen, nicht Aufloesung - der Dongle lag unbewegt. Die GNSS-Zuwaechse brauchen deshalb ein Bewegungstor, bevor sie summiert werden duerfen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,6 +109,8 @@ class Koordinator:
|
||||
self.fahrt_start_ts: datetime.datetime | None = None
|
||||
self.tiefststand_pct: float | None = None
|
||||
self.tiefststand_liter: float | None = None
|
||||
# Seit wann das Fahrzeug steht (Zeit des Geraets). None = unbekannt.
|
||||
self.geparkt_seit_ts: datetime.datetime | None = None
|
||||
# Ergebnis des letzten "Auf Update prüfen"/"Update installieren" -
|
||||
# nur auf Tastendruck gesetzt (siehe dienste.py), nie im normalen
|
||||
# Veröffentlichungs-Takt neu berechnet, damit keine automatischen
|
||||
@@ -242,7 +244,42 @@ class Koordinator:
|
||||
neu = ereignis.data["new_state"]
|
||||
return (neu.state if neu else None, alt.state if alt else None)
|
||||
|
||||
async def _zuendung_angezeigt(self, _ereignis: Event[EventStateChangedData]) -> None:
|
||||
async def _zuendung_angezeigt(self, ereignis: Event[EventStateChangedData]) -> None:
|
||||
"""Die Zündung dient nur der Anzeige - und hält den Parkbeginn fest.
|
||||
|
||||
"Geparkt seit" hing bis 2026-09-01 am Ende der jüngsten Fahrt in der
|
||||
Liste. Das ist keine Aussage über das Parken, sondern über die
|
||||
Fahrterkennung: eine verpasste Fahrt lässt das Fahrzeug seit Tagen
|
||||
stehen, obwohl es gestern unterwegs war (real vorgekommen am
|
||||
31.08.2026). Der Zeitpunkt, zu dem die Zündung zuletzt ausging, ist
|
||||
die direkte Antwort.
|
||||
|
||||
Mit der Gerätezeit, nicht mit der Ankunft: der Datensatz kommt bei
|
||||
niedriger Priorität erst mit der nächsten Übertragung an, trägt aber
|
||||
seinen eigenen Zeitstempel (siehe verlauf.geraetezeit())."""
|
||||
neu, alt = self._zustaende(ereignis)
|
||||
# Kein Vorzustand heisst: die Entitaet taucht gerade erst auf (Start von
|
||||
# Home Assistant, Neuladen der Integration). Das ist kein Wechsel der
|
||||
# Zuendung. Ohne diese Pruefung stempelte JEDER Neustart den Parkbeginn
|
||||
# neu - live beobachtet beim Ausliefern von 2026.9.1.6 - und die
|
||||
# Parkdauer begann wieder bei null. Der gespeicherte Wert ueberlebt den
|
||||
# Neustart ohnehin (_laufzeit_laden). Dieselbe Pruefung wie in
|
||||
# fahrterkennung.zuendung_geaendert().
|
||||
if alt is None:
|
||||
await self.fahrzeugstatus_veroeffentlichen()
|
||||
return
|
||||
if neu == "off":
|
||||
zustand = ereignis.data["new_state"]
|
||||
seit = await verlauf.geraetezeit(
|
||||
self.hass,
|
||||
self.zuordnung.werte.MELDEZEIT_SENSOR,
|
||||
zustand.last_updated if zustand else None,
|
||||
datetime.datetime.now(datetime.UTC),
|
||||
)
|
||||
await self.geparkt_seit_setzen(seit)
|
||||
_LOGGER.info("Zündung aus - geparkt seit %s", seit.isoformat())
|
||||
elif neu == "on" and self.geparkt_seit_ts is not None:
|
||||
await self.geparkt_seit_setzen(None)
|
||||
await self.fahrzeugstatus_veroeffentlichen()
|
||||
|
||||
async def _fahrtsignal_geaendert(self, ereignis: Event[EventStateChangedData]) -> None:
|
||||
@@ -291,18 +328,31 @@ class Koordinator:
|
||||
self.fahrt_start_ts = None
|
||||
self.tiefststand_pct = gespeichert.get("tiefststand_pct")
|
||||
self.tiefststand_liter = gespeichert.get("tiefststand_liter")
|
||||
roh = gespeichert.get("geparkt_seit_ts")
|
||||
if roh:
|
||||
try:
|
||||
self.geparkt_seit_ts = datetime.datetime.fromisoformat(roh)
|
||||
except ValueError:
|
||||
self.geparkt_seit_ts = None
|
||||
|
||||
async def _laufzeit_sichern(self) -> None:
|
||||
await self._store.async_save({
|
||||
"fahrt_start_ts": self.fahrt_start_ts.isoformat() if self.fahrt_start_ts else None,
|
||||
"tiefststand_pct": self.tiefststand_pct,
|
||||
"tiefststand_liter": self.tiefststand_liter,
|
||||
"geparkt_seit_ts": (
|
||||
self.geparkt_seit_ts.isoformat() if self.geparkt_seit_ts else None
|
||||
),
|
||||
})
|
||||
|
||||
async def fahrt_start_setzen(self, ts: datetime.datetime | None) -> None:
|
||||
self.fahrt_start_ts = ts
|
||||
await self._laufzeit_sichern()
|
||||
|
||||
async def geparkt_seit_setzen(self, ts: datetime.datetime | None) -> None:
|
||||
self.geparkt_seit_ts = ts
|
||||
await self._laufzeit_sichern()
|
||||
|
||||
async def tiefststand_setzen(self, wert: float | None) -> None:
|
||||
self.tiefststand_pct = wert
|
||||
await self._laufzeit_sichern()
|
||||
@@ -359,7 +409,7 @@ class Koordinator:
|
||||
self.setzen(E_ZUORDNUNG, "aktuell", self.zuordnung.aktueller_stand())
|
||||
|
||||
async def fahrzeugstatus_veroeffentlichen(self) -> None:
|
||||
self.setzen(E_FAHRZEUGSTATUS, "aktuell", fahrzeugstatus(self.hass, self.zuordnung.werte))
|
||||
self.setzen(E_FAHRZEUGSTATUS, "aktuell", fahrzeugstatus(self.hass, self.zuordnung.werte, self.geparkt_seit_ts))
|
||||
|
||||
async def beleg_ergebnis_veroeffentlichen(self, daten: dict) -> None:
|
||||
self.setzen(E_BELEG_ERGEBNIS, "aktuell", daten)
|
||||
|
||||
Reference in New Issue
Block a user