44dcb3c9d9b0de1b17527f018142ddda8b5f112d
75 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
44dcb3c9d9 |
Erstzulassung war in der App nicht speicherbar
Einstellungen.tsx fuehrt fuer die Erstzulassung einen eigenen Entwurf neben `entwurf`. Zwei Stellen kannten ihn nicht: speichern() stieg in der ersten Zeile aus, und die Speicherleiste haengt allein an `entwurf` - wer nur die Erstzulassung aenderte, bekam also gar keinen Speichern-Knopf zu sehen und verlor den Wert beim Verlassen der Seite. Damit blieb auch die Hauptuntersuchung leer, die daraus abgeleitet wird. Das Panel speichert an dieser Stelle sofort und war nie betroffen. Dazu: * Platzhalter beider Felder war MM/JJJJ, obwohl ein voller Tag gemeint ist - jetzt TT.MM.JJJJ. Die Monatsform bleibt lesbar, damit gespeicherte Werte wie "08/2026" gueltig bleiben. * Das Tagesmuster nimmt jetzt Punkt oder Bindestrich, in beiden Codebasen wortgleich. "01-03-2025" ergab vorher still nichts. Unmoegliche Daten werden weiterhin abgewiesen, die ISO-Form nicht verwechselt. Geprueft am laufenden System ueber die ganze Kette: eintragen, speichern, Profildatei, dann App-Service, Panel-Service und Panel-Mein-Audi mit uebereinstimmend 15.06.2027. 299 Tests gruen, 0 Tracebacks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e9c16325cc |
Musterseite verworfen, Zahnrad-Regression behoben, Fotomenue als Aktionsblatt
Musterseite entfernt (companion-app/muster, vite.muster.config.ts, /config/www/dmmuster). Ansage des Eigentuemers: sie fuehrt nur zu neuen Fehlerquellen. Ausloeser war ein Befund, den ich als App-Fehler gemeldet hatte - Ringe und Typenschild schwarz auf schwarz - und der nur dort bestand. Behoben: * Das Zahnrad im Autohaus-Kasten hatte seine Ecke verlassen (58/288 statt 8/8). Ursache war mein HIG-Durchgang von gestern: .zahnrad kam in die Gruppe fuer die 44x44-Trefferflaeche und bekam damit position:relative, was das absolute aus dem Basisblatt ueberschrieb. Die Auflage war ueberfluessig - .zahnrad ist dort schon 44x44. * Das Fotomenue hing mit position:absolute an der Kachel statt am Bildschirm und lag bei der hohen Raeder-Kachel ausserhalb des Sichtfelds; einen Abbrechen-Knopf hatte es nie. Das Panel benutzt jetzt dasselbe Aktionsblatt wie die App. .bildmenu ist samt Zustand, Markup, totem Handler und CSS entfernt. * Der Blattkopf las sich als dritte Auswahl (linksbuendig, 15px, --fg). Jetzt zentriert, 13px, gedaempft - Apples Muster, in beiden Codebasen. * "Anstehende Termine" stand 5px ueber "Oelwechsel" und wirkte als dessen Beischrift. Entfernt. * Wartungsplan-Formular: Art nach oben, Datum 124px statt Browser-Vorgabe, Werkstatt ueber die volle Zeile (218 -> 306px), Kosten 116px. Zwei Erklaertexte entfernt. * Thema folgt jetzt einer Systemumstellung im laufenden Betrieb. Vorher las es prefers-color-scheme genau einmal beim Laden. Drei Tests, die ohne die Behebung nachweislich fallen. Geprueft: 295 App-Tests, Panel node --check, 0 Tracebacks, alle Aenderungen live an der Testinstanz gemessen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
5621b818cc |
flespi: echtes Lesen statt Zwischenspeicher, und kein Gleichstand ohne Grundlage
Der Waechter meldete am 04.09.2026 "stimmt ueberein" fuer
trip_scenario.ign_off_timeout: 900 gegen unsere Konstante NACHLAUF_S = 900.
Das Geraet hat dort 0 - das Trip-Szenario ist abgeschaltet. flespis
Zwischenspeicher trug den Stand vom 01.09. 13:15, dreieinhalb Tage alt.
Der Eigentuemer hat es aufgedeckt: "die gelesenen werte sind veraltet".
Zwei Aenderungen:
1. "Jetzt lesen" leert erst den Zwischenspeicher der ueberwachten
Einstellungen (DELETE /gw/devices/{id}/settings/{name} - die
API-Entsprechung des Panel-Knopfes "clear cache and synchronize"; loescht
den gespeicherten Wert, nicht den im Geraet) und holt dann neu.
Einstellungen mit einem AUSSTEHENDEN Wert werden uebersprungen: dasselbe
DELETE wuerde ihn verwerfen, und die Aenderung kaeme nie an - wie
1003/1004, die am 04.09. acht Stunden in der Warteschlange standen.
2. `abweichung` ist dreiwertig: true, false und **null (kein Urteil)**. Null
steht dort, wo ein Vergleich nichts aussagt - der Wert wurde nie vom
Geraet bestaetigt, oder es ist gerade eine Aenderung unterwegs. Dazu
traegt jede Zeile `gemeldet_am` (flespis `updated`), und beide
Oberflaechen zeigen es an: "bestaetigt 01.09.2026 (4 T. alt)" bzw.
"nie bestaetigt".
Ein stiller Gleichstand mit einem veralteten Wert ist schlimmer als gar kein
Vergleich: er behauptet Sicherheit, wo keine ist.
tsc sauber, 271 Tests, vite build sauber, Panel als Modul geparst,
py_compile sauber, audi_ha_test auf 2026.9.4.26 ohne Traceback.
|
||
|
|
b0ec8b4982 |
Pruefdurchgang ueber alle 26 Bildschirme - fuenf Fehler behoben, HIG nachgezogen
Gemessen statt geschaut: eine Pruefroutine lief auf jedem Bildschirm und
pruefte Ueberlauf, Tippziele, abgeschnittenen Text, Bilder ohne Quelle und
WCAG-Kontrast fuer jeden Textknoten. Dazu die Live-App mit echten Daten, die
Musterseite fuer Leerzustaende und das Panel zum Abgleich.
1. Deutsche Datumsangaben wurden falsch gelesen. new Date("01.03.2025")
liest amerikanisch: Tage bis 12 wurden still vertauscht, ab Tag 13 fiel
der Wert ganz weg. Die Erstzulassung stand auf zwei Bildschirmen
unterschiedlich da. alsZeitpunkt() erkennt jetzt ISO, TT.MM.JJJJ und
MM/JJJJ, weist unmoegliche Daten ab und fuehrt die Genauigkeit mit -
aus "08/2026" wird "August 2026", kein erfundener Erster.
2. Die Hauptuntersuchung war in beiden Oberflaechen unerreichbar. Das Panel
leitete sie aus der Erstzulassung ab, aber nur bei MM/JJJJ, und benutzte
den eingetragenen Wert gar nicht. Jetzt beide: eingetragene Faelligkeit
vor Servicebuch vor Erstzulassung + 24 Monate.
3. Die Tankstellenmarke stand zweimal da, wenn der Name kein Komma hat
("Shell München Ost"). ohneMarkeVorn() nimmt sie vorn ab.
4. Bilder wurden geholt, obwohl beide wussten, dass es sie nicht gibt -
fuenf 404 fuer dieselbe Datei in einem Ladevorgang. Jetzt gar keine
Adresse bei Stand 0; nachgemessen 4 Anfragen, alle 200.
5. Ein Bildelement ohne Quelle zeigte das kaputte Bildsymbol, und onerror
greift dort nicht: ohne src gibt es keinen Ladeversuch.
Dazu: leere Klammern beim Steuersatz, leere graue Kachel bei leerer
Leistungsgruppe, Umbruch auf dem Einrichtungsbildschirm, drei
Leerdarstellungen in einer Kachel, fehlende Grundschrift.
Apple HIG: Kontrast war an einer Stelle 3,18 statt 4,5, weisse Schrift auf
der Loeschflaeche 3,41/3,55. Rot als Schrift und Rot als Flaeche sind jetzt
getrennte Token (--bad / --bad-flaeche), beide Apples systemRed fuer
erhoehten Kontrast. Tippziele: unsichtbares 44x44-Overlay, wo die sichtbare
Groesse Teil des Bildes ist, echte Mindesthoehe, wo das Element Flaeche ist -
Formulare werden dadurch sichtbar hoeher.
Neu auf Wunsch: Wischen in der Bildergalerie (beide Richtungen) und die
HIG-konforme Loeschgeste - ein voller Wisch loescht ohne zweiten Tipp, ab
55 % der Zeilenbreite, mit wachsender roter Flaeche und erhaltener
Rueckfrage. Dabei fiel auf, dass der Zugwert aus dem React-Zustand gelesen
wurde und ein schneller Wisch dadurch verlorenging; er liegt jetzt in einer
Referenz.
Paritaet: alle 26 Routen und Titel decken sich, Fahrzeugstatus zeilengleich,
zwei ungeplante Abweichungen (Datumsformatierung, Herkunft der
Hauptuntersuchung) geschlossen.
tsc sauber, 271 Tests, vite build sauber, Design-System gebaut, Panel als
Modul geparst, audi_ha_test auf 2026.9.4.23 ohne Traceback. Live nachgemessen:
Datum auf beiden Bildschirmen gleich, keine 404 mehr, Zurueck-Pfeil sichtbar
34x34 und treffbar 44x44, Galerie wischt in beide Richtungen, voller Wisch
loest die Rueckfrage aus, keine Kontrast-Unterschreitung mehr.
|
||
|
|
bdbdb4a010 |
Tankstellenmarke als eigenes Feld, Belegfelder in der App richtig zugeordnet
Die Marke steht auf jedem Beleg, war aber nirgends gespeichert: der Parser erkennt sie seit dem 16.08.2026, faltete sie aber nur in station_name. Fuer jeden Beleg, den eine aeltere Fassung eingelesen hat, blieb dort der Betreibername stehen und die Marke war danach nicht mehr zu holen. - shell_beleg_parser: station_brand als eigenes Feld aus beiden Parserwegen, dazu marke_aus_text()/marke_aus_pdf() - sie lesen nur den Belegkopf und haengen nicht am vollstaendigen Einlesen. - belege.marken_nachtragen(): traegt die Marke einmal beim Start aus der abgelegten Belegdatei nach. Nur wo das Feld gar nicht vorkommt und die Datei liegt; ein einmal eingetragenes Feld wird nie ueberschrieben. - Panel und App: die gespeicherte Marke geht vor, geraten wird nur, wo keine da ist. Ein Teil, der fuer sich genommen eine Kopfmarke ist, taugt zudem nie als Ort. Dazu Punkt 5 der Meldung vom 04.09.2026: ein eingelesener Beleg fuellte nur Datum und Uhrzeit. Der Parser las ihn immer vollstaendig - die App fragte liter/kosten/station/ersparnis/kraftstoff ab, veroeffentlicht werden aber die Namen des Belegs (liters/fuel_total_eur/station_name/discount/fuel_type). Uebereingestimmt hat allein ts. Die Zuordnung steht jetzt als belegFormularwerte() in daten/belegentwurf.ts und wird gegen die echte Nutzlast dieses Belegs geprueft. tsc sauber, 258 Tests (die drei neuen Marken-Tests gegen den alten Stand als scheiternd nachgewiesen), vite build sauber, Panel als Modul geparst, Parser-Suite 11 Tests gegen elf echte Belege. Panel und App liefern fuer elf Faelle byteweise dasselbe. Live in audi_ha_test auf 2026.9.4.21 ohne Traceback: Uebersicht "Shell, Nuernberger Str., Ansbach", Einzelbeleg zweizeilig mit Marke, und der echte geteilte Beleg fuellt durchs Backend das ganze Formular. |
||
|
|
a99ae432fc |
Tankstellen-Nadel, doppeltes Tanken-Symbol, Tankstellenname, packageClassList
Fuenf Meldungen des Eigentuemers, vier davon behoben: 1. Tankstellen-Nadel war bei 32 px ein dunkler Fleck (poi zeichnet nur einen Ring). Gefuellter Punkt in currentColor zwischen Silhouette und Symbol - die Geometrie stand im Pfad. Rot wurde ausdruecklich abgelehnt, die Umsetzung aendert keine Farbe. 2. Tanken-Symbol im Standort-Blatt wurde gefuellt UND umrandet, weil das CI-Symbol zusaetzlich stroke-Attribute mitbekam. Jetzt ueber ciSVG wie das Parkplatz-Symbol daneben; in der App dafuer imRaster an SymbolTanken (der 0,84-Faktor gilt nur in der Reiterleiste). 3. Tankstellenname: der Bestand hat zwei Bauformen - aeltere Belege tragen den Betreiber in station_name und die Anschrift daneben. Neu tankstelleTeile() liest beide Felder, entfernt Firmierungen, kuerzt Strassen und trennt die Hausnummer auch ohne Leerzeichen. Uebersicht: Marke, Strasse, Ort. Einzelbeleg: zwei Zeilen. adresseTeilen() hat keinen Aufrufer mehr und ist entfernt. 4. Zwischenablage und Kalendereintrag hatten denselben Grund: Capacitor 8 registriert nur, was in packageClassList steht, und cap sync traegt dort ausschliesslich npm-Pakete ein. Beide app-eigenen Plugins lagen im Programm und wurden nie registriert. ios-teilen-einrichten.mjs traegt sie jetzt nach, ios-signieren.sh bricht ab, wenn sie im fertigen .ipa fehlen. 5. Geteilter Beleg nur mit Datum und Uhrzeit bleibt offen - der Weg nutzt denselben belegLesen()-Pfad wie eine gewaehlte Datei, es fehlt der konkrete Beleg oder die Protokollzeile. tsc sauber, 246 Tests, vite build sauber, Panel als Modul geparst, audi_ha_test auf 2026.9.4.20 ohne Traceback. Panel und App liefern fuer die Tankstelle byteweise dasselbe. |
||
|
|
68732aa10f |
Bilder: der Cache-Brecher haengt am Foto statt an der Startzeit
Beide Oberflaechen haengten Date.now() an jede Bildadresse - richtig gegen ein veraltetes Foto (31 Tage Cache-Vorgabe unter /local/), aber die Adresse aendert sich damit bei JEDEM Start, der Zwischenspeicher greift zwischen zwei Starts also nie. Mit dem Vorladen waeren das 5,3 MB je Start gewesen. bilder.staende() liefert jetzt den Zeitstempel je Datei, veroeffentlicht an sensor.audi_dashboard_app_version; eine Bildadresse aendert sich damit genau dann, wenn das Foto ein anderes ist. Ein fehlendes Foto bekommt 0 (dann loest sich auch ein gespeicherter 404 von selbst auf), ein Backend ohne Staende faellt auf das bisherige Verhalten zurueck, und Upload wie Loeschen veroeffentlichen sofort neu. Die App merkt sich den letzten Stand im Browserspeicher: sie malt ihren ersten Bildschirm, bevor die Versionsangabe eintrifft - ohne das Gedaechtnis trug genau dieser Durchlauf noch die Startzeit und holte das Uebersichtsfoto doch wieder bei jedem Start. Live gemessen: Neuladen ohne Aenderung 5.328.771 Bytes Inhalt bei 0 Bytes uebertragen; ein per touch geaendertes Foto wird neu geholt (513.403 Bytes), die anderen nicht; App-Start ohne eine einzige Adresse mit Startzeit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d6f7993504 |
QR-Code aus gespeichertem Bild, stiller Debug-Knopf, HA-Zugang bei den Zugaengen
Der Scanner liest den QR jetzt auch aus einer gespeicherten Bilddatei - in der Testumgebung ohne Kamera der einzige Weg, auf dem Telefon der kuerzere (der Token entsteht am Rechner, das Bildschirmfoto liegt ohnehin auf dem Geraet). Gleicher Leser, gleiche Deutung, nur eine andere Quelle; ohne Kamera entfaellt das schwarze Quadrat. Dabei ein echter Fehler in der ersten Fassung, gefunden an der Musterseite: img.decode() loest bei einem GIF in Chromium nie auf - das Blatt haette ohne Meldung ewig gewartet. Jetzt createImageBitmap, als Rueckfall bewusst das load-Ereignis statt decode(). Debug-Mode ist nur noch ein stiller Textknopf am Seitenende, ohne Kachel und ohne Erlaeuterung; der Zugang zu Home Assistant steht als Akkordeon in der Kachel "Zugaenge" darin. Beides auf Vorgabe des Eigentuemers. Die Musterseite kann jetzt auch die Ersteinrichtung (?seite=einrichtung) - damit ist der ganze Weg ohne echten Token nachgewiesen: selbst erzeugter QR mit Token-Text landet zeichengleich im Feld, einer mit http-Adresse im Adressfeld, ein Bild ohne Code meldet das sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4ab6b9fca5 |
Debug-Mode, eine Version-Kachel, Knoepfe nach HIG, Bilder ohne Verzoegerung (2026.9.4.11)
Debug-Mode: Zugaenge und Dongle stehen nicht mehr verstreut oben in den Einstellungen, sondern zusammen hinter einem Schalter am Seitenende - dazu neu der letzte Datensatz des Dongles (geraet.py). "Letzter Datensatz" heisst dabei: alle Entitaeten des Geraets, deren Aktualisierung hoechstens zwei Sekunden nach der juengsten liegt - die flespi-Integration setzt einen Datensatz in Millisekunden. Angezeigt mit Ankunft, Geraetezeit und dem Rueckstand zwischen beiden. Beim Verifizieren gefunden: app_version_veroeffentlichen() lief nur beim Start und nach einer Aktion, und beim Start haben die Entitaeten des Geraets noch keinen Zustand - die Kachel waere dauerhaft leer geblieben. Laeuft jetzt im Minutentakt mit, ohne Netzaufruf. Ausserdem: - "Version" und "Integration-Update" sind eine Kachel - Speichern/Verwerfen als zwei gleich breite Knoepfe, der bestaetigende gefuellt und rechts; "Verwerfen" war in der App blosser Text - Bilder werden nach dem ersten Zeichnen in der Leerlaufzeit vorgeladen UND dekodiert. Die Verzoegerung beim Seitenwechsel kam nicht vom Netz (31 Tage Cache), sondern vom asynchronen Dekodieren eines frisch erzeugten <img>. 214/214 Tests, Panel als Modul geparst, live gegen audi_ha_test geprueft. |
||
|
|
63a45d4ee2 |
Die .ipa war nicht installierbar, plus QR-Scanner (2026.9.4.8)
Der Erweiterung fehlte CFBundleVersion - eine Pflichtangabe, ohne die iOS
die Installation der ganzen App verweigert ("kann nicht installiert werden").
Verursacht von der Versionsangleichung vom Vortag: das Skript reichte den
Platzhalter $(CURRENT_PROJECT_VERSION) statt einer Zahl weiter, und das per
Skript angelegte Ziel der Erweiterung kennt diese Build-Einstellung nicht.
An den entpackten .ipa nachgemessen, 2026.9.3.3 gegen 2026.9.4.5.
ios-signieren.sh reicht nur noch echte Zahlen weiter, das Gegenlesen der
fertigen .ipa bricht ab statt zu warnen, und abgelegt wird erst danach -
eine Datei, die die Pruefung nicht besteht, darf nicht in auslieferung/
landen.
Dazu:
- Kopfmarke statt Firmierung des Betreibers in der Tankstellen-Zeile
- dritter Suchbegriff: der Name ohne fuehrende Marke. Gemessen: Nominatim
findet "Shell, Pascalstr. 8, Ingolstadt" nicht, "Pascalstr. 8, Ingolstadt"
schon - daran blieb die Belegkarte der realen Instanz leer
- der Tankstellen-Verweis zeigt die Tankstelle, statt eine Route zu rechnen
- Cache-Brecher auf .ipa, Symbolen und manifest.plist
- QR-Scanner fuer den Zugangs-Token bei der Ersteinrichtung (jsQR statt
GoogleMLKit, damit der Xcode-Lauf kein pod install riskiert)
214/214 Tests, Panel als Modul geparst, live gegen audi_ha_test geprueft.
|
||
|
|
43f25e2e0d |
Tankstelle zweizeilig und antippbar, Belegkarte ohne toten Knopf (2026.9.4.5)
Sieben Meldungen des Eigentuemers, beide Codebasen. Karte im Einzelbeleg: "Position laedt nicht" und "der Button funktioniert nicht" waren dieselbe Stelle - ohne aufloesbaren Ort malte das Panel einen beliebigen Ausschnitt und liess den Zentrieren-Knopf fuer immer disabled. Beide zeigen jetzt die Auskunft statt einer Karte und unterscheiden dabei "steht nicht im Beleg" von "findet niemand". Dazu ein echter Paritaetsmangel: die App schlug nur station_address nach, das Panel faellt seit jeher auf den Namen zurueck - von 16 Testbelegen tragen vier eine Anschrift. Der Suchbegriff darf Name und Anschrift NICHT zusammensetzen: gemessen findet Nominatim "Pascalstr. 8, 85057 Ingolstadt", mit dem Betreibernamen davor nichts. Jetzt zwei Kandidaten nacheinander (Anschrift, dann Name); fuer den Kartendienst dagegen beides zusammen, weil Apple und Google Betriebsnamen kennen. Tankstelle steht ueber die volle Kachelbreite, zweizeilig (Tankstelle und Strasse / Ort) und fuehrt beim Tippen in den Standard-Kartendienst - Apple Karten auf Apple-Geraeten, sonst Google Maps. Dieselbe Wahl jetzt auch fuer Fahrzeugstandort und Autohaus. SmartDeal-Ersparnis brach um, weil die dt-Spalte 150,00px breit war und ihr Inhalt 150,20px - zwei Zehntel Pixel, Zeile dadurch 44,8 statt 26,4px hoch. Der Regler "Fahrt beenden" schreibt nicht mehr beim Loslassen: derselbe Wert stellt den Schlaf-Timeout des Dongles, das soll bewusst ausgeloest werden. Speichern/Verwerfen erscheinen nur bei echter Aenderung. Share-Erweiterung: an der ausgelieferten .ipa gemessen trug sie 1.0, die App 2026.9.3.3 - iOS registriert eine Erweiterung mit abweichender Versionsnummer nicht, sie fehlt dann im Teilen-Blatt. ios-signieren.sh schreibt die Version jetzt in beide Ziele und liest die fertige .ipa gegen. Zwischenablage: dritter Weg ueber UIPasteboard.itemProviders, und ein fehlender nativer Teil wird als solcher gemeldet statt als "Kein Zugriff". Am Geraet gesetzt: 1003 Network Ping Timeout 0 -> 60 s, 1004 ACK Type TCP/IP -> AVL. Beide liegen bei flespi als pending bereit. 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> |
||
|
|
4a6c48e81c |
Zwei Textfehler der Dongle-Kachel, an der Sichtpruefung gefunden (2026.9.3.15)
"Gelesen vor 1 Std.." - der Punkt der Abkuerzung und der Satzpunkt standen doppelt. Und im Panel stand noch der Halbsatz "Lesen und Schreiben gehen nur bei laufender Zuendung" vor dem neuen Text - ausgerechnet die Behauptung, die am selben Tag widerlegt wurde; meine Ersetzung hatte nur den hinteren Teil getroffen. Gefunden, weil die Kachel bis dahin nur an den Daten belegt war, nie angesehen. Der erste Blick zeigte dabei eine sechs Fassungen alte Datei aus dem Tab-Zwischenspeicher - die Lehre aus Abschnitt AQ, jetzt dort mit dem Einzeiler zum Mitlesen der geladenen Fassung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2736c3d6e0 |
Audit nach dem Dongle-Umbau: vier Befunde (2026.9.3.13)
1. profil_schreiben awaitete wunsch_uebernehmen und damit bis zu drei HTTP-Runden zu flespi - bei 39 Aufrufstellen von profilSpeichern() im Panel je Feldaenderung. Laeuft jetzt als eigene Aufgabe. 2. Ein gescheiterter Schreibversuch wurde bei jedem Speichern wiederholt, weil der Fehlerstand kein "werte" hat. Er merkt sich jetzt unter "versucht", was gescheitert ist. Dazu: kein zweites Schreiben, wenn der Wert schon als pending bereitliegt. 3. buendelPasst() versprach im Kommentar, ein aelteres Buendel abzulehnen, pruefte aber nur Ungleichheit - deshalb meldete die App "diese Fassung aendert auch Natives", obwohl nur das Buendel nach einem Versionssprung nicht neu gebaut war. Vergleicht jetzt gegen die Serverfassung, drei Regressionstests (der entscheidende gegen den alten Stand rot). Der Text behauptet keine Ursache mehr, die die App nicht kennen kann. 4. Das Regler-Minimum ging heute von 0 auf 1, ein bereits gespeicherter Wert darunter lief ungeprueft durch. Beide Oberflaechen klemmen jetzt auf 1-60. 182/182 Tests, 28 Backend-Dateien py_compile, beide Frontends als Modul geparst, Dienst- und Katalog-Konsistenz in beide Richtungen geprueft, Buendel auf derselben Fassung wie das Manifest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4d4890034a |
Regler stellt den Schlaf-Timeout des Dongles (2026.9.3.10)
Der Regler "Fahrt beenden" ist jetzt eine Zahl fuer zwei Dinge: unsere eigene
Wartezeit bis zum Fahrtende und der Schlaf-Timeout des FMM003 (103). So lange
bleibt der Dongle wach und wartet darauf, dass es gleich weitergeht; danach
schlaeft er. Die 180 s Ignition OFF Delay laufen davor und bleiben unsichtbar -
sie werden nur von der Fahrtdauer abgezogen. Der Regler geht deshalb von 1 bis
60 in Einerschritten; das Geraet kennt kein Timeout 0.
flespi.py liest und schreibt die Geraete-Konfiguration. Drei Annahmen sind an
der echten API gefallen und stehen als Messung im Modulkopf: der Wert liegt in
current (nicht value), die Einstellung heisst sleep_mode mit dem Wert eine Ebene
tiefer unter mode, und ein PUT braucht {"properties": ..., "address": ...}.
Die eigene Auftrags-Warteschlange ist wieder entfallen. Sie war fuer "das Geraet
schlaeft" gebaut - das gilt aber nur fuer das Geraet, nicht fuer die
Schnittstelle: die vollstaendige Konfiguration kam herein, waehrend das Fahrzeug
seit dem Vortag stand. flespi puffert selbst (pending + address=connection), ein
zweites Auftragsbuch waere eine zweite Warteschlange fuer dieselbe Aufgabe.
Gegengelesen wird nach jedem Schreiben; als Erfolg zaehlt current ODER pending -
letzteres ist bei stehendem Fahrzeug der Normalfall.
Live gegen den echten Account belegt: Token sieht genau ein Geraet, 127
Einstellungen bei parkendem Fahrzeug gelesen, Regler 15 geschrieben und als
pending bestaetigt (Nachbarfelder unveraendert), zweiter Neustart ohne erneute
Anfrage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
8c96d9b78e |
Zugaenge: die Dienste-Token aus App und Panel bedienbar (2026.9.3.8)
Die Token liegen seit jeher in entry.options, geschrieben vom Options-Flow unter Einstellungen -> Geraete & Dienste -> Konfigurieren. Der Weg bleibt und ist der Rueckfall, wenn die App den Server nicht erreicht - genau der Fall, in dem ein abgelaufener Token auffaellt. Erreichbar ist er aber nur ueber HAs eigene Weboberflaeche; die iOS-App zeigt keine Konfigurationsdialoge. Die neue Kachel ist die Bedienflaeche dafuer, kein zweiter Speicherort. Der Wert kommt nie zurueck: veroeffentlicht werden nur "gesetzt/nicht gesetzt" und die letzten vier Zeichen (unter zwoelf Zeichen Laenge gar nichts). Auch das Protokoll bekommt ihn nicht, und das Panel leert das Eingabefeld sofort nach dem Absenden. Bewusst NICHT im Fahrzeugprofil: sicherung.py sichert fahrzeugprofil.json, und "Backup exportieren" laedt es als Datei auf das Geraet - ein Token dort wanderte in jede Sicherung und jede weitergegebene Datei. Ein Dienst statt zwei: zugang_setzen(dienst, token), leerer Text loescht. In der App nicht ueber die Warteschlange - ein Stunden spaeter nachgereichter Token ueberschriebe womoeglich einen inzwischen eingetragenen neuen. CONF_FLESPI_TOKEN ist neu und noch ohne Leser; der Flespi-Weg zum Auslesen der Geraetekonfiguration ist damit vorbereitet, aber nicht gebaut. Verifiziert: py_compile auf sechs Backend-Dateien, Panel als Modul geparst, companion-app tsc sauber und 179/179, audi_ha_test auf 2026.9.3.8 sauber gestartet. Live am laufenden Panel der ganze Kreis, Container hinterher wie vorgefunden: Wegwerf-Token gesetzt -> "gesetzt . ...0000", der Wert selbst taucht in den veroeffentlichten Attributen nirgends auf (darauf geprueft), ueber die Sicherheitsabfrage geloescht -> wieder "nicht gesetzt", der Gitea-Token unberuehrt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5ccbfec92d |
Fahrt beenden auf Knopfdruck, Schieberegler, Zuendungspause (2026.9.3.5-.7)
Vier Themen aus einer Sitzung. 1. Die Fahrt endet wieder bei uns statt im Dongle (Abschnitt BW). Der Ignition-OFF-Timeout des FMM003 (900 s) und sein Schlaf-Timeout (ebenfalls 900 s) starten beide beim Zuendungs-Aus und fallen in derselben Sekunde - am 02.09. zweimal beobachtet, einmal ging das Trip-Ende verloren, einmal kam es eine Sekunde vor dem Schlaf an. Ausloeser ist jetzt die Zuendung, die Wartezeit laeuft in Home Assistant. ZUENDUNG_NACHLAUF_S = 180 wird in beiden Wegen abgezogen (ueber das Trip-Signal 1080 s, weil dessen Ende selbst an der verzoegerten Zuendung haengt). 2. Schieberegler, neu in beiden Codebasen. Schrittweite 5 Minuten; der Daumen war im Tagmodus weiss auf weiss und traegt jetzt einen Ring aus --line-strong - ein Token, das genau dort sichtbar ist, wo es gebraucht wird. 3. Knopf "Fahrt beenden" in der Zuletzt-Kachel (Abschnitt BX). Schliesst auf das letzte Lebenszeichen, nicht auf "jetzt", und kennzeichnet das Ende als vorlaeufig. Ein spaet eintreffendes Zuendungs-Aus zieht es nach - innerhalb von sechs Stunden, nur nach vorn, und nur bei einer vorlaeufigen Fahrt. ts_end wandert bewusst NICHT in edited_fields, sonst blockierte der Schutz fuer Handeingaben genau diese Korrektur. 4. Das OTA-Buendel kann auf dem Mac gar nicht entstehen (Abschnitt BV): npm run ota ist eine Windows-PowerShell-Datei, ios-signieren.sh baut ein frisches dist/ und fasst das Buendel nie an. Ausgeliefert war deshalb eine Oberflaeche ohne den Versionshinweis unter richtiger Nummer. Verifiziert: Backend 27/27 (5 Signalwechsel, 14 Zuendungspause, 8 Fahrtende), companion-app tsc sauber und 179/179, Panel als Modul geparst, audi_ha_test auf 2026.9.3.7 sauber gestartet. Live am laufenden Panel und ohne Rueckstand belegt: Wartezeit samt Abbruch, die 180-s-Rechnung, der Regler im Tagmodus und der Knopf von der laufenden Fahrt bis zum verworfenen Kurzvorgang - Fahrten vorher 16, nachher 16. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6016053a92 |
Kalender ueber EventKit, Orte nach dem Import, Fotos verkleinert, Signalsperre (2026.9.3.1-.3)
- Kalendertermine gehen nativ ueber EventKit statt ueber das Teilen-Blatt:
Apples Kalender meldet sich beim System gar nicht als Teilen-Ziel an, ein
anderes Dateiformat haette also nie geholfen (Abschnitt BS).
- Der Rueckblick stoesst jetzt selbst das Screening an, wenn er Fahrten
angelegt hat - sonst blieb eine importierte Fahrt ohne Ort liegen, solange
das Fahrzeug steht (Abschnitt BT).
- Fahrzeugfotos werden vor dem Upload im Browser auf 2000 px/WebP gebracht.
Gemessen: 3.099.022 -> 325.994 Bytes. Damit ist die Nachrichtengrenze der
WebSocket-Verbindung kein Thema mehr ("connection lost" auf der realen
Instanz). Formate, die der Browser weder umwandeln noch anzeigen kann,
werden mit klarer Meldung abgelehnt statt roh gespeichert.
- Zwei Wechsel des Fahrtsignals in derselben Sekunde kosteten eine ganze
Fahrt: das "on" ueberholte den noch laufenden Beende-Vorgang und fiel durch
beide Zweige. Neue asyncio-Sperre plus Regressionstest, der ohne sie
nachweislich rot ist (Abschnitt BU).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
8c95e50554 |
Teilen-Weg repariert, Zwischenablage nativ, Sprung in den Tankvorgang (2026.9.2.24/.25)
BEFUND. Die Uebergabe der Teilen-Erweiterung an die App konnte nie
funktionieren: sie legte den Beleg im Gruppen-Container ab, die App suchte ihn
ueber @capacitor/preferences - und dessen iOS-Code liest IMMER
UserDefaults.standard der App, configure({group}) setzt nur ein
Schluessel-Praefix. Falscher Behaelter, falscher Schluessel, und weil ein
fehlender Eintrag der Normalfall ist, meldete nichts einen Fehler.
UMBAU. Die Erweiterung schreibt das PDF als Datei in den Gruppen-Container und
gibt den Pfad im Aufruf mit; die App liest ihn ueber @capacitor/filesystem
(volle file://-Pfade) und loescht ihn danach. Abgeholt ueber getLaunchUrl()
und appUrlOpen - iOS benutzt beide. Nebenbei entfallen die
Base64-Aufblaehung und die 4-MB-Grenze der UserDefaults.
ZWEI WEITERE FEHLER AUF DEMSELBEN WEG. Ein Beleg zu einem bestehenden
Tankvorgang lief in die 20-Sekunden-Frist, obwohl der Server laengst fertig
war. Und beim Duplikat verriet das Backend nicht, welcher Vorgang gemeint ist
- jetzt kommt vorhandener_tank_id mit, und beide Oberflaechen springen
dorthin. Dazu: nach dem Speichern oeffnet sich der neue Vorgang, und waehrend
gelesen wird, steht "Tankbeleg wird verarbeitet ..." mit Zapfsaeule und
Kreisel im Formular.
ZWISCHENABLAGE. navigator.clipboard.read() gibt nur Text, HTML und Bilder
heraus - ein kopiertes PDF ist dort nie zu bekommen. UIPasteboard kennt die
Grenze nicht: ein kleines eigenes Plugin holt es, auch aus Mail (Anhang als
Verweis, ueber pasteboard.urls mit Sicherheitsbereich).
Der native Teil braucht einen Mac-Lauf; ios-teilen-einrichten.mjs spielt beide
Swift-Dateien bei jedem Bau ein.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
d889353cbe |
Termine ohne Gedaechtnis, Listen nach HIG, zwei zu schmale Felder (2026.9.2.13-.20)
TERMIN. Der Werkstatttermin wanderte bisher ins Fahrzeugprofil, stand als
Merkmal an der Karte und liess sich "verwerfen" - eine zweite Verwaltung neben
dem Kalender. Auf Ansage entfernt: er dient jetzt allein dem Kalendereintrag
"was, wann, bei welcher Werkstatt". Dabei aufgefallen: die App schrieb gar kein
LOCATION in die .ics, obwohl das Panel es seit jeher setzt.
Ohne Speicherung startete das Feld leer ("tt.mm.jjjj", so gemeldet). Es
schlaegt jetzt die Faelligkeit der gewaehlten Art vor, sonst heute - dafuer
liefert service.ts serviceKandidaten(). "Andere" ergaenzt die Auswahl.
BREITEN. Am laufenden Panel gemessen: die vier festen 132px-Datumsfelder
brauchen ab 140px, damit die letzte Ziffer nicht unter dem Kalendersymbol
liegt (jetzt 150px); die Art-Auswahl braucht 178px fuer
"Hauptuntersuchung" (jetzt 190px). In der App war nichts davon kaputt - eine
dort vorsorglich eingebaute Breite ist wieder entfernt.
LISTEN. Fahrten- und Tankliste verloren 58px an tote Breite: 22px Einrueckung
der Monatsebene plus 40px linkes Polster der Zeile. Auf dem Telefon brach
"Eichstaett -> Adelschlag" deshalb um. Apples Richtlinien gruppieren ueber
Abschnittskoepfe statt Einrueckung; die Zeilen stehen jetzt alle auf derselben
Kante (34 statt 96px), der Monat traegt Versalien und Sperrung und liest sich
als Kopf. Beschraenkt auf .liste/.dm-liste - anderswo ist das Polster gewollt.
BILDER. Die Draufsicht ist aus der Galerie genommen (nurStatus), gehoert aber
weiter in die Auswahl der Einstellungen: nur dort laesst sie sich hochladen.
Die Galerie schneidet Fotos nicht mehr an - die Frontansicht verlor unten die
Stossstange.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
38e7731a3d |
Rollende Zeitraeume, zwei Gesten, CI-Symbole und das Screening faellt nach (2026.9.2.8-.12)
Gemeldet vom Eigentuemer an der realen Instanz, in einem Zug abgearbeitet. STATISTIK. "Monat kleiner als Woche" war kein Rechenfehler, sondern die Definition: am 02.09. begann die Kalenderwoche am 31.08., der Monat erst am 01.09. Umgestellt auf rollende Fenster (1/7/30/365 Tage), damit 1 ⊂ 7 ⊂ 30 ⊂ 365 an jedem Tag gilt. "Jahr" meint damit nicht mehr das Kalenderjahr - so entschieden. Zwei neue Tests halten die Verschachtelung fest. Aus dem Langzeitverbrauch sind Herleitung und Erklaerabsatz aus der ANSICHT genommen, nicht aus der Rechnung; das Datum des letzten Tankstops ebenfalls. UEBERSICHT. Unter "Letzter Tankvorgang" steht das Datum statt der Tankstelle. BILDER. Die Draufsicht war der einzige sichtbare Bildplatz ohne Zugang - bilder.py kannte den Dateinamen, BILDER/BILDPLAETZE nicht. Jetzt ein Platz wie jeder andere. Die Vorschau in den Einstellungen schneidet Fotos nicht mehr an, und der Bildbereich der Fahrzeugseite steht eingerueckt statt randlos. ZAHNRAD. Es lag mit seiner 44px-Trefferflaeche 21px im Kachelinhalt und fing die obere Haelfte des ersten Knopfes ab (Versicherung, "Inland"). Die Kopfzeile bekommt jetzt die Hoehe, die es braucht. SCREENING. Lief ausschliesslich bei einer Aenderung des Kilometerstands, also nur waehrend der Fahrt - im Stand blieben Ortsnamen und Verbrauch liegen. Jetzt zusaetzlich einmal nach dem Start, und danach faellt es selbst nach, solange ein Lauf sein Ortsbudget aufbraucht UND dabei etwas aufloest. Kein Dauertakt: die Kette endet, sobald ein Lauf mit uebrigem Budget durchkommt. GESTEN. Zum Loeschen nach links wischen, jetzt auch im Radarchiv (das Panel hatte die Mechanik, das Archiv war nie angeschlossen; die App hatte sie gar nicht). Vom linken Rand nach rechts wischen = zurueck, jetzt auch in der App, mit denselben Zahlen wie im Panel und in beiden mit sichtbarer Rueckmeldung. CI-SYMBOLE. Das Kachel-Zahnrad ist settings-s - im Panel stand der Pfad sechsmal wortgleich im Markup, jetzt einmal als CI.settingsS. Das handgezeichnete Zahnrad der Seitenleiste ist ersetzt und geloescht. Die Zapfsaeule des Tanken-Reiters ist fuel-station-s, Faktor 0,84 um die Rastermitte - live per getBBox() gemessen, damit sie auf dieselbe senkrechte Spanne kommt wie Statistik. Zurueckgenommen: die Titel der Unterseiten stehen wieder mittig. Zentriert ist Apples HIG fuer Navigationsleisten; die linksbuendigen Titel sind die der Hauptbereiche und folgen der anderen Regel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
960e07d7d7 |
Übersicht-Symbol: nochmals 10 % (Faktor 1,21) und auf die Rastermitte gelegt
Die eigene Mitte des Symbols liegt bei x=13, nicht 12. Ohne Verschiebung wäre Faktor 1,21 rechts wieder angestoßen (24,10 statt 22,89). Jetzt Geometrie 1,11-22,89, mit Strichstärke 0,36-23,64 - im Raster. Gemessen: 21,8 x 12,5 gegen ursprünglich 18,0 x 10,3, gerenderte Strichstärke weiterhin 1,5 wie bei den Nachbarn. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0b497642f4 |
Übersicht-Symbol: Faktor 1,1 statt 1,33 - der erste Versuch stand über
Faktor 1,33 hatte das Symbol auf volle Rasterbreite gezogen und dabei von x=3,99 bis x=27,9 geschoben - knapp vier Einheiten über den rechten Rand des 24er-Rasters, also rechts abgeschnitten. Beim Nachmessen waren Breite und Höhe geprüft, aber nicht die Position. Jetzt Faktor 1,1 um die Rastermitte (12,12): 19,8 x 11,3 bei x 3,2-23,0 und y 7,6-18,9, also die vom Eigentümer gewünschten 10 % ohne Überstand. Alle fünf Tab-Symbole nachgemessen, diesmal mit Rändern. 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> |
||
|
|
ce287ccac2 |
Fahrtenliste zeigt Orte aus dem Zwischenspeicher (2026.9.1.23)
Was die Einzelfahrt einmal aufgeloest hat, zeigt die Liste umsonst mit:
ortAusCache() liest nur den Zwischenspeicher und fragt nie das Netz. Ein Abruf
je Zeile waere genau der Vorratsabruf, um dessen Unterlassung Nominatim bittet.
In der Liste steht nur der ORT, nicht die Anschrift (Wunsch des Eigentuemers):
eine Zeile traegt Datum, Art, Strecke und Verbrauch, zwei volle Anschriften
passen dort nicht. Auf der Einzelfahrt bleibt die vollstaendige Anschrift.
Der Ortsname wird beim Aufloesen separat gemerkt ("ort:"-Schluessel), nicht aus
der Anschrift geschnitten - faellt Nominatim auf display_name zurueck, stuende
hinter dem letzten Komma das LAND.
Der Rueckfall war trotzdem noetig, und das Ausliefern hat es gezeigt: die Liste
stand weiter voller Anschriften, weil der Ortsname nur bei einem frischen Abruf
entsteht und die Adressen laengst im Speicher lagen. stadtAusAnschrift()
schneidet ihn deshalb aus einer gespeicherten Anschrift - aber nur, wenn hinter
dem letzten Komma eine Postleitzahl steht. Damit greift es bei unserem Format
"<Strasse>, <PLZ> <Ort>" und niemals bei display_name.
VERIFIZIERT: 7 Faelle gegen den Schnitt (mit/ohne Strasse, benannter Platz,
ohne PLZ, display_name-Form, null), Panel als Modul, tsc --noEmit und
vite build sauber, 165/165 Tests gruen. Im Browser: "Eichstaett -> Adelschlag"
in der Liste, volle Anschrift auf der Einzelfahrt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
0f680780a4 |
Einzelfahrt: Orte aus den Koordinaten, "Min." statt "min" (2026.9.1.20)
START UND ZIEL STANDEN AUF "UNBEKANNT"
start_address/end_address stehen in HANDFELDER - das Backend fuellt sie nie von
selbst, sie kommen nur aus einer von Hand angelegten oder bearbeiteten Fahrt.
Die Koordinaten dagegen traegt das Screening ein: 12 von 14 Fahrten im
Testbestand hatten Start- und Zielposition, aber genau eine hatte eine Adresse.
Beide Oberflaechen loesen sie jetzt beim Oeffnen der Einzelfahrt auf, ueber
denselben Cache wie die Standortansicht - ein Abruf je Ort, danach nie wieder.
Bewusst NICHT in der Liste: ein Vorratsabruf fuer alle Fahrten waere genau das,
worum Nominatim in seinen Nutzungsbedingungen bittet, es nicht zu tun.
Bis zur Antwort steht "wird ermittelt ...", ohne Koordinaten oder ohne Treffer
"unbekannt". Das Panel prueft vor dem Eintragen, ob noch dieselbe Fahrt offen
ist - wer waehrend des Abrufs weiterblaettert, soll nicht die Adresse der
vorigen Fahrt in der neuen sehen.
Live: Start "Schottenau, 85072 Eichstaett", Ziel "Am Anger 7a, 85111
Adelschlag".
"MIN." STATT "MIN"
Deutsche Abkuerzung, wie die Oberflaeche sie an anderer Stelle laengst
verwendet ("Geparkt seit 2 Tg. 16 Std. 12 Min."). In dauerText() bzw. dauer(),
also ueberall wo eine Dauer erscheint. Zwei Testerwartungen mitgezogen.
Verifiziert: Panel als Modul, tsc --noEmit und vite build sauber, 165/165
Tests gruen, im Browser nachgesehen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
97a1482bb5 |
Drei Erlaeuterungen aus der Fahrt-Detailansicht entfernt (2026.9.1.19)
Auf Wunsch des Eigentuemers entfallen die Kleingedruckten unter drei Zeilen: "Strecke / Dauer, Standzeiten eingerechnet" bei der Durchschnittsgeschwindigkeit "groesster gemeldeter Wert, alle 10 s ein Datensatz" bei der Hoechstgeschwindigkeit "Naeherung aus Tankfuellstand" bei Verbrauch In beiden Oberflaechen (Paritaetsregel). Die Ortsangaben unter Start und Ziel bleiben, das sind Daten und keine Erlaeuterung. Die Herleitungen selbst stehen weiterhin im Quelltext: durchschnitt_kmh() in verlauf.py rechnet unveraendert Strecke durch Dauer, hoechstwert_im_fenster() erklaert in seinem Docstring, warum der gemeldete Wert nicht die tatsaechliche Spitze ist, und verbrauch_aus_literstaenden() begruendet die Naeherung samt MIN_STRECKE_VERBRAUCH_KM. Es verschwindet nur die Anzeige, nicht das Wissen. Verifiziert: Panel als Modul geparst, tsc --noEmit sauber, 165/165 Tests gruen, audi_ha_test auf 2026.9.1.19 ohne Fehler gestartet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9a4999ccbc |
Strecken gestaffelt anzeigen (2026.9.1.18)
Die gewonnene Genauigkeit kam nicht an: de() formatiert ohne Nachkommastelle,
aus 6,896 km wurde in beiden Oberflaechen "7 km". Den ganzen Tag auf zehn Meter
genau gemessen und im letzten Schritt weggerundet.
Staffelung, vom Eigentuemer festgelegt: unter 1 km Meter ("400 m"), bis
99,9 km eine Nachkommastelle ("6,9 km"), ab 100 km ganze Kilometer ("104 km").
streckeTeile()/streckeText() in beiden Codebasen, wortgleich.
Gestaffelt wird nach dem GERUNDETEN Wert: 0,9996 km sind gerundet 1000 m und
gehoeren in die km-Stufe, sonst stuende dort "1.000 m". streckeTeile() gibt
Wert und Einheit getrennt zurueck, weil die Detailansicht beide in getrennten
Elementen setzt - ohne das stuende unter "400" weiterhin "km".
Im Panel heisst die Funktion streckeText, nicht strecke: den Namen gibt es dort
schon fuer die Ortsangaben einer Fahrt. node --check hat die Kollision gefunden.
Angewandt auf Einzelfahrt und Jahres-/Monatssummen. Nicht auf Kilometerstaende,
Serviceintervalle oder Reichweite - das sind Zaehlerstaende und Prognosen.
VERIFIZIERT: 12 Faelle gegen die Staffelung samt beider Grenzen, 165/165 Tests
gruen, Panel als Modul, tsc --noEmit und vite build sauber, im Browser
nachgesehen: die Fahrt vom 01.09. steht jetzt mit 6,9 km statt "7 km".
Die angepasste Testerwartung ist selbst ein Beleg: sie verlangte "43 km" fuer
eine Summe von 42,5 km - die alte Anzeige rundete schon dort, wo es etwas zu
zeigen gab.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7e2854fe8d |
Setup: Erwartungswert je Listenposition, gruen auch dort (2026.9.1.15)
Tuer- und Fenstersensoren haben vier Positionen, aber nur einen Beispielnamen (front_left_door). Der beschreibt die erste; die anderen drei koennen ihn nie enthalten. Folge: nur die erste Position konnte gruen werden, und im Kopf stand ein Erwartungswert, der fuer drei von vier Zeilen nicht galt. Neu "beispiele" je Position im Feld-Katalog und feldBeispiel(feld, idx) im Panel. Der Erwartungswert steht jetzt an jeder Position statt im Kopf - rechtsbuendig, in der kleinen grauen Schrift des Positionslabels. Auch die Sortierung der Vorschlagsliste nutzt ihn, sonst stuende in allen vier Zeilen dieselbe Entitaet oben. Typografie: .setup-feld-hinweis ist fuer die Kopfzeile gebaut (14px, --fg, rechtsbuendig, max-width 55%). Im 12,5px-Positionslabel wirkt das falsch herum. Eine Regel im Kontext .setup-unterfeld-label .setup-feld-hinweis laesst Groesse und Farbe erben; die Rechtsbuendigkeit kommt aus justify-content: space-between am Label, wie eine Ebene darueber bei .setup-feld-kopf. Verifiziert: alle acht Positionen tragen ihren eigenen Beispielnamen, py_compile und Panel als Modul sauber, audi_ha_test ohne Fehler gestartet. Die Darstellung selbst habe ich nicht im Browser gesehen - das Panel liess sich in der Testinstanz nicht ansteuern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
be95b40d79 |
Rueckblick legt keine Fahrten ohne gefahrene Strecke mehr an (2026.9.1.12)
Der Eigentuemer hatte auf der realen Instanz alle Nullfahrten geloescht - und bei JEDEM Import kam eine davon wieder: 31.08.2026, 14:48-15:21, 33 Minuten, 209177 -> 209177 km, vmax 3 km/h. MINDESTDAUER_S liess sie durch, weil sie mit 33 Minuten lang genug war; eine Pruefung auf die Strecke gab es im Rueckblick nicht. Steht der Kilometerstand an beiden Enden gleich, hat sich das Fahrzeug nicht bewegt - Zuendung an, aber nicht gefahren. Solche Fenster werden jetzt uebersprungen und als eigene Zahl gemeldet, damit der Import nicht stillschweigend etwas weglaesst. Nur die GEMESSENE Null wird verworfen, nicht die unbekannte: liegt kein Kilometerstand vor, bleibt distanz None und die Fahrt wird angelegt. Der Preis, bewusst getragen: eine echte Fahrt unter einem Kilometer, bei der der Zaehler nicht umsprang, geht verloren - sie waere aber genau der Nulleintrag, den der Eigentuemer nicht im Bestand haben will. Beide Oberflaechen melden die neue Zahl (Paritaetsregel). VERIFIZIERT im Testcontainer ueber den echten Dienst: 1 Fahrt angelegt, 2 Fenster als "nicht gefahren" uebersprungen, null Fahrten mit 0 km im Bestand. py_compile, Panel als Modul, tsc --noEmit sauber, 165/165 gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
02187ee129 |
Setup: gruene Bestaetigung statt Zuruecksetzen-Knopf (2026.9.1.11)
Passt die zugeordnete Entitaet zum Beispielnamen der Rolle (FELDER-Schluessel "beispiel"), faerbt sich das Feld leicht gruen. Dieselbe Pruefung, die entitaetScore() ohnehin mit 8 gewichtet - hier nur fuers Auge, damit man eine richtig belegte Rolle sieht, ohne den langen Entity-Namen Zeichen fuer Zeichen mit dem Beispiel daneben zu vergleichen. Bewusst nur ein Hinweis, keine Bedingung: Installationen mit anderer Datenquelle haben andere Namen und sind trotzdem richtig zugeordnet. Deshalb gruen als Bestaetigung, aber kein Rot und keine Warnung, wenn es fehlt. Und nicht waehrend gesucht wird - dann steht die Sucheingabe im Feld, nicht die Zuordnung. Die Farbe kommt per color-mix aus dem vorhandenen --ok-Ton und dem Feldgrund statt aus einem eigenen Gruen, damit sie in beiden Themen ruhig bleibt. "Auf Standard zurueckstellen" entfernt (Wunsch des Eigentuemers): Knopf, Symbol, Zuhoerer, CSS und der nur dafuer vorhandene Helfer setupStandardwert(). Keine verwaisten Verweise mehr im Quelltext. Panel als Modul geparst, Bundle und Manifest auf 2026.9.1.11. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3cd9e6149b |
"502" beim Neustart entschaerft, OTA-Buendel nachgezogen (2026.9.1.8)
DIE APP MELDETE EINEN FEHLER, WO KEINER WAR Nach "Jetzt neu starten" sprang der Knopf zurueck und darunter stand 502, waehrend Home Assistant ordnungsgemaess hochfuhr. Der Nutzer musste annehmen, der Neustart sei gescheitert, und drueckte erneut. updateNeustartAusloesen() behandelte jeden Fehlschlag als Fehler. Ueber einen Vorschaltserver kommt beim Neustart aber kein Abbruch zurueck, sondern eine saubere 502/503/504 - der Proxy antwortet, Home Assistant noch nicht. Genau der Fall, fuer den ApiFehler.istVoruebergehend seit dem 31.08. existiert; er wurde hier nur nicht gefragt. Der Bildschirm bleibt jetzt auf "Home Assistant startet neu ...", der bestehende Effekt raeumt ihn ab, sobald die Verbindung wieder steht. Im Panel war es kein Fehler (WebSocket bricht ab statt 502 zu liefern), aber die Luecke war dieselbe, sobald ein Vorschaltserver dazwischen steht - dieselbe Toleranz deshalb auch dort. DAS OTA-BUENDEL STAND NOCH AUF 2026.8.31.5 Gemeldet: Kopfzeile "App ist aelter als der Server", Kachel "App ist aktuell 31.5", Integration auf 1.7. Kein Fehler - die Anzeige sagte die Wahrheit. Sieben Versionen lang wurde nur die Integration ausgeliefert; npm run ota lief seit dem 31.08. nicht mehr. Merkposten: eine Aenderung an companion-app/src ist erst dann beim Nutzer, wenn das Buendel neu gebaut wurde. Der Versionssprung allein beschreibt sonst eine App, die es nicht gibt. VERIFIZIERT: Manifest, bundle.json und die ausgelieferte Zip tragen alle 2026.9.1.8 und denselben SHA-256 c2f9192e...; tsc --noEmit sauber, 165/165 Tests gruen, Panel als Modul geparst, audi_ha_test fehlerfrei gestartet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
553e128066 |
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> |
||
|
|
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> |
||
|
|
90efcc5b00 |
Neustart-Festhaenger, OTA-Pruefsumme, Statistik-Kopfzahl (2026.8.31.4)
Die App blieb nach einem Neustart von Home Assistant auf dem alten Stand stehen, mit einer 502-Fehlerzeile, die erst ein Beenden der App wegbekam. Zwei Ursachen: 502/503/504 galten als harter Ladefehler statt als "Server faehrt gerade hoch", und nach dem Wiederverbinden wurde genau einmal nachgeladen - schlug das fehl, kam nie wieder ein Versuch. Beides behoben, vier Regressionstests dazu. OTA: das Buendel ist von HEAD ueber die Platte bis zu den ausgelieferten Bytes nachweislich deckungsgleich. Die Fassung haengt jetzt trotzdem als ?v= an der Adresse (der statische Pfad kommt ohne Cache-Control, aber mit ETag), und ein Pruefsummenfehler wird erklaert statt durchgereicht. Statistik: der Gesamtwert steht jetzt als grosse Zahl in der Kopfzeile, darunter bleiben vier Spalten - fuenf passen auf dem Telefon nachweislich nicht in eine Zeile. Fahrzeugfoto ohne Beschnitt und ohne Bodenschatten, damit auch ohne den Schalter dafuer. Setup filtert zusaetzlich nach dem Signalnamen aus dem Katalog. 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> |
||
|
|
b1411625aa |
Teilen-Blatt, HIG-Blaetter, geteilte Ansichtseinstellungen (2026.8.31.1)
Share-Erweiterung: ein PDF aus Mail landet ueber Teilen -> DataMetric360 als Tankbeleg. Alles Native liegt versioniert unter companion-app/native/, weil ios/ gitignored ist und npx cap add ios es sonst wieder frisst; scripts/ios-teilen-einrichten.mjs haengt es bei jedem Bau ins Xcode-Projekt und ist in ios-signieren.sh eingehaengt. Der pbxproj-Teil ist auf keinem Mac erprobt - er bricht vor dem Schreiben ab, und docs/SHARE_EXTENSION.md beschreibt dieselben Handgriffe fuer Xcode. "In den Kalender uebernehmen" ging in der App nie: WKWebView ignoriert das download-Attribut, der Klick lief ins Leere. Auf dem Geraet jetzt @capacitor/filesystem plus @capacitor/share. useTheme/useBoden legten je Aufrufer eigenen Zustand an - fuenf Kopien. Der Schalter aenderte nur seine eigene, data-theme in App.tsx blieb stehen, die Tag/Nacht-Umschaltung wirkte erst nach einem Neustart. Jetzt ein Speicher je Einstellung ueber useSyncExternalStore. Zwei Regressionstests, gegen den alten Stand als fehlschlagend nachgewiesen. Alle Popups nach Apple HIG: neue Bausteine Sheet und ActionSheet, blickdicht und mit abgedunkeltem Schleier, in beiden Codebasen. Popup portalierte nach document.body - ausserhalb von [data-theme] - und war deshalb im Tagmodus fast unsichtbar; Portal zielt jetzt auf .ads-root. ImagePlaceholder merkte sich "fehlgeschlagen" ohne die Adresse: nach einem leeren Galerieplatz zeigten auch die mit Foto nur noch den Platzhalter. Vier Regressionstests, ebenfalls gegen den alten Stand geprueft. Bildadressen tragen jetzt einen Cache-Brecher - HA liefert /local/ mit 31 Tagen Cache-Vorgabe aus, im Panel eingefuegte Radfotos erschienen in der App deshalb nicht. uebersichtsbild: Panel speichert den Namen, die App verglich gegen den Dateinamen - der Vergleich traf nie zu. Kanonisch ist der Name. Weiter: Navigationspfeil statt gleichschenkligem Dreieck auf der Streckenlinie (die Kerbe unterscheidet Kopf und Ende), CI-Symbol tour-s als Fahrten-Icon, Datumsfelder zeigen ihren Wert ohne erstes Antippen, feste Beispielnamen im Setup, Kopf-Gegengewicht fuer mittige Titel, Standort-Blatt mit festem Fussabstand, NSLocationWhenInUseUsageDescription, watchPosition fuer die Live-Ortung, Art-Pille wieder als Knopf, Zwischenablage fuer Tankbelege. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d622d74434 |
DRINGEND: Panel war seit 2026.8.30.14 syntaktisch kaputt (2026.8.30.19)
Beim "Zuendung an"-Patch habe ich den Begruendungskommentar in den
${...}-Ausdruck gesetzt statt in den Markup-Text. Dort ist <!-- kein
HTML-Kommentar, sondern JavaScript. Folge: audi-dashboard-app.js liess sich
nicht mehr als Modul parsen, connectedCallback() brach ab, das Panel hatte
keinen Shadow Root - der Bildschirm blieb leer.
Betroffen sind .14 bis .18, also alles, was seit dem auf Gitea lag. Wer in
dieser Zeit aktualisiert und neu gestartet hat, bekam ein totes Panel.
Warum es durchrutschte - und das ist der eigentliche Befund: "node --check"
prueft eine .js-Datei als SCRIPT, und dort sind HTML-artige Kommentare per
Annex B ausdruecklich erlaubt. Der Browser laedt dieselbe Datei als MODUL,
wo sie verboten sind. Die Pruefung, auf die sich dieses Projekt bei jeder
Panel-Aenderung verlaesst, kann diesen Fehler grundsaetzlich nicht finden.
Ab sofort gilt: die Datei vor dem Ausliefern als Modul pruefen, also unter
.mjs kopieren und node --check darauf laufen lassen. Rueckwirkend ueber alle
heutigen Commits geprueft - .14 ist der erste kaputte.
Erschwerend kam dazu, dass ich den Panel-Tab nach .14 nie neu geladen habe.
Alle spaeteren "live geprueft"-Aussagen zur Panel-Seite liefen gegen das noch
im Speicher stehende alte Skript und waren damit wertlos.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
c300aab223 |
Update-Kachel: Zeitstempel und "Erneut pruefen" auch im Verfuegbar-Zweig (2026.8.30.17)
Die angezeigte "Verfuegbare Version" ist das gespeicherte Ergebnis der letzten Pruefung, nicht der Live-Stand - version_pruefen() laeuft ausschliesslich auf Tastendruck. Im Zweig "Integration ist aktuell" stand der Zeitpunkt der Pruefung schon dabei, ausgerechnet im Verfuegbar-Zweig nicht. Eine Wochen alte Zahl sah dort aus wie eine Tatsache. Schlimmer: der Knopf "Auf Update pruefen" gab es nur im Zweig "ist aktuell". Sobald einmal ein Update gefunden war, liess sich die Angabe gar nicht mehr auffrischen - sie blieb bis zur Installation stehen, auch wenn auf Gitea laengst eine neuere Fassung lag. Beides in beiden Codebasen ergaenzt: Zeitstempel als Nebenzeile an der Version, "Erneut pruefen" als zweiter Knopf unter "Update installieren". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d2994ce919 |
Standort: "Zuendung an" statt "Fahrzeug faehrt" (2026.8.30.14)
Es gibt keinen Bewegungssensor am Fahrzeug. Der einzige Anhaltspunkt ist ZUENDUNG_SENSOR, und der meldet on auch bei blosser Zuendung oder in Zubehoerstellung - "Fahrzeug faehrt" behauptete also mehr, als bekannt ist. Mein zwischenzeitlicher Vorschlag, zusaetzlich eine laufende Fahrt zu verlangen, war falsch begruendet: fahrt_start_ts in fahrterkennung.py wird aus genau demselben Signal abgeleitet und haette nur eine zweite Huelle um dieselbe Aussage gelegt. Der umgekehrte Fall bleibt unangetastet: Zuendung aus heisst verlaesslich, dass gerade nicht gefahren wird - "Fahrzeug steht" und "Geparkt seit ..." stehen weiter. Zwei Typ-Kommentare, die dieselbe Gleichsetzung weitertrugen, sind mitkorrigiert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
67135da4f7 |
Layer-Symbol: falscher Pfad in der App, zu klein in beiden (2026.8.30.12)
Drei Anlaeufe, die ersten beiden mein Fehler. Gemeldet war "Icon falsch im Knopf platziert". Ich habe die Zeichenflaeche gemessen, sie fuellt 20,9x15,6 des 24er-Rasters gegen 20x20 bis 24x22 bei den Nachbarn, und daraus auf "zu schwer und aussermittig" geschlossen - also verkleinert. Zwei Fehler darin: gemessen habe ich das Panel und geaendert habe ich beide, ohne das Symbol der App je selbst zu messen; und "fuellt weniger Flaeche als die Nachbarn" spricht fuer "wirkt kleiner", nicht dagegen. Nach der Ruecknahme im Panel zeigte die Messung der App den echten Fehler dort: ihr mapLayer-Pfad begann mit grossem M statt kleinem m. Beim ersten Befehl ist das gleichbedeutend, aendert aber alles danach - nach M gelten folgende Zahlenpaare als absolute Linien, nach m als relative. Der zweite Punkt sprang damit auf (-8.97,-5.66), weit aus dem Raster: das Symbol war verzerrt, nicht bloss falsch dimensioniert. Pfad wortgleich vom Panel uebernommen, alle vier Steuerungssymbole vergleichen sich jetzt zeichengleich. Damit stand die urspruengliche Meldung fuer sich und war schlicht richtig: die flache Form wirkt bei gleicher Kastengroesse kleiner. Beide zeichnen sie jetzt mit 26px statt 22px - dieselbe Loesung wie beim Oelwechsel-Icon der Servicebloecke, das aus demselben Grund 26px neben 20px bekommt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0fd81df700 |
Ziehen zum Aktualisieren, Nachtmodus-Zeilen, Parkplatznamen (2026.8.30.10)
Ziehen zum Aktualisieren funktionierte auf keinem Geraet, in keiner der beiden Anwendungen - und der Grund entwertet zugleich, wie es bisher geprueft wurde. Beide trieben die Geste ueber pointermove und riefen dort preventDefault(). Das verhindert laut Spezifikation kein Scrollen; darueber entscheidet allein touch-action. Auf echtem Touch uebernimmt der Browser die senkrechte Geste, schickt pointercancel und stellt pointermove ein - der Zug wird zurueckgesetzt, lange bevor er die Schwelle erreicht. Eine Maus kennt diese Uebernahme nicht, synthetische PointerEvents ebenso wenig: genau deshalb lief die Geste 2026-08-17 im Test sauber durch und am Geraet nie. Jetzt laeuft sie auf Touch-Ereignissen, touchmove zwingend mit passive:false (sonst ist preventDefault() wirkungslos); der Zeigerweg bleibt fuer Maus und Stift und ignoriert pointerType "touch". Mit echten TouchEvents geprueft, inklusive defaultPrevented - dem einzigen Signal, das belegt, dass das native Ueberscrollen wirklich unterbunden ist. Der zuletzt nicht nachstellbare Befund war nachtmodus-spezifisch: --tile ist dort ein durchscheinender Schleier, und die Wischzeilen malten ihn ein zweites Mal auf die Kachel, auf der sie ohnehin liegen. Am Tag sind beide deckend weiss, deshalb war nichts zu sehen. Das Panel nutzt an dieser Stelle --tile-deckend; dieses Token fehlte im Design-System und ist jetzt da. Ausserdem: steht das Auto auf einem benannten Platz, zeigen beide dessen Namen statt der naechsten Hausnummer - Nominatim liefert ihn mit, die Pruefung auf die Art der Flaeche verhindert, dass irgendein benanntes Gebaeude die Anschrift verdraengt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
a08922e9a0 |
Befundliste des Besitzers: drei echte Fehler, dazu Feinschliff (2026.8.30.9)
Fahrzeug-Pin auf der Standortkarte fehlte: die Marker-Effekte lesen Refs, die erst im asynchronen Leaflet-Import gesetzt werden. Beim ersten Lauf leer, Effekt steigt aus - und weil die Koordinaten sich danach nicht mehr aendern, lief er nie wieder. Ein Bereitschaftsschalter in den Abhaengigkeiten behebt das fuer Marker, Kachelebene und eigene Position zugleich. Kachelpfeil auf "Mein Audi" sass auf halber Kachelhoehe statt oben neben der Ueberschrift; Auswahlfelder hatten nach appearance:none ueberhaupt keinen Aufklapp-Pfeil mehr. SmartDeal: das Datumsfeld war fehlerhaft und die Abfrage, bis wann der Rabatt gilt, fehlte ganz. Das Panel fragt beim Einschalten und zeigt danach nur an - genau daran haengt, dass der Rabatt von selbst auslaufen kann. Portiert. Adressen statt Koordinaten: Nominatim drosselt uns inzwischen. Beide Apps fielen korrekt zurueck, merkten sich Treffer aber nur bis zum Neuladen. Jetzt dauerhaft im selben Cache wie die Tankstellensuche. Ziehen zum Aktualisieren auf dem Geraet: dem Scrollbehaelter fehlte overscroll-behavior, das native Overscroll nahm die Geste weg - derselbe Befund, den das Panel am 2026-08-17 hatte. Ausserdem: Platzhalter wieder in voller Groesse, FIN statt Fahrgestellnummer, Details als Hinweiszeile, Chevron an der Batteriespannung, Reifenzeile "aktuell montiert:", Zahnrad statt Stift am Anzugsmoment, Radkilometer in der Zahlenschrift, Layer-Icon zentriert, share-s beim Teilen, Schliessen-Knopf nur bei aufgezogener Karte. Nicht nachstellbar und zurueckgemeldet: "Fahrten/Tanken, grauer Hintergrund" - Panel und App sind dort deckungsgleich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4a58021670 |
Paritaetsrunden 2 und 3, Designpruefung umgesetzt (2026.8.30.8)
Drei zusammenhaengende Runden, alle live bei 375x812 gegen audi_ha_test geprueft und in beiden Codebasen angewandt. Paritaetsrunde 2: der gemeinsame Rahmen war das eigentliche Problem - Seitenrand, Kachelabstaende, Kopfleiste, Tableiste und vier Bausteine des Design-Systems trugen noch den Stand vor der iOS-Entscheidung. Dazu sieben Bildschirme neu aufgebaut. Zwei Panel-Fehler dabei mitbehoben: teaser() zeigte unter "Letzte Fahrt" den aeltesten Datensatz, und "Daten bearbeiten" war ein toter Knopf. Paritaetsrunde 3: das Panel hat nie Audi Type gerendert. @font-face in einem Shadow Root wird ignoriert - Schriftschnitte registriert der Browser pro Dokument, nie pro Shadow Tree. Die drei Schnitte liegen jetzt in audi-dashboard-schriften.css und werden ins Dokument gehaengt. Damit erledigt sich eine ganze Reihe von "die Schrift sieht anders aus"-Eindruecken: die beiden Anwendungen zeigten tatsaechlich verschiedene Schriften. Ausserdem "Daten bearbeiten" im Panel gebaut und portiert, das Zeilenmenue entfernt und die letzten neun Bildschirme angeglichen. Designpruefung: die fuenf Punkte der Reihenfolge. Beim vierten hat das Messen den Befund veraendert - gezaehlt waren die deklarierten Groessen, wirksam war laengst eine saubere Sieben-Schritt-Skala mit 27 Ausreissern; die sind jetzt auf den naechsten Schritt gezogen, keiner verschiebt sich um mehr als 1px. Zuletzt: die Standortvorschau zeichnete die falsche Nadel (das Panel wechselt den Icon-Satz ab 34px, die App nahm immer den grossen), und der Kopfabstand der App ist auf den sicheren Bereich reduziert - die 56px des Panels liegen dort unter der Kopfleiste von Home Assistant, in der nativen Huelle steht darueber nichts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e1ebe6d694 |
Vollständiger Panel-companion-app-Paritätsaudit (11 Kapitel)
Systematischer Bildvergleich der companion-app gegen das HA-Panel (companion-app/AGENTS.md Kapitel 1-11): Farbtoken/Radien aus dem falschen Stylesheet gelesen (iOS-Overlay statt Basis-CSS, betraf fast jede Kachel/Farbe/Radius app-weit), vier app-weite @audi-dash/ui-Bugs (Switch/Seg/Feld rot statt neutral bzw. falsche Feldbreite), Reifen-Seite strukturell neu gebaut (beide Radsätze gleichzeitig statt Umschalter, editierbare Felder, Anzugsmoment-/km-Korrektur), Standort-Feature komplett neu (fehlte bisher ganz), sowie diverse Struktur-/Typografie-/Datenlücken in MeinAudi/Service/Versicherung/Sicherheit/Fahrten/Tanken/Statistik/Batterie/Einstellungen. Manifest auf 2026.8.30.2 angehoben, OTA-Bündel neu gebaut und in audi_ha_test verifiziert (sauberer Neustart, keine Tracebacks). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
391725e663 |
Setup-Menü: Sensorhinweis auf (z. B. tatsächlicher Sensor) reduziert
Erst zwei Zeilen (festes Beispiel + zugeordneter Sensor) versucht, aber die erfundenen Beispiele waren für Reichweite/Sofort-Aktualisierung schlicht falsch. Jetzt nur noch eine Zeile mit dem tatsächlich zugeordneten Sensor, "(z. B. ...)" in Label-Größe/-Farbe, der Sensorname selbst wie die Einheit daneben ([on/off], [km]); für Listenfelder (Türen/Fenster) ganz entfernt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
6b35de458d |
Fahrgestellnummer: expliziter "automatisch"-Schalter statt Nur-wenn-leer-Heuristik
- Neues Profilfeld fahrzeug.fin_automatisch (Standard: an). - identitaet.py: bei "aus" läuft die Ableitung (samt Mehrfach-Sensor-Abgleich) gar nicht erst; bei "an" überschreibt der abgeleitete Wert auch einen vorher von Hand eingetragenen - der Schalter selbst entscheidet jetzt, statt aus einem leeren Feld zu raten. - dienste.py: profil_schreiben löst die Ableitung jetzt auch aus, damit das Umschalten des Schalters selbst sofort wirkt. - Panel: Schalter "automatisch" zwischen Label und Textfeld in der Fahrgestellnummer-Zeile, Feld wird bei "an" deaktiviert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8f88ccf581 |
Zuletzt-Kachel: Werte jetzt wirklich spaltenbündig
- .teaser-Klasse auf die Kachel gesetzt (teaser()). - .teaser .leaf .v: min-width:72px (gleiche Spaltenbreite je Zeile). - .teaser .leaf .k: flex:1 1 auto, damit unterschiedlich lange Labels nicht mehr über justify-content:space-between den ganzen Rest der Zeile verschieben - vorher blieben .v-Boxen zwar gleich breit, saßen aber an unterschiedlichen X-Positionen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |