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 <[email protected]>
This commit is contained in:
2026-09-01 11:52:05 +02:00
co-authored by Claude Opus 5
parent cef11b26f3
commit 553e128066
9 changed files with 227 additions and 18 deletions
+2
View File
@@ -68,6 +68,7 @@ export interface Fahrzeug {
an nur, dass die Zündung an ist. `null` heißt „kein Zündungssensor
zugeordnet", also unbekannt — nicht „steht". */
zuendung: boolean | null
geparktSeit: string | null
standortLat: number | null
standortLon: number | null
standortZeit: string | null
@@ -171,6 +172,7 @@ export function profilZuFahrzeug(profil: Profil, status: Fahrzeugstatus): Fahrze
gesichert: status.gesichert ?? null,
sicherheitscheck: status.sicherheitscheck ?? [],
zuendung: status.zuendung ?? null,
geparktSeit: (status.geparkt_seit as string | null) ?? null,
standortLat: status.standort_lat ?? null,
standortLon: status.standort_lon ?? null,
standortZeit: status.standort_zeit ?? null,
+1
View File
@@ -27,6 +27,7 @@ function fahrzeug(odo: number, modus = "hersteller"): Fahrzeug {
gesichert: null,
sicherheitscheck: [],
zuendung: null,
geparktSeit: null,
standortLat: null,
standortLon: null,
standortZeit: null,
+16 -9
View File
@@ -112,15 +112,22 @@ function dauerSeitText(ts: number | null): string {
damit aber nichts zu tun und bleibt als eigene Zahl stehen. */
const PARKPLATZ_AB_MIN = 15
/* Seit wann das Fahrzeug steht: aus dem Backend, hergeleitet aus dem
Zeitpunkt, zu dem die Zuendung zuletzt ausging (in der Zeit des Geraets).
Bis 2026-09-01 stand hier das Ende der juengsten Fahrt aus der Liste. Das
war keine Aussage ueber das Parken, sondern ueber die Fahrterkennung: eine
verpasste Fahrt laesst das Fahrzeug seit Tagen stehen, obwohl es gestern
unterwegs war. Real vorgekommen - am 31.08.2026 zeigte die Anzeige
"geparkt seit 2 Tg. 16 Std.", waehrend am Vorabend 7 km gefahren wurden.
Kein Rueckfall auf die Fahrtenliste: null heisst unbekannt, und das wird
auch so angezeigt. Eine falsche Zahl ist schlechter als keine. */
function standortZustand(
fahrzeug: Fahrzeug,
fahrten: readonly { ts_end: string }[],
): { faehrt: boolean; unbekannt: boolean; seitTs: number | null; geparkt: boolean } {
let neuesteTs: number | null = null
for (const t of fahrten) {
const ts = new Date(t.ts_end).getTime()
if (!Number.isNaN(ts) && (neuesteTs === null || ts > neuesteTs)) neuesteTs = ts
}
const roh = fahrzeug.geparktSeit ? new Date(fahrzeug.geparktSeit).getTime() : NaN
const neuesteTs: number | null = Number.isNaN(roh) ? null : roh
if (fahrzeug.zuendung === true) return { faehrt: true, unbekannt: false, seitTs: null, geparkt: false }
const minuten = neuesteTs != null ? (Date.now() - neuesteTs) / 60000 : null
return {
@@ -241,7 +248,7 @@ export function StandortVorschau({ geheZu }: { geheZu: () => void }) {
/** Vollbild-Standortansicht — Vorlage: vStandort() im Panel. */
export function Standort() {
const { fahrzeug, einstellungen, fahrten } = useDaten()
const { fahrzeug, einstellungen } = useDaten()
const behaelter = useRef<HTMLDivElement | null>(null)
const kartenRef = useRef<import("leaflet").Map | null>(null)
const fahrzeugMarkerRef = useRef<import("leaflet").Marker | null>(null)
@@ -442,7 +449,7 @@ export function Standort() {
: (positionsFehler ?? "Abstand wird ermittelt …")
const koordinaten = fahrzeugPos ? `${de(fahrzeugPos.lat, 4)}, ${de(fahrzeugPos.lon, 4)}` : ""
const adresseAnzeige = !bekannt ? "Kein GPS-Signal vom Fahrzeug" : (adresse ?? koordinaten)
const zustand = standortZustand(fahrzeug, fahrten)
const zustand = standortZustand(fahrzeug)
const kartenlink = fahrzeugPos
? `https://www.google.com/maps/dir/?api=1&destination=${fahrzeugPos.lat},${fahrzeugPos.lon}`
: null
@@ -584,7 +591,7 @@ export function Standort() {
? "Fahrzustand unbekannt"
: zustand.seitTs != null
? `Geparkt seit ${dauerSeitText(zustand.seitTs)}`
: "Fahrzeug steht"}
: "Fahrzeug steht, Parkdauer unbekannt"}
</span>
</>
)}