356a0bdf7655042db49ee7c3a3b4d90b6175a5e2
16 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
863284e540 |
Hauptuntersuchung: Ableitung aus Erstzulassung und Wartungsplan, drittes Feld entfernt
Gemeldet: Wartungsplan leer, Erstzulassung 01.03.2025, erwartet 01.03.2028 -
gezeigt wurden drei verschiedene Antworten (Uebersicht 01.08.2026, Mein Audi
"August 2026", Service "kein Eintrag im Wartungsplan").
Ursache war das Profilfeld hauptuntersuchung_faellig ("08/2026"), das die
Ableitung ueberstimmte, in keiner Oberflaeche ein Eingabefeld hatte und im
Backend kein Schema. Drei Bildschirme verarbeiteten denselben Wert
verschieden. Das Feld ist samt Lese- und Schreibweg entfernt; es gibt jetzt
zwei Quellen: Wartungsplan + 24 Monate, sonst Erstzulassung + 36 Monate.
Dabei mitbehoben:
* Die Service-Kachel verschluckte abgeleitete Termine, sobald kein
Wartungsplan-Eintrag dahinterstand.
* monatePlus() in der App verlor einen Tag ueber die Zeitumstellung (drei von
fuenf gemessenen Faellen) - betraf Oelwechsel- und Inspektionsprognose
genauso. Das Panel rechnete dort seit jeher richtig.
* Die App verlangte fuer jeden Wartungsplan-Eintrag eine Kilometerangabe. Eine
Hauptuntersuchung ist rein datumsbasiert; ohne km waere der erste HU-Eintrag
ignoriert worden. Ausserdem nahm das Panel den ersten Treffer der Liste, die
App den juengsten - beide nehmen jetzt den juengsten.
* Monatsgenauigkeit ("03/2025") bleibt auf beiden Seiten erhalten.
Neu: paritaet_hu.test.ts vergleicht die App gegen die aus der Panel-Quelle
herausgeschnittenen Originalfunktionen, 15 Faelle. Gesamt 292 App-Tests, 73
Python-Tests mit 231 Untertests, 0 Tracebacks. Live an der Testinstanz auf
allen drei gemeldeten Bildschirmen geprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7f386d19ea |
Geraetezeit statt Ankunftszeit - die Wurzel hinter der 3-km-Fahrt (2026.9.4.1)
Das Fahrtfenster stand seit dem 01.09. in der Gerätezeit, der Verlauf war nach Ankunftszeit sortiert. Zwei Uhren, und das Gerät puffert: was verspätet ankam, fiel aus einem Fenster heraus, in dem es der Sache nach lag. Am 03.09. hat das eine Fahrt gekostet - 26 von 48 GPS-Punkten und 3,0 statt 7 km. verlauf_lesen() stempelt jeden Punkt jetzt mit der Gerätezeit seines Datensatzes. Eine Stelle, an der alle Verbraucher vorbeikommen. Dazu zwei Riegel aus derselben Untersuchung: ein Rückschritt von 43 Metern ist keine Zählerrücksetzung mehr (aus 87 Metern wurden vorher 13,7 km), und das Fahrtende wird auf das letzte Lebenszeichen des Geräts geklemmt - der Nachlauf ist eine Rechnung, kein Messwert. Am echten Recorder nachgerechnet: Tacho 3,0 -> 7,0 km, GNSS 2,952 -> 6,877 km, Route 26 -> 47 Punkte, Ende 23:21:57 -> 23:17:48. Beim ersten Lauf haben zwei Fahrten eine Strecke bekommen, die vorher gar keine hatten. Nicht das Gerät war schuld: es hat lückenlos aufgezeichnet. Die zehn Minuten Funkstille waren eine offene, aber tote TCP-Sitzung (flespi-Log: 703 s, 16 Nachrichten) - kein Funkloch. Begründung und die Empfehlung fürs Gerät stehen in AGENTS.md, Abschnitt CB. Dazu die neun Paritätsbefunde, alle Richtung Panel gelöst - darunter ein unmaskierter Punkt in beiden Codebasen, der aus "vor 3 Tage" ein "vor 3 Tag" machte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b73a8fb334 |
Meldezeit auch nach hinten prüfen - "Geparkt seit 20698 Tg." war die Unix-Epoche
geraetezeit() prüfte nur, ob die Meldezeit in der Zukunft liegt. Ein Sensor, der 0 meldet, rutschte durch, und fromtimestamp(0) ergibt 1970 - auf der realen Instanz sichtbar als "Geparkt seit 20698 Tg. 9 Std. 39 Min.". Neu geraetezeit_plausibel(): nicht aus der Zukunft und nicht älter als MELDEZEIT_RUECKLAUF (365 Tage). Geprüft wird an drei Stellen - beim Auslesen der Gerätezeit, beim Setzen des Parkbeginns und beim LADEN aus dem Laufzeit-Store, denn ein einmal falsch gespeicherter Wert überlebt sonst jedes Update. Fängt auch eine im Setup falsch zugeordnete ID-Entität ab: das flespi-Gerät hat drei ID-Sensoren, deren Namen dem Zeitstempel ähneln, und deren Werte ergeben als Unix-Zeit ebenfalls 1970. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2af5c469d6 |
Ortsnamen aus dem Backend, Verbrauchsfaktor aus dem Tankbeleg, Radzaehler ueber Fahrten
Ortsauflösung serverseitig (geokodierung.py): der Ort steht jetzt in der Fahrt statt im Zwischenspeicher jedes Geräts. Beide Oberflächen fragen nichts mehr ab. Verbrauchskorrektur (verbrauchskorrektur.py): Faktor = Beleg-Liter / Summe der Einzelfahrten, voll zu voll. Statt einer Schranke am Faktor wird der Nenner geprüft - decken die erkannten Fahrten 90-110 % der Tacho-Spanne ab? Ausgelöst beim Schreiben eines Tankvorgangs, nicht erst bei der nächsten Fahrt. Radzähler: summiert die Fahrten des montierten Satzes statt Tacho-Deltas. Der alte Weg hatte Fahrzeugwechsel als gefahrene Strecke verbucht (375.962 km bei einem Tacho von 61.823). Null heißt unbekannt: ein Kilometerstand von 0 oder ein leeres Feld werden zu None normalisiert, statt an sechs Lesestellen als "Tachostand null" zu gelten. Momentanwerte der Sensoren gelten nur für einen Tankvorgang von jetzt. Oberfläche, beide Codebasen: Wertespalte der Fahrtenliste ausgerichtet, Ort -> Ort in "Zuletzt", "Räder" statt "Reifen", "Termin vereinbart" entfernt, Markenlogo 20 % größer, Übersicht-Symbol auf volle Rasterbreite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
78a8017e95 |
Verbrauch: Tankstand ab Fahrtbeginn statt davor (2026.9.1.24)
DER VERBRAUCH WAR SYSTEMATISCH ZU HOCH Der Startwert kam aus wert_bei(), also dem letzten Literstand VOR der Fahrt - und das ist im Stand der Wert vom Ende der VORIGEN Fahrt. An der Fahrt Eichstaett - Adelschlag nachgemessen: 36,4 l um 13:52 (Ende der vorigen Fahrt), 36,2 l um 16:20:49 (erster Datensatz der neuen). In der Standzeit dazwischen ist niemand gefahren; diese 0,2 l Setzung wurden der neuen Fahrt zugerechnet. alt: 36,4 - 35,6 = 0,8 l auf 6,896 km -> 11,6 l/100 km neu: 36,2 - 35,6 = 0,6 l auf 6,896 km -> 8,7 l/100 km Neu wert_ab() in verlauf.py: der erste Wert AB dem Zeitpunkt. Fuer einen ZAEHLER ist "zuletzt davor" richtig (der Kilometerstand aendert sich im Stand nicht), fuer einen gemessenen FUELLSTAND nicht - der driftet. Das Fahrtende bleibt bei wert_bei(). Livepfad und Rueckblick benutzen beide die neue Funktion. Bereits gerechnete Fahrten behalten ihren Wert: _verbrauch_screenen() fuellt nur fehlende. Die Neuberechnung kommt mit dem Korrekturwert aus den Tankvorgaengen, den der Eigentuemer vorgeschlagen hat. ANZEIGE Hoechstgeschwindigkeit ohne Nachkommastelle. Statuswort raus aus der Fahrtenliste - "vollstaendig" sagt dem Nutzer nichts, und "offen" verspricht Daten, die bei einer laengst abgeschlossenen Fahrt nie mehr kommen; fehlt ein Wert, steht dort ein Strich. Strecke und Verbrauch stehen jetzt in einer Spalte: die Wertspalte wuchs mit dem Inhalt, gemessen 86px gegen 37px, und die Zahlen standen versetzt. Feste Mindestbreite in beiden Oberflaechen, nachgemessen alle Zeilen 92px. Verifiziert: py_compile, Panel als Modul, tsc --noEmit sauber, 165/165 Tests, wert_ab() gegen vier Randfaelle, im Browser nachgesehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9d70192da3 |
Audit: Livepfad und Rueckblick messen wieder dasselbe (2026.9.1.17)
BEFUND 1 (behoben): dieselbe Fahrt, zwei Strecken screening.py las den Verlauf ueber verlauf_lesen(), das den Stand zu Beginn des Fensters mitliefert. historienimport.py schnitt sein Fenster streng heraus und verlor genau diesen Punkt. An der echten Fahrt nachgemessen: 6,896 km gegen 6,816 km fuer denselben Zeitraum. Neu verlauf.zaehlerstrecke(punkte, start, ende) - der Anker ist der letzte Datensatz am oder vor dem Beginn, dieselbe Ueberlegung wie bei wert_bei(). Beide Wege schneiden jetzt durch dieselbe Funktion. Nachgewiesen: Rueckblick 6,896, Livepfad 6,896. Dritter Fall dieser Art nach UNPLAUSIBLE_KMH und MINDESTDAUER_S - und ich hatte ihn am selben Tag selbst eingebaut. BEFUND 2 (behoben): STANDARDWERTE gingen unnoetig ueber die Leitung. zuordnung.py schickte sie mit jeder Katalogantwort; gelesen hat sie seit dem Entfernen des Zuruecksetzen-Knopfes niemand mehr. Die Konstante bleibt, sie traegt intern die Vorgabewerte und leitet SCHLUESSEL ab. BEFUND 3 und 4 bleiben offen und gehoeren dem Eigentuemer: die vier Tage alte Reichweite auf der Uebersicht (RANGE_SENSOR besser leer lassen) und die Nullfahrt-Regel, die nur der Rueckblick kennt - im Livepfad hiesse sie, einen bereits gespeicherten Datensatz automatisch zu loeschen. SAUBER: 24 Backend-Dateien py_compile, Panel als Modul geparst, tsc --noEmit und vite build sauber, 165/165 Tests, 27 Katalogeintraege gegen 27 Dataclass-Felder ohne Abweichung, jedes Listenfeld mit so vielen Beispielen wie Positionen, keine verwaisten Verweise, in der Konsole nur das bekannte ServiceWorker-Rauschen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
09c7461892 |
Rueckblick misst auf Meter, Streckenwahl gemeinsam (2026.9.1.14)
Der erste Wurf (2026.9.1.12) verwarf jedes Importfenster mit distanz == 0. Zu grob: seit der GNSS-Verfeinerung messen wir Meter, und eine Fahrt von 400 Metern steht im CAN-Wert als Null. Der Eigentuemer hat es auf den Punkt gebracht - "0,0 moechte ich nicht, ab 0,1 schon". Der Rueckblick liest jetzt ebenfalls den GNSS-Zaehler und entscheidet auf eine Nachkommastelle. Dabei stand die Toleranzlogik kurz doppelt im Code - in screening.py und in historienimport.py. Genau die Doppelung, die dieses Projekt bei UNPLAUSIBLE_KMH und MINDESTDAUER_S schon einmal teuer bezahlt hat. Sie liegt jetzt gemeinsam in verlauf.py: strecke_waehlen(grob, fein) - die feine Zahl gilt, solange sie in der Rundungsunschaerfe des Ankers liegt, oder wenn es keinen Anker gibt. ist_gefahren(distanz) - ab 0,1 km ja. Eine unbekannte Strecke gilt als gefahren; nur die gemessene Null ist ein Nein. VERIFIZIERT: 13 Faelle gegen beide Funktionen, darunter die zwei echten Fahrten, die 400-Meter-Fahrt, die 100-Meter-Untergrenze, 40 Meter, fehlender Anker, fehlender GNSS-Wert, gedrifteter Zaehler und beide Seiten der Grenze. Import live: 1 Fenster uebersprungen, null 0-km-Fahrten im Bestand. Livepfad live: vier alte Fahrten korrekt abgelehnt. NICHT live gezeigt: ein Fenster mit 0,1-0,9 km, das der Import nun behaelt - der Recorder enthaelt kein geschlossenes Fenster dieser Groesse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
af83805c34 |
Fahrtstrecke auf 100 m: CAN als Anker, GNSS als Nachkommastelle (2026.9.1.10)
Zwei echte Fahrten am 01.09.2026 haben die Datenform geliefert, auf die 2026.9.1.5 gewartet hat. strecke_aus_zaehler() summiert die Zuwaechse des geraeteeigenen Kilometerzaehlers und behandelt einen Ruecksprung als Ruecksetzung. Weder der rohe Zaehler noch die Teilstrecken taugen allein: der Zaehler verliert bei einer Ruecksetzung alles Vorherige (Fahrt 1: 0,415 km), die Teilstrecken verlieren einzelne Datensaetze (Fahrt 2: 4 von 50 null, 0,2 km zu wenig). An jedem Datensatz sind beide identisch - sie gehen nur verschieden kaputt. _gnss_verfeinern() ersetzt die grobe Strecke nur, wenn die feine innerhalb der Rundungsunschaerfe des Ankers liegt (GNSS_TOLERANZ_KM = 1.0; beide Enden des CAN-Werts sind auf ganze Kilometer gerundet). Sonst behaelt der Fahrzeugwert recht. VERIFIZIERT gegen die echten Fahrten: - Fahrt 1 (mit Ruecksetzung): 6,958 km, Google Maps sagt 7,1 - Fahrt 2 (sauber): 6,816 km - live: 'Strecke auf 6.896 km verfeinert (Kilometerstand sagte 7.0 km)' - drei aeltere Fahrten korrekt abgelehnt (209178 km gegen 21 km Anker) - sechs Randfaelle: zwei Ruecksetzungen, ein Punkt, leer, unlesbare Werte Nebenbei bestaetigt: NACHLAUF_S = 900 (Zuendung aus 16:33:39, Trip-Signal aus 16:48:44, gespeichertes Ende 16:33:36); der Rueckwaertssprung-Schutz griff live beim Fahrzeugwechsel (-147361 km verworfen, Fahrt blieb offen); die RPM-Zuendung prellt nicht; das Bewegungstor meldet wieder Stillstand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4cc91c461b |
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> |
||
|
|
9b0e390dfd |
Audit Panel/iOS: sechs Befunde behoben, Zuendung aufs Trip-Signal (2026.8.31.5)
ZUENDUNG_SENSOR liegt jetzt auf dem Trip-Signal des FMM003 statt auf dem rohen, prellenden Zuendungseingang. Damit kommt die Pausentoleranz vom Geraet - eine Fahrt beginnt erst bei Zuendung UND Bewegung UND Start Speed. MINDESTDAUER_S wandert nach verlauf.py und gilt jetzt auch im Livepfad. Vorher verwarf nur der Import Zuendphasen unter 60 s; live entstanden daraus am 31.08. elf Fahrten mit 0 km, zwei davon mit null Sekunden Dauer. Das Panel erfand einen Literpreis von 0,00 EUR, wenn die Kosten noch nicht feststanden (null/liter ist 0 in JavaScript) - neue Hilfsfunktion literpreis() prueft beides, wie die App seit jeher. schnittpreis() teilte ohne Nennerpruefung und konnte "NaN" oder "unendlich" anzeigen. Der Setup-Dialog ist wirklich modal: die Tab-Leiste hatte einen eigenen Zuhoerer vor der Sperre und liess einen Tabwechsel bei offenem Fenster zu. Verwaister Code entfernt: drei Funktionen und vier Regeln im Panel, 20 Regeln in der App. Offen bleibt allein die leere Erstzulassung - eine Angabe, keine Aenderung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4af38d7e65 |
Fahrten, Statistik, Trip-Timer (2026.8.31.3)
Der 15-Minuten-Timer war doppelt: der FMM003 wartet laut Konfiguration (Trip \ Odometer, Ignition OFF Timeout) selbst 900 s, die App noch einmal 15 Minuten. Zusammen eine halbe Stunde. Die Pausenregel ist damit entfallen - in der Live-Erkennung, im Historienimport und in beiden Oberflaechen. Der Schwellwert "ab wann ist es ein Parkplatz" hing an derselben Einstellung, hat damit aber nichts zu tun und steht jetzt als eigene Zahl. Hoechst- und Durchschnittsgeschwindigkeit je Fahrt. Der Durchschnitt folgt aus Strecke und Dauer, vmax aus der neuen Rolle GESCHWINDIGKEIT_SENSOR - laut Konfiguration liest das Geraet die Geschwindigkeit vom OBD/CAN. Es ist der groesste gemeldete Wert, nicht die tatsaechliche Spitze: alle zehn Sekunden ein Datensatz. So ist es auch beschriftet. Der Langzeitverbrauch war um einen ganzen Tankinhalt zu hoch. Gemessen wird die Strecke ZWISCHEN erstem und letztem Tankstop; verbraucht wurde darauf, was ab dem ZWEITEN hineinkam - der erste fuellte die Strecke davor. Bei 13 Tankvorgaengen rund 8 Prozent, im Testfall 16,7 statt 8,3 l/100 km. Der Test hatte die falsche Rechnung festgeschrieben und ist mitkorrigiert. Eine negative Strecke (falscher Kilometerstand an einem Tankvorgang) gilt jetzt als unplausibel statt als Null ohne Erklaerung. Verbrauch je Fahrt bekommt Grenzen: am Sensor nachgemessen loest can_fuel_volume 0,1 l auf, ein Schritt entspricht also 10/Strecke l/100 km Fehler. Unter 3 km sagt die Differenz nichts mehr, ueber 60 l/100 km ist es kein Verbrauch. Statistik: zusaetzlich "Absolut", und die Einheit steht jetzt in eckigen Klammern an der Rubrik statt vier Mal am Zeitraum. Fuenf Spalten passen auf einem Telefon nicht nebeneinander, das Raster bricht um. Radfoto in Reifen war ein reines <Bild> - Ersetzen und Loeschen von dort aus gar nicht erreichbar. Jetzt BildMitMenue wie im Panel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
90fff7b305 |
Vollaudit: sechs echte Fehler in Backend, Panel und companion-app behoben
- companion-app Batterie.tsx: Generatorspannung zeigte sich faelschlich als Ruhespannung/verzerrte den SOH-Trend, Panel-Filter (AGM_RUHE_MAX_V) fehlte - Manuell angelegte Fahrten/Tankvorgaenge trugen naive Zeitstempel und wurden von der Import-Dublettenpruefung stillschweigend uebersprungen; neue gemeinsame zeit_normalisiert() in verlauf.py schliesst die Luecke - Batteriespannungsverlauf fehlte im Backup (sicherung.py) - Tankvorgangs-Import verlor stillschweigend aeltere Tankvorgaenge vor Beginn der Litersensor-Historie; laeuft jetzt zweigleisig (Prozent + Liter) - Panel-Statistikseite behauptete faelschlich, der Verbrauch je Fahrt komme vom Fahrzeug (OBD) - ist eine Naeherung aus dem Tankfuellstand - companion-app Statistik.tsx: Arbeitsweg-Segment war noch rot statt neutral Version 2026.8.27.19, OTA-Buendel neu gebaut, im Testcontainer verifiziert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
172db54e7a |
Statistik-Icon-Groesse, Batteriediagramm-Ueberarbeitung, Temperatur-Kopplung mit 300s-Fenster, letzte gueltige Spannung als Fallback
- Statistik-Tab-Icon per zentrierter Stauchung an die Fuellflaeche der anderen Tab-Icons angeglichen (Panel + companion-app), auf Nutzerwunsch anschliessend 10% groesser. - Batteriediagramm neu gezeichnet: dynamische viewBox (1 Einheit = 1 Pixel, kein preserveAspectRatio-Verzerren mehr), ein Punkt je Ruhespannungsmessung statt Datumsbeschriftung, Tageshoechstwert nur noch im Tooltip. Generator- spannungen (> AGM_RUHE_MAX_V = 13,0 V, vom Nutzer festgelegt) bleiben aus dem Diagramm aussen vor; der SOC-Kurve-Eckwert "100% / voll" bleibt bei den ursprünglich recherchierten 12,8 V. companion-app auf dieselbe lineare SOC-Interpolation umgestellt (vorher eine abweichende Stufenkurve). - Außentemperatur wird jetzt auch beim Batterieverlauf-Import nachgetragen (vorher nur live) - Kopplung an die naechstgelegene Messung innerhalb NEBENWERT_MAX_ABSTAND_S (verlauf.py), vom Nutzer nach Live-Daten-Analyse auf 300s festgelegt. Merge-Logik in ablage.py ergaenzt: ein erneuter Import kann eine zuvor fehlende Temperatur jetzt tatsaechlich nachtragen, auch wenn sich der Tagesminimalwert selbst nicht aendert. - "Mein Audi"/Zustand zeigt bei unplausibler Live-Messung (z. B. Dongle offline) die zuletzt gemessene Spannung statt "unbekannt". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
80d73e8afd |
Fahrten: Verbrauch-Näherung, 0V-Zustandsanzeige gefiltert, Plausibilitätsgrenze für die Live-Vervollständigung
Verbrauch (l/100km) war bislang totes Schema - kein Codepfad füllte verbrauch_l_100km je. Jetzt aus der Literstand-Differenz (TANK_LITER_SENSOR) über die Distanz genähert, live und beim Import, in beiden Frontends. Die "Zustand"-Kachel zeigte die Batteriespannung ungefiltert direkt vom Sensor, unabhängig von der Plausibilitätsgrenze der Verlaufsaufzeichnung - ein Sensorausreißer (0V) zeigte sich dort weiterhin, obwohl die Messwertliste ihn längst verwarf. Dieselbe Grenze gilt jetzt auch für diesen Anzeigepfad. Reale Fahrtendaten zeigten eine Fahrt mit 22km in 67s (~1180 km/h) - die Live-Vervollständigung (screening.py) hatte anders als der Import keine Plausibilitätsprüfung der Durchschnittsgeschwindigkeit. Jetzt gemeinsam in verlauf.py (UNPLAUSIBLE_KMH/durchschnitt_kmh) für beide Pfade. Dabei einen zweiten echten Bug gefunden: _fahrt_screenen() zog sein Ergebnis nie ins In-Memory-Objekt nach (nur in die Ablage) - eine im selben Durchlauf gerade erst ermittelte Distanz blieb für spätere Schritte (z. B. Verbrauch) bis zum nächsten Screening unsichtbar. Beide Stellen jetzt behoben. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
f337820fc8 |
Batteriespannung: 8V-Plausibilitätsgrenze; Fahrten: echte Start-/Zielposition und Streckenlinie
Batteriespannung: Werte unter 8V (Sensor-/Verbindungsfehler, nicht physikalisch
plausibel für eine 12V-Bleibatterie) werden nicht mehr erfasst - live und beim
Import. "Neue Räder anlegen"-Knopf sitzt jetzt auf derselben Zeile wie "Montiert".
Fahrten: start_lat/-lon, end_lat/-lon und route wurden bisher nur beim
rückwirkenden Import befüllt, nie bei live erkannten Fahrten (dem Normalfall) -
Screening trägt sie jetzt aus dem GPS-Verlauf nach, unabhängig vom
Kilometerstand-Status. fakeTrack() (eine erfundene Linie) ist entfernt, die
Karte zeichnet jetzt die echte Route oder eine ehrliche Gerade zwischen den
bekannten Punkten. CARTOs anonyme Kartenkacheln verlangen inzwischen einen
API-Schlüssel ("API key required" auf jeder Karte in beiden Apps) - auf
schlüssellose OpenStreetMap-Kacheln umgestellt. Start/Ziel zeigen jetzt Datum
und Uhrzeit über der Adresse; die fehlerhafte "Status"-Zeile ist entfernt.
Batteriespannungs-Diagramm nutzt auf großen Bildschirmen die volle
Spaltenbreite statt einer festen 400px-Deckelung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
d8b12da36d |
pyscript-Backend zur echten HA-Integration umgebaut (HACS-fähig)
Das Backend liegt jetzt als custom_components/audi_dashboard/ vor - eine normale Home-Assistant-Integration mit Config-Flow, einer sensor-Plattform und 18 Diensten. Damit ist die App über HACS installierbar; bis das Repo auf GitHub gespiegelt ist (HACS spricht ausschließlich mit GitHub), installiert homeassistant/installationspaket/install.ps1 denselben Ordner ohne HACS. Fünf Installationsschritte entfallen ersatzlos: der pyscript:-Block, der panel_custom:-Block, das Kopieren der Oberfläche nach www/, das langlebige Zugriffstoken (der Verlauf wird direkt über die recorder-API gelesen) und "pip install pypdf" (steht in manifest.json). Das Fahrzeugprofil legt die Integration beim ersten Start aus ihrer Vorlage an. Drei alte Schwächen sind dabei mit erledigt: - Die Nutzlast landet nicht mehr in der Recorder-Datenbank (_unrecorded_attributes - das kann nur eine echte Entität). - Eine laufende Fahrt überlebt einen Neustart (Store statt Arbeitsspeicher); fiel sie während eines Ausfalls ins Ende, schließt nach_neustart_fortsetzen() sie beim letzten aufgezeichneten Zeitpunkt. - Sensor-Zuordnungen wirken sofort - die Zustandsbeobachter werden neu gebunden, der Neustart-Hinweis und der Neustart-Dienst sind weg. Namensvertrag geändert, beide Oberflächen mitgezogen: pyscript.audi_dashboard_x -> sensor.audi_dashboard_x, pyscript.audi_dashboard_y -> audi_dashboard.y. Eine Companion-App vom alten Stand findet nach dem Umstieg nichts mehr und muss neu gebaut werden; das Panel liegt in der Integration und kann nicht driften. Der selbstgebaute Updater entfällt - HACS ist die Update-Mechanik, die Home Assistant kennt. Die Versionierung schrumpft auf eine Quelle: manifest.json. Geprüft am laufenden Testcontainer (Container byteweise identisch mit dem Repo): alle 18 Dienste, Panel, Config-Entry neu laden, Historienimport, echter Shell-Beleg in-process, Neuinstallation im Wegwerf-Container blank mit automatisch nachinstalliertem pypdf. Companion-App: tsc sauber, 112/112 Tests, beide Rauchtests gegen das laufende Backend grün. Belegparser 8/8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |