d889353cbede5d0930ff61fb9bef7f4defdaa4d2
30 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5ff33c92d9 |
install.ps1: Zugangsdaten direkt nach der Pfadeingabe abfragen
Bisher wurde nach dem manuell eingegebenen config-Pfad erst ein Erreichbarkeits-Test versucht (der ohne bestehende SMB-Sitzung fast immer scheitert) und erst danach nach Benutzername/Kennwort gefragt. Jetzt folgt die Abfrage direkt auf die Pfadeingabe. Die Anmeldelogik selbst ist dafür in die Funktion SambaAnmelden ausgelagert, die weiterhin auch als Rückfallebene für automatisch gefundene oder per -Ziel übergebene Pfade dient. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
3c28c771fd |
install.ps1: net use /delete darf das Skript nicht abbrechen
"Nichts zu löschen" ist der Normalfall beim ersten Verbindungsversuch, meldet sich aber als Fehler des net.exe-Aufrufs. Mit dem umgeleiteten Fehlerstrom (*>) und $ErrorActionPreference "Stop" wurde daraus ein terminierender Fehler, der die gesamte Installation abbrach, bevor der eigentliche Anmeldeversuch überhaupt lief. Jetzt abgefangen statt nur umgeleitet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
e999d629c5 |
install.ps1 fragt bei fehlgeschlagener Verbindung selbst nach Zugangsdaten
Test-Path auf einem UNC-Pfad fragt nie nach einem Passwort - ohne eine bereits bestehende SMB-Sitzung liefert es bei einem geschuetzten Share einfach "false", ganz ohne Fehlermeldung. Das Skript verliess sich bisher darauf, dass eine Sitzung schon von Hand aufgebaut wurde (Explorer oder "net use"), und meldete sonst "Ziel nicht erreichbar" - selbst wenn Pfad und Zugangsdaten korrekt waren. Jetzt fragt es bei fehlender Erreichbarkeit selbst nach Benutzername/Kennwort und baut die Sitzung per "net use" auf, bevor es endgueltig abbricht. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
2ea01ce2ce |
install.ps1 warnt vor einem veralteten OTA-Bündel
Beim Prüfen, ob die GitHub-Entfernung eine Versionserhöhung brauchte, fiel eine echte Lücke auf: nichts hielt frontend/app/bundle.json auf demselben Stand wie manifest.json. Bei der nächsten echten Versionserhöhung ohne "npm run ota" hätte das zu einem stillen Widerspruch geführt - die Hinweisleiste hätte "veraltet" gemeldet (liest die Version live), die Update-Seite "aktuell" (vergleicht gegen das eingefrorene, dann falsche Bündel) -, ohne dass ein Update über OTA erreichbar gewesen wäre, bis jemand den Widerspruch bemerkt. install.ps1 liest jetzt direkt nach der Manifest-Version auch frontend/app/bundle.json und vergleicht. Bei Abweichung: deutliche Warnung plus erster Eintrag in der Restliste. Fehlt das Bündel ganz, passiert nichts - OTA ist optional, das ist der normale Zustand. Beide Pfade an einem Mock-Zielordner geprüft: passende Versionen melden "OTA-Bündel passt zur Integration" ohne Restliste-Eintrag; eine testweise erhöhte Manifest-Version (danach byte-genau zurückgesetzt, gegen HEAD gegengeprüft) erzeugt die Warnung und landet als Restliste-Punkt 1. VERSIONIERUNG.md: "Was du tun musst" nennt den OTA-Neubau jetzt als eigenen nummerierten Schritt, statt ihn ganz auszulassen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
ba182cb180 |
GitHub-Spiegel entfernt - HACS kann nicht helfen, Gitea bleibt die einzige Quelle
Der am 2026-08-24 angelegte Spiegel nach github.com/T130B/DM360 hatte keinen Zweck erfüllt: HACS lehnt private Repositories laut eigener Dokumentation kategorisch ab, unabhängig davon, ob sie auf Gitea oder GitHub liegen. Ein GitHub-Konto zusätzlich zu pflegen kaufte also nichts. Auf Wunsch entfernt - entwickelt wird ausschließlich auf der eigenen Gitea-Instanz. - hacs.json entfernt: tote Konfiguration ohne GitHub-Ziel, das sie bedienen könnte. - manifest.json: documentation/issue_tracker/codeowners zeigen jetzt auf gitea.nothaft.cloud/paul/audi-app statt auf den abgeschafften Spiegel. - install.ps1: Kopfkommentar nennt keinen aktiven Spiegel mehr. - AGENTS.md: die HACS-Ablehnung als endgültig festgehalten (nicht nur "heute privat"), samt der Begründung, warum ein erneuter GitHub-Anlauf nichts ändern würde - falls das je wieder aufkommt. Am laufenden Testcontainer geprüft: Integration lädt mit dem neuen Manifest fehlerfrei neu, keine Fehler im Protokoll. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
1354ca6b06 |
OTA-Updates für die iOS-App; HACS-Fehlannahme korrigiert
HACS kann laut eigener Dokumentation grundsätzlich nicht mit privaten GitHub-Repositories arbeiten (hacs.xyz/docs/faq/private_repositories) - keine Ausnahme für Tokens oder verbundene Konten. Meine frühere Annahme, HACS käme damit zurecht, wenn es unter dem richtigen Konto angemeldet ist, war falsch. Da das Repository aus Lizenzgründen privat bleiben muss (Audi-Hausschrift, Typenschilder), ist install.ps1 damit nicht die Rückfallebene, sondern der einzige Installationsweg - README, INSTALL.md, ANLEITUNG.md, install.ps1 und VERSIONIERUNG.md korrigiert. Oberflächen-Updates für die iOS-App laufen jetzt ohne Xcode: @capgo/capacitor-updater eingebaut, ein Update-Abschnitt in den Einstellungen lädt ein neues Bündel und tauscht die Oberfläche aus. Kein Selbstlauf (autoUpdate: false) - nur auf Tastendruck, nie während der Benutzung. Das Bündel liegt in der Integration selbst (custom_components/audi_dashboard/frontend/app/), nicht unter /local/: so reist es bei jeder Installation automatisch mit, ohne zweiten Auslieferungsweg. Gebaut von companion-app/scripts/ota-paket.ps1 (neuer Befehl: npm run ota), gemeldet über sensor.audi_dashboard_app_version (neues Feld daten.buendel). Ein echter Bug beim Bauen gefunden: [IO.Compression.ZipFile]::CreateFrom- Directory schreibt unter Windows PowerShell 5.1 Backslashes in die Zip-Einträge - iOS hätte das Archiv falsch entpackt. Behoben, indem die Einträge von Hand mit "/" geschrieben werden. Rückfallebene: notifyAppReady() läuft erst, wenn React nachweislich gerendert hat (App.tsx). Kommt diese Meldung nicht, rollt das Plugin nach 20 Sekunden von selbst auf das vorherige Bündel zurück. Am laufenden Testcontainer verifiziert: die ausgelieferte Zip hasht exakt auf den in bundle.json hinterlegten Wert, 13 Einträge, index.html in der Wurzel, keine Backslashes, keine Beschädigung. tsc sauber, 117/117 Tests (5 davon neu für buendelPasst() - dabei eine echte Lücke gefunden: die Funktion hätte bei unbekannter eigener Version fälschlich ein Update angeboten, jetzt genauso vorsichtig wie versionVergleichen). 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> |
||
|
|
99cef7c393 |
Fahrzustand aus der Zuendung statt aus dem Fahrtstatus, App-Version vergleichbar
BUG "Fahrzeug faehrt" aenderte sich nie. standortZustand() leitete den
Fahrzustand aus TRIPS[0].status === "offen" ab - zwei Fehler
uebereinander, die sich gegenseitig verstaerkt haben.
Erstens heisst "offen" nicht "unterwegs", sondern "Daten noch
unvollstaendig": _fahrt_beenden() legt die Fahrt mit diesem Status an,
wenn sie ENDET, und das Kilometerstand-Screening fuellt sie spaeter. Eine
Fahrt, die nie eine Strecke bekam - etwa weil damals kein KM_SENSOR
zugeordnet war -, bleibt fuer immer "offen". Zweitens ist TRIPS[0] die
AELTESTE Fahrt, nicht die neueste: fahrten_veroeffentlichen() reicht
profil.fahrten_lesen() unveraendert in Dateireihenfolge weiter, und die
ist aufsteigend. Zusammen hat die aelteste jemals unvollstaendig
gebliebene Fahrt das Fahrzeug dauerhaft als fahrend angezeigt; an der
Testinstanz war das eine seit 18 Tagen beendete Fahrt.
Nicht den Index geflickt, sondern die Quelle korrigiert: das Backend
veroeffentlicht jetzt "zuendung" im Fahrzeugstatus, gelesen aus dem
ohnehin zugeordneten ZUENDUNG_SENSOR - demselben Signal, das auch
fahrterkennung.py als massgeblich nimmt. Anzeige und Erfassung koennen
dadurch gar nicht mehr auseinanderlaufen. Ohne zugeordneten Sensor
(null) steht "Fahrzustand unbekannt" statt einer Behauptung.
companion-app hatte denselben Fehler spiegelverkehrt: liveZustandLesen()
las "zuendung" (gab es nie) und "lat"/"lon" (das Backend liefert
standort_lat/standort_lon), und der Typ Fahrzeug kannte keines dieser
Felder. Die Live-Ansicht meldete deshalb dauerhaft "Das Fahrzeug steht"
und zeigte nie eine Position. Felder in Fahrzeugstatus/Fahrzeug und im
Adapter ergaenzt, damit der Typ diese Fehlerklasse kuenftig faengt -
wovor sein eigener Kopfkommentar seit einem frueheren Vorfall warnt.
BUG "Standortzugriff verweigert" war irrefuehrend. Die Zeile steht
direkt unter dem Fahrzeugnamen, wo sonst der Abstand zum Auto steht,
handelt aber vom Standort DIESES Geraets - sie las sich, als sei der
Standort des Autos nicht abrufbar. Jetzt "GPS offline" wie gewuenscht.
Die verweigerte Freigabe behaelt eine eigene Meldung ("GPS-Freigabe
fehlt"): sie ist der einzige Fall mit anderer Abhilfe, und "GPS offline"
wuerde dort zur Signalsuche statt zum Freigabeschalter schicken.
VERSIONIERUNG: die Zahl, die alle fuer "die Version" hielten, ist keine.
Der Integer in audi-dashboard-version.json ist ein Cache-Brecher, den
install.ps1/update.ps1 bei jedem Deploy mit UtcNow neu setzen -
unabhaengig davon, ob sich Code geaendert hat. Zwei Builds derselben
Quelle bekommen verschiedene Zahlen. Er kann die Frage "ist das derselbe
Stand?" grundsaetzlich nicht beantworten.
Deshalb beide Aufgaben getrennt: neue Datei VERSION im Projektstamm
(2026.08.23.1) als Identitaet, von Hand erhoeht; der Integer bleibt
unveraendert der Cache-Brecher. VERSION fliesst in beide Seiten - als
zweites Feld "app" in audi-dashboard-version.json (alle drei
Deploy-Skripte uebernehmen es jetzt; sie haben die Datei bisher komplett
ueberschrieben und haetten es still zerstoert) und ueber vite define als
__APP_VERSION__ in den Companion-Build. Das Backend veroeffentlicht
pyscript.audi_dashboard_app_version, die App vergleicht und meldet eine
Abweichung in der Hinweisleiste - deren erklaerter Grundsatz "nie eine
stille Veraltung" genau dieser Fall ist, nur dass hier nicht die Anzeige
veraltet, sondern die App selbst.
Bewusst nur Gleichheitsvergleich, nie groesser/kleiner: die Version ist
eine Kennung, keine Zahl; Sortieren waere scheingenau und wuerde bei
einem Formatwechsel still falsch antworten. Fehlt eine der beiden
Seiten, wird nicht verglichen und nichts gemeldet - ein aelteres Backend
oder ein Start ohne Netz darf keinen Fehlalarm ausloesen. Der
vite-Build bricht dagegen hart ab, wenn VERSION fehlt, statt eine App zu
erzeugen, die ihre eigene Veraltung nicht erkennen kann. Das Panel
braucht nichts davon: es laedt bei jedem Seitenaufruf neu.
Geprueft: Backend meldet zuendung: False und app_version 2026.08.23.1 im
Testcontainer, Panel zeigt statt "Fahrzeug faehrt" jetzt "Geparkt seit
13 Tg. 13 Std." und statt der alten Meldung "GPS-Freigabe fehlt";
VERSION landet nachweislich im Build (im Bundle gegriffen) und der Build
bricht ohne die Datei ab (gegengeprueft); tsc sauber, Tests 112/112,
vite build sauber, HA-Start ohne Fehler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
d504de0645 |
ANLEITUNG.md an den neuen Stand angeglichen
Die Kurzanleitung im Installationspaket beschrieb noch den Stand vor dem Historienimport: sie nannte die feste configuration.yaml.bak (jetzt zeitgestempelt), kannte weder hass_is_global noch den recorder-Block und endete bei Schritt 5. Neu bzw. korrigiert: die Datenaufbewahrung als eigener, ausdruecklich zeitkritischer Schritt 3 samt Speicherplatz-Hinweis fuer HA OS; der Import als Schritt 7; der Warnhinweis, beim Kilometerstand nicht den vom FMM003 selbst berechneten GPS-Wert zu nehmen; der Hinweis, dass im Auslieferstand kein Sensor vorbelegt ist und die drei trigger-gebundenen Felder einen zweiten Neustart brauchen. Dazu ein Abschnitt "Ist das fuer meine bestehende HA-Installation gefaehrlich?", der die Sicherheitseigenschaften des Installers benennt, statt sie voraussetzen zu lassen - kein Remove-Item, kein robocopy /MIR, .storage/ unangetastet, kein Neustart, und als einzige fremde Datei die configuration.yaml mit Sicherung, Konfliktabbruch und Rueckrollen. Und die ehrliche Einordnung, dass das eigentliche Risiko nicht der Installer ist, sondern der Plattenplatz bei einem Jahr Aufbewahrung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3b99f1f332 |
Vergangene Daten aus dem HA-Verlauf importierbar, Auslieferstand bereinigt
Datenaufbewahrung (recorder_snippet.yaml, neu): Home Assistant loescht Sensor-Verlaeufe standardmaessig nach 10 Tagen - das war die stille Obergrenze dafuer, wie weit sich ueberhaupt je etwas rekonstruieren laesst, denn geloeschte recorder-Zeilen sind endgueltig weg. Der Block hebt das auf 365 Tage. Die Bestaende der App selbst (fahrten.jsonl, tankvorgaenge.jsonl, batteriespannung.jsonl, fahrzeugprofil.json) waren davon nie betroffen, die kennen ohnehin keine Purge-Logik. Platzbedarf an der Testinstanz gemessen statt geschaetzt: 90.858 Zeilen in 17 Tagen, hochgerechnet grob 1,9 Mio. Zeilen und 1-1,5 GB im Jahr, davon 96 % aus der EU-Data-Act-Integration - dafuer liegt eine auskommentierte exclude:-Liste bei. Bewusst kein include:-Block, der wuerde jeder anderen Integration den Verlauf nehmen und dabei kaum Platz sparen. Historienimport (pyscript/historienimport.py, neu): neuer Dienst audi_dashboard_historie_importieren(start, ende) liest denselben Verlauf, den die Live-Trigger in Echtzeit sehen, und leitet rueckwirkend dieselben Datensaetze ab - Fahrten aus dem Zuendungsverlauf (inklusive der Pausenregel, kurze Unterbrechungen verschmelzen zu einer Fahrt), Tankvorgaenge nach derselben Tiefststand-Logik und denselben Schwellen wie tankerkennung.py, Tagesmin/-max der Batteriespannung. Mehrfach ausfuehrbar: ueberschneidet sich eine Fahrt mit einer bereits erfassten, wird sie uebersprungen statt doppelt angelegt. Erzeugte Datensaetze tragen source: "import". Gelesen wird ueber HAs eigene recorder-API (get_significant_states), nicht per direktem SQL auf home-assistant_v2.db: das Schema ist HA-intern und aendert sich zwischen Versionen, die Funktion ist die stabile Schnittstelle. Preis dafuer ist hass_is_global: true im pyscript-Block; ohne die Zeile laeuft alles andere unveraendert weiter, nur der Import meldet, dass er den Verlauf nicht lesen kann. Oberflaeche in beiden Codebasen: Knopf "Daten importieren aus Home Assistant" unter Einstellungen -> Einrichten, dahinter ein Fenster mit Von/Bis (Vorbelegung: letzte 30 Tage), "Importieren" als Hauptaktion und "Abbrechen" als zweite Wahl. Das Fenster bleibt offen und zeigt das Ergebnis, statt optimistisch zu schliessen - hier ist das Ergebnis der Zweck des Aufrufs. Fortschritt ueber die Entitaet pyscript.audi_dashboard_import_status, weil pyscript-Dienste sofort zurueckkehren. In companion-app bewusst NICHT ueber die Offline-Warteschlange: ein spaeter aus dem Nichts abgefeuerter Importlauf waere fuer den Nutzer nicht nachvollziehbar. Beim Testen gefunden und mitgefixt: profil.batterieverlauf_tageswert_ aktualisieren() haengte in Einfuegereihenfolge an. Solange nur die Live-Aufzeichnung schrieb, war das dasselbe wie sortiert (sie traegt immer den heutigen Tag ein) - der Import traegt vergangene Tage nach, die waeren hinter den neueren gelandet und das Diagramm haette zeitlich rueckwaerts gelaufen. Sortiert jetzt nach Datum, wie der eigene Docstring es ohnehin versprach. Auslieferstand bereinigt: einstellungen.py brachte zwei Entity-IDs einer laengst abgeraeumten Testinstanz mit (testzone_fmm003_...). Beim Testen unsichtbar, weil die Testinstanz sie ueber entitaeten.json ueberschreibt - auf einer Neuinstallation waeren sie die wirksamen Werte gewesen. Und schlimmer als nur wirkungslos: fahrterkennung.py registriert seinen @state_trigger nur, wenn das Feld belegt ist, ausdruecklich als Schutz gegen eine leere Entity-ID. Ein gesetzter, aber nicht existierender Wert hebelt genau diesen Schutz aus. Beide Felder jetzt leer wie alle anderen; Kopfkommentar der Datei ueberarbeitet, er behauptete noch, die EU-Data-Act-Integration werde nicht mehr verwendet. install.ps1 abgesichert, da die erste echte Installation auf HA OS ansteht: die feste configuration.yaml.bak wurde bei jedem Lauf ueberschrieben, ausgerechnet das Original war nach dem zweiten Lauf weg - Sicherungen jetzt zeitgestempelt. Nach dem Schreiben wird die Datei zurueckgelesen und geprueft (Laenge, genau ein Markerblock, bisheriger Inhalt unveraendert); bei der kleinsten Abweichung rollt das Skript automatisch zurueck. Die Sicherheitseigenschaften stehen jetzt im Kopf der Datei, statt dass man ihnen glauben muss. Standort-Blatt: "Teilen" war im Tagmodus unsichtbar - .standort-pille nutzte var(--tile), das Blatt darunter var(--tile-deckend), und die iOS-Auflage setzt im Tagmodus beide auf #FFFFFF. Gemessener Kontrast 1,00:1, weiss auf weiss. Beide Pillen folgen jetzt der Knopfsprache des Panels (.aktion / .aktion.primaer): Umriss fuer die Nebenaktion, var(--fg) gefuellt fuer "Route". Danach 17-21:1 Textkontrast in beiden Themes. Nebenbei ist damit --line-strong - eine Linienfarbe - nicht laenger als Knopffuellung im Einsatz. Geprueft: Import zweimal ueber die echte Oberflaeche im Browser gegen eine in die recorder-DB eingespielte Kunsthistorie (der Testcontainer laeuft nicht, waehrend das Auto faehrt, echte Fahrten liegen dort also nicht vor) - drei Fahrten wie erwartet, die 5-Minuten-Unterbrechung korrekt zu einer 50-Minuten-Fahrt verschmolzen, die 30-Sekunden-Zuendung verworfen, Strecken kilometergenau; zweiter Lauf legte 0 an und meldete 3 als vorhanden. Neuinstallation in einem Wegwerf-Container: nur Profilvorlage und Parser, keine Fahrten-/Tank-/Batteriedatei, null Fehler im Log. install.ps1 gegen Attrappen: -Pruefen schreibt nichts, echter Lauf laesst automations.yaml bytegleich (SHA-256) und fremde Bloecke stehen, Ergebnis parst als gueltiges HA-YAML, zweiter Lauf idempotent, bei fremdem pyscript:/panel_custom: bleibt die Datei bytegleich. tsc --noEmit sauber, companion-app-Tests 106/106, vite build sauber, HA-Configcheck und Start ohne Fehler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
f115af50ab |
Versicherung/Steuer: Wortlaut-Feinschliff und Vertrag komplett editierbar
Mein-Audi-Kachel "Versicherung/Steuer" (vAudi()) und Kfz-Steuer-Detail (vSteuer()): "Zusammen" heisst jetzt "Summe", die Fusszeile "feste Kosten im Jahr" darunter entfaellt ersatzlos. Die Kfz-Steuer-Zeile zeigt "im Jahr" statt des rohen Datenwerts "jaehrlich", deckungsgleich mit der Versicherungs-Zeile darueber - nur wenn steuer.zeitraum tatsaechlich "jaehrlich" ist. Der gespeicherte Wert und die "jaehrlich"/"halbjaehrlich"-Auswahl in vSteuerBearbeiten() bleiben unveraendert, das war ein reiner Anzeige-Fix, keine Datenmodell- Aenderung. companion-app hatte an keiner der beiden Stellen ein Gegenstueck (kein "Zusammen"-Tile, keine Nur-Lese-Anzeige des Zeitraums) - dokumentiert als vorbestehende strukturelle Luecke statt kommentarlos uebersprungen. Vertrag-Kachel: war komplett nur lesbar (Gesellschaft, Umfang, Vertragsnummer, Selbstbeteiligung, Schadenfreiheitsklasse). Neue vVertragBearbeiten()-Ansicht (Panel, Route "vertrag") ueber ein neues Zahnrad auf der Vertrag-Kachel - alle Felder editierbar, Selbstbeteiligung zusaetzlich mit Hinzufuegen/Loeschen pro Zeile (neue .zeile-loeschen-Klasse, 44x44pt-Tippflaeche wie .km-edit). Die aktuelle Schadenfreiheitsklasse bleibt bewusst nur ueber "Beitrag anpassen" editierbar (Querverweis statt Duplikat), nur "zuvor" (sfAlt) ist neu in der Vertrag-Ansicht. companion-app: neue Vertrag()-Seite (Route "vertrag", eigene NaviKachel auf der Versicherungs-Seite) nach dem dortigen etablierten Muster (lokaler Entwurf-State + expliziter Speichern-Knopf statt Panel-Autosave pro Feld - gleiches Verhalten, eigenes Idiom). Die bisherige Nur-Lese-Selbstbeteiligung in Vertragsdetails() entfaellt, da sie jetzt (editierbar) in Vertrag() lebt. Schadenfreiheitsklasse wird in companion-app bewusst nicht ergaenzt: das Feld war dort noch nie sichtbar, auch nicht lesend - eine komplette neue UI-Sektion dafuer waere kein "Zeile editierbar machen" mehr, sondern ein neues Feature; als Luecke dokumentiert statt still uebergangen. tsc --noEmit sauber, companion-app-Tests 100/100 (inkl. dem Alle-Seiten-Rendertest, der jetzt auch "vertrag" abdeckt), vite build erfolgreich. Panel live im Docker-Testcontainer geprueft: Zeile hinzufuegen/bearbeiten/loeschen, Daten bleiben nach Re-Render erhalten. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
23b6defa68 |
Service-Termine: CI-Icons statt Wortlaut, Anstehende-Termine neu gegliedert
Naechster-Service-Kachel (Uebersicht): das "bis zum Oelwechsel"/
"bis zur Inspektion" vor der Kennzahl entfaellt zugunsten der echten
Audi-CI-Icons oil-change/inspection (vom Nutzer als SVG geliefert,
verbatim uebernommen wie die uebrigen CI-Icons). Hauptuntersuchung hat
kein eigenes Icon (kein Restkilometer-Ziel) und zeigt stattdessen ihr
Datum in derselben 40px-Groesse wie die km-Zahlen, mit dem Wort
"Hauptuntersuchung" darunter statt "bis zur Hauptuntersuchung" - vorher
war das Datumsfeld kleiner (30px), um Umbruch zu vermeiden; am
laufenden Panel nachgemessen, dass 40px keinen Umbruch verursacht.
"vsl." wird ausgeschrieben zu "voraussichtlich am". bisText()/ART_BIS
(Panel) und bisText()/BIS_TEXT (companion-app) wurden durch die
Aenderung ueberfluessig und als Orphans entfernt.
Anstehende-Termine-Box (Service-Seite): aus der dt/dd-Liste werden drei
sichtbar getrennte Bloecke (Kopfzeile mit Icon + Name + optionalem
Werkstatt-Chip, optionale Herstellervorgabe-Zeile, grosse Kennzahl,
optionale Prognose-Fusszeile) - Apple HIG (Hierarchie ueber
Position/Groesse, Inhalt nicht mit Nebensaechlichem ueberladen) plus
Audi-CI (Flaeche mit Haarlinien statt Karten). Durchlief drei
Mockup-Runden als Artefakt vor der Umsetzung, zwei davon vom Nutzer
zurueckgewiesen ("Major Information is missing" bzw. Kommentare zu
Icon-Groesse/Herstellervorgabe/Ausrichtung).
Herstellervorgabe-Logik korrigiert: eine Fahrzeugmeldung stammt immer
aus dem werkseigenen Wartungsprogramm des Bordcomputers, unabhaengig
vom in "Einrichten" gewaehlten App-Intervall - zaehlt also immer als
Herstellervorgabe, nicht nur wenn der App-Modus zufaellig "hersteller"
ist. Die Prognose-Fusszeile zeigt die Restkilometerzahl nur noch beim
eigenen (kuerzeren) Intervall, bei Herstellervorgabe nur noch das
Datum. "Eigenes" in der Ölwechsel-Intervall-Auswahl umbenannt zu
"Individuell".
companion-app-Portierung ist eine echte Neustrukturierung: die
bisherige "Naechster Oelwechsel"-Kachel mischte Oelwechsel-,
Inspektions- und Hauptuntersuchungs-Zeilen in einer gemeinsamen
Werteliste, jetzt "Anstehende Termine" mit denselben drei Bloecken wie
im Panel. Neuer Export letzterInspektion() in service.ts. Zwei
dokumentierte, vorbestehende Luecken bleiben bestehen statt neu
kaschiert zu werden: kein Werkstatt-Chip (companion-app hat keine
"Termin vereinbaren"-Funktion), Herstellervorgabe kommt aus
fahrzeug.oel.modus statt einem intervalle()-Aequivalent (das es dort
nicht gibt).
npm run typecheck sauber, npm run test 99/99, npm run build erfolgreich.
Panel deployed als Version 1787013003, synchron in installationspaket/,
live im Docker-Testcontainer per DOM-Abfrage geprueft.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
600c92fd0f |
Service-Kennzahl als Kachel mit Hintergrund statt flach
Nutzerwunsch nach dem ersten Stand: der Block soll als Box mit Hintergrund
erscheinen. .tile.flat -> .tile; die Haarlinie trennt jetzt innerhalb der
Kachel, statt die Kachel zu ersetzen.
Der Chevron bleibt unveraendert auf right:0 relativ zum Knopf - da der
Knopf innerhalb des Kachel-Paddings sitzt, landet er damit automatisch auf
demselben Innenabstand wie ein normales .go in einer gepolsterten Kachel,
ohne Sonderregel.
Neu: .serviceblock:active{opacity:.55} als Tipp-Rueckmeldung. Ein
Hintergrundwechsel wie bei .tilebtn geht hier nicht, weil der Knopf schon
auf der Kachelflaeche liegt und nur ihr oberer Teil ist.
Beide Themes geprueft: Kachelhintergrund und Haarlinie kommen aus Tokens
(Tag rgb(255,255,255) / Nacht rgba(255,255,255,.055)), der Knopf selbst
bleibt transparent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
e56f2040e8 |
Uebersicht: fuehrende Service-Kennzahl statt zwei gleichrangiger Kacheln
Kilometerstand und Service standen als zwei identisch aussehende Kacheln
nebeneinander - 166x113px, gleiche 29px-Zahl, gleiche Farbe -, obwohl nur
die rechte ein Knopf war (erkennbar allein an einem 12px-Chevron) und die
beiden Zahlen Grundverschiedenes meinen: ein gemessener Ist-Wert gegen
einen taeglich schrumpfenden Countdown.
Neu, nach Abstimmung mit dem Nutzer und belegt an beiden Regelwerken
(Apple HIG "Layout"/"Widgets" live gelesen, Audi-CI aus dem
projekteigenen AUDI_CI_ARCHIV):
Naechster Service: >
9.029 km
bis zum Oelwechsel · vsl. 15.04.2027
------------------------------------
Kilometerstand 20.845 km
Das .duo-Raster entfaellt; der Block liegt in einer .tile.flat, also in
derselben Ebene wie die Reichweite darueber, statt in einem eigenen
Kachelcontainer. Der Chevron sitzt nur am .serviceblock-Knopf, nicht ueber
der ganzen Flaeche - damit bleibt erkennbar, welcher Teil bedienbar ist
und welcher reine Anzeige (HIG: "differentiate controls from content").
"Naechster Service" meint jede Serviceart; naechsterTermin() waehlte
ohnehin schon ueber Oelwechsel/Inspektion/Hauptuntersuchung aus, neu ist
die Beschriftung samt ART_BIS fuer den richtigen Artikel ("bis zum
Oelwechsel", aber "bis zur Inspektion"). Ohne Restkilometer
(Hauptuntersuchung) rueckt das Datum selbst ins Zahlenfeld, dann bei 30px
statt 40px.
Von der Aenderung verwaist und mitentfernt: mmjjjj() und die
.duo-Regeln in beiden Stylesheets.
Live geprueft bei 375px und 1280px: Block und Wertezeile fluchten mit der
Kachelkante, Chevron buendig rechts, Tippflaeche 88px; Klick auf den Block
oeffnet "Service", Klick auf die Kilometerstand-Zeile navigiert nicht.
Keine neuen Konsolenfehler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7319501ee6 |
Service-Seite: Prognose-Fussnote ueber volle Breite statt umgebrochen
Gemeldet: das Datum der Oelwechsel-Prognose steht in einer eigenen Zeile. Nachgemessen: das <small> in der rechten Spalte war 29px hoch bei 217px Breite (zwei Zeilen); .row ist ein Flex aus dt/dd, und dd bekommt nur den Rest neben dem Titel - fuer "9.029 km, voraussichtlich am 14.04.2027" reicht das bei 12,5px nicht. Statt an Schriftgroesse oder Text zu drehen, haengt die Fussnote jetzt als eigenes Element (.row-fussnote) neben dt/dd und bricht per flex:1 0 100% auf eine eigene Zeile ueber die volle Kachelbreite um. flex-wrap:wrap ist per :has(.row-fussnote) auf genau diese Zeilen eingegrenzt, damit die uebrigen .row-Verwendungen zweispaltig bleiben. Die verschachtelte fm-/nicht-fm-Verzweigung im Markup faellt dabei zu einem hatMeldung-Zweig fuer den Wert plus einem separaten fussnote-String zusammen; die Anzeigelogik selbst ist unveraendert. Live geprueft bei 375px und 1280px: beide Fussnoten einzeilig (14px), 307px bzw. 636px breit; alle 17 .row auf "Mein Audi" weiterhin zweispaltig; keine neuen Konsolenfehler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7fc378f427 |
Übersicht: Wert und Kontext trennen statt "9,0 tkm/ 04/27"
Auf Nachfrage, wie Apple HIG und die Audi-CI die beiden Kacheln loesen
wuerden - beide laufen auf dieselbe Antwort hinaus.
Die Oelwechsel-Kachel presste zwei verschiedene Groessen in ein
Zahlenfeld: Restkilometer und Prognosedatum, getrennt durch einen
Schraegstrich. Zwei Einheiten, davon eine erfundene ("tkm" schreibt
niemand - die Mein-Audi-Servicebox nannte dieselbe Zahl schon immer
"9.029 km"), zwei Schraegstriche mit zwei Bedeutungen, und auf 375px
zweizeilig umgebrochen.
Apple HIG "Layout" ("don't obscure essential information by crowding it
with nonessential details") und "Typography" (Hierarchie ueber Groesse
und Farbe) verlangen die Trennung; die Audi-CI definiert .fig
ausdruecklich als "large numeric figures" - eine Zahl, nicht zwei.
- Wert gross (9.029 km), Kontext leise darunter (vsl. 04/2027)
- Echte Einheit statt "tkm"
- Kachel ist jetzt ein Knopf mit Chevron zur Service-Seite; vorher eine
Sackgasse, obwohl es die Seite gibt
- mmjj() dadurch verwaist, ersetzt durch mmjjjj() mit vollem Jahr
- HU-/Inspektionszweig faellt mit dem Oelwechselzweig zusammen, weil sie
nach der Trennung dieselbe Form haben
companion-app hatte diesen Fehler nicht (dort standen die Termine schon
als Label/Wert/Zusatz). Dort stattdessen der benachbarte
Gruppierungsfehler behoben: die Service-Zeilen hingen innerhalb der
Kilometerstand-Kachel und fuehrten nirgendwohin - jetzt eigene,
antippbare Kachel zur Service-Seite.
Live geprueft im Panel (Tag und Nacht, 375px): beide Kacheln einzeilig,
Tippen oeffnet Service. companion-app: typecheck sauber, 95/95 Tests,
Build erfolgreich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
126033e4dd |
Fahrt-Formular: Ankunftszeit statt Dauer, Art gross, neutrale Pille
Fuenf gemeldete Punkte plus ein Theme-Bug beim Nachpruefen: - "Dauer" ist kein Eingabefeld mehr - stattdessen Ankunftszeit, die Dauer wird aus Start/Ankunft berechnet und live angezeigt (fahrtZeitraum()/ dauerText()), inklusive Fahrten ueber Mitternacht. - Art-Werte werden grossgeschrieben angezeigt (Privat/Arbeitsweg), der gespeicherte Wert bleibt klein (artText()-Helfer). - Arbeitsweg-Pille ist nicht mehr rot - sieht jetzt aus wie Privat. - "tippen zum Umschalten" unter der Pille entfernt. - Bild-Platzhalter (Einstellungen) war im Tag-Theme unsichtbar: --tile wird dort vom iOS-Overlay auf reines Weiss gesetzt, identisch mit Canvas/ Kacheln. Auf --ios-fill umgestellt, in beiden Themes sichtbar grau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2d76f10c1c |
Fahrten bearbeitbar, Inspektionsprognose, Bootstrap-Takt reisst nicht mehr ab
Sechs gemeldete Punkte plus ein Fund beim Nachlesen des Ladevorgangs: - HECKKLAPPENSCHLOSS_SENSOR ueberall entfernt (einstellungen.py, entitaeten.py-Katalog, _sicherheitscheck()). HECKKLAPPE_SENSOR bleibt. - Bild-Platzhalter in den Einstellungen war halb abgeschnitten: die bare .carfix-Regel der Desktop-Container-Query traf auch den Platzhalter-Div, dessen inset:0 von der festen Hoehe uebersteuert wurde. Auf .bildbox eingegrenzt. - Inspektion bekommt eine eigene "voraussichtlich am ..."-Zeile (nur Datum). oelwechselPrognose() dafuer auf den gemeinsamen Kern servicePrognose() zurueckgefuehrt. - "Neue Fahrt" bietet jetzt alle Felder, die die Einzelfahrt anzeigt, und die Einzelfahrt laesst sich bearbeiten - gemeinsames fahrtFelder()/ fahrtFormularWerte() nach dem Muster von tankFelder(). Backend: Service audi_dashboard_fahrt_aktualisieren, profil.fahrt_bearbeiten() (edited_fields schuetzt gegen die Automatik, nicht gegen den Nutzer). Die Art-Pille speichert jetzt ebenfalls statt nur lokal umzuschalten. - Titelzeile steht auf dem Handy buendig zu den Kacheln: .back:not(.on) gibt seine Breite und den Gap auf allen Breiten frei, .topbar links 16px. - Ladebildschirm: nachladeAnstossen() und datenLaden() stiegen bei fehlendem HASS aus, ohne eine naechste Runde zu planen - genau die Sackgasse, aus der bisher nur ein Menueklick half. Beide planen jetzt weiter, der Timer wird beim Abhaengen gestoppt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
91dfd4807a |
Drop the Strg+V hint: PC gets drag-and-drop and file picker only
Ctrl+V does not reach the dialog either - Chrome only delivers a paste gesture when there is a paste target, and the dialog has no input field. So the shortcut is no longer mentioned anywhere; the computer now offers exactly two routes, dragging and the file picker, and the phone keeps the clipboard button. The paste listener stays as a silent bonus for browsers that do deliver the event, and the now-orphaned tastenkuerzelEinfuegen() is gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e5e82b3634 |
Fix clipboard paste on PC, round price per litre to 2 decimals
The "paste from clipboard" button could never work on a desktop: clipboard.read() only ever exposes text, HTML and images by spec, so a file copied in Explorer is not offered through it - and the dialog then wrongly blamed the file for not being a PDF. It is now hidden on pointer-coarse devices only, where it does work; on a PC the drop zone names Strg+V, which is the path that carries the actual file. Detection also relied solely on the MIME type, but a file copied or dragged from Explorer can arrive with an empty type and was rejected - istPdf() now falls back to the extension. Price per litre now shows 2 decimals everywhere (list, receipt detail, both entry forms, CSV) instead of 3. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5aaf1cd958 |
Fix pull-to-refresh on touch devices, add drag/paste receipt upload
The pull-to-refresh gesture logic was already correct (verified by driving real pointer events through it); what was missing was overscroll-behavior on the scroll container, so on real touch hardware the browser's own native overscroll could take the gesture over before it hit the threshold. "Beleg hochladen" now opens a dialog instead of the native file picker: drag a PDF in at the computer, paste it from the clipboard on the phone (copied out of a mail), file picker kept as a third route. All three sources share one upload path. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8a751fe441 |
Run a full Apple HIG audit; fix silent save failures and popup polish
Read Tab Bars, Sidebars, Sheets, Alerts, Action Sheets, Toolbars, Buttons, Pickers, Loading, Feedback, Privacy, and Undo/Redo off developer.apple.com and cross-checked each against the actual code. profilSpeichern() (the shared save path for ~25 fields) had no error handling at any call site, so a failed backend write was an unhandled promise rejection with zero user feedback - fixed centrally, plus the same for serviceRufen(). Also added a spinner to the "Ladt ..." bootstrap screen and gave the Anzugsmoment/km-correction popups the same primary-button styling the Setup popup already used. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
6bf7435434 |
Add real Audi CI battery/edit icons, manual km-correction for tire sets
Replaced the hand-drawn placeholder battery icon with the real Audi CI battery-12v-l/-s (user supplied the actual SVGs) next to "Ruhespannung", matching the existing poi-l/poi-s size-variant convention. Added a km-correction control to the Sommerräder/Winterräder tiles: a pencil icon (Audi CI edit-s) opens an inline field to manually correct the tire-set's accumulated km. The tricky part was persistence - configCarZuProfil() deliberately never writes km back (a stale browser copy could otherwise clobber a since-elapsed automatic increment), so this needed its own backend service, audi_dashboard_reifen_km_setzen, that overwrites only the stored counter and leaves referenz_odo_km alone - the existing odometer-delta tracking in reifenzaehler.py then continues accumulating from the corrected value on its own, no other backend change required. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8b3e5b2b8f |
Rename Sommer/Winter to Sommerräder/Winterräder, reflow Reifen tile headline
The tile headline now reads "Sommerräder"/"Winterräder" and renders as an actual headline (new .tile-headline class, 20px/var(--fg)) instead of the small muted .label styling used for other in-tile section titles. Headline + km now sit above "Montiert" instead of the wheel photo overlaying it: new .radkopf-row (flex) puts headline/km and the photo side by side at the tile's top; Montiert dropped position:absolute (no longer needed once the photo stopped sharing its space) and is now a normal-flow pill below the headline block. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ec55e5808e |
Fix real tab-bar-icons-vanish bug, dropdown popup color, wheel/Montiert swap
The reported "whole tab bar disappears when hiding labels" bug was real,
just one level deeper than first checked. .tabbar.ohne .tab span{display:
none} targeted the label span, but the icon is also wrapped in a <span
class="tabpille"> - a bare "span" type selector doesn't care about class,
so the icon's own wrapper collapsed too. Confirmed by measuring the <svg>
directly (0x0 bounding rect) after a live screenshot showed all 5 tab
buttons empty. Fixed with :not(.tabpille) in both stylesheets.
The Modell dropdown was still bright despite the color-scheme hint from
the last commit: a <select>'s opened option list is rendered by the
browser/OS as its own surface, entirely outside the page's paint tree -
confirmed when a screenshot call hung 30s trying to capture it open.
color-scheme only gets partial credit there; explicit background-color/
color on <option> is what Chrome/Firefox/Edge actually honor for the
popup rows. Added that, verified via getComputedStyle since the open
popup itself can't be screenshotted by this tooling.
Swapped the wheel photo (now right-aligned via margin-left:auto on the
now-correctly-square .bildbox.radbild) and Montiert (already left) per
request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
17b25d492a |
Fix wheel-photo squareness bug, native select popups, image-cycle crash
.bildbox.radbild lost to a same-specificity, later-declared .bildbox rule, so the wheel photo stayed a full-width 4:3 box despite the earlier crop fix - only which slice showed ever changed. Fixed with a compound selector and moved "Montiert" to top-left to match the now-correctly-sized photo. Native <select> popups had no color-scheme hint and rendered in the browser's default light palette regardless of the app's dark theme - this is what made "Modell" and other dropdowns flash bright white. bildWeiter() (Mein Audi image-cycle tap) referenced a CSS class that was never emitted (.platzhalter-datei vs. the real .platzhalter-aktion), throwing and aborting before the page-dot indicator update - the photo advanced but the dots never moved. Merged the separate "Fahrzeugbilder" upload grid into "Bild der Übersicht": pick a view from the existing dropdown, tap its preview to upload/replace/delete - same generic popup plumbing, no new mechanism. Removed the now-dead BILDER_UPLOAD_SLOTS/.bildgrid/.bildslot/.carfix.mini. Back arrow changed from red to the neutral headline color, matching every other navigation-color decision in this project. Investigated but could not reproduce: user-reported "whole tab bar disappears" when hiding labels. Traced the exact commit that added the icon+label highlight and confirmed it's correctly scoped to :not(.ohne); live DOM/computed-style testing across toggle, navigation, and both mobile/desktop widths showed the tab bar staying visible throughout. Left unchanged pending a repro from the user. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
367985ba44 |
UI polish batch + fix genuinely-invisible map pins, Apple HIG audit
Battery voltage stat cutoff 13.2V -> 12.8V (values above that are already alternator output, not the battery); fixed the battery chart's Y-axis "stretching" on zoom by computing it once from the full dataset; removed two explanatory paragraphs from the battery detail view; Tankfuellung now shows "X % / X l"; removed the "noch etwa X l im Tank" suffix; fuel bar color now matches the headline instead of a red/yellow/green gradient; active/primary buttons are grey again, not red (destructive stays red per HIG); select fields gained an Apple-HIG pull-down chevron (appearance:none had removed the native one with nothing replacing it); selected menu icon is white on desktop, matching mobile; Reifenfoto crops from the right edge; "Montiert" button rebuilt as a compact top-right pill with a 44px invisible tap target; tab-bar active highlight now covers icon+label, not just the icon; removed two leftover explanatory texts from Einstellungen. Root-caused the map pins looking "transparent": the CI poi-car/poi icons are pure contour forms (nonzero-fill-rule ring + thin detail lines, only 13-40% of their own bounding box actually filled). Fixed by extracting each icon's own first sub-path (the true outer balloon silhouette, verified by rasterizing it in isolation) as a solid-filled layer behind the original icon, applied to both the vehicle and station markers. Read Color/Typography/Layout/Buttons/Materials on developer.apple.com and applied the user-approved subset (11px text floor, 44px tap targets); declined items (font weight, materials) documented with rationale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
899b770cfa |
Einzelbeleg: CI poi pin from the receipt address, plus a centre button
The station marker was a red circleMarker. It is now the CI poi pin (poi-l/poi-s via tankstellenMarkerSVG) - the plain pin rather than poi-car, so the vehicle and the station stay distinguishable on a map. While testing it turned out nothing in the backend ever writes station_lat / station_lon, so that marker had never been reachable in practice. The receipt address is now geocoded in the frontend via Nominatim /search (adresseAufloesen, the forward counterpart to the existing reverse lookup), with results cached in localStorage - negative ones too, since a station address does not move and Nominatim's terms ask for caching. Verified live: "Shell, SÖLDEN" resolves to 46.9756 / 11.0111. The map card gained a centre button (CI.gps, which is byte-identical to the delivered gps-s.svg), disabled until the coordinates arrive. .mapbox needed position:relative so the control anchors to the card instead of an ancestor. Only in the Einzelbeleg, as requested - the Standort fullscreen already has its own centre controls. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
484f2ffe6d |
Add one-click installer to installationspaket
Installieren.cmd (double-click) wraps install.ps1, which automates steps 1-3 of ANLEITUNG.md: find the HA config share, copy pyscript/, data/ -> audi_dashboard/ and www/, merge the configuration.yaml snippet, optionally write ha_token.txt. The .cmd wrapper exists because double-clicking a .ps1 opens it in an editor and the execution policy blocks it; the bypass applies to that one call only. Designed to be safe to re-run: - Never overwrites fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl, entitaeten.json or ha_token.txt, so re-running on a live install keeps the vehicle profile, trips, fills and sensor mapping. - configuration.yaml is backed up to .bak first; the inserted part sits between marker lines and gets replaced instead of appended twice. - If pyscript: or panel_custom: are already there from another source, the file is left untouched and the script prints what to merge by hand - duplicate top-level keys would be invalid YAML and HA would not start. - Aborts before writing if the target has no configuration.yaml. Steps that cannot be automated from a Windows share (HA restart, pip install pypdf, sensor mapping) are collected into a closing to-do list. -Pruefen shows what would happen without writing. install.ps1 is stored UTF-8 *with* BOM - PowerShell 5.1 reads scripts as ANSI otherwise and mangles the umlauts; the files it writes stay BOM-less. Verified against a fake config tree: fresh install, re-run idempotency, existing-data preservation, foreign-key refusal, wrong-directory abort, and the merged configuration.yaml parses as valid YAML. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fb38c297bd |
Station name as "brand, street, city", grey box on all editable fields
The "grey box around the icons" report turned out not to be a defect: the box on "10.000 km"/"1 Jahr"/"15" is the wanted pattern, and every value the user can change should carry it. All .feld inputs and selects now get the grey iOS fill; inputs with their own visual language (checkbox/radio/range/file) keep the transparent base rule, so the switches are unaffected. Fuel stations are now displayed as "Shell, Pascalstr. 8, Ingolstadt" instead of the bare operator name. New _marke()/_ist_strasse()/_tankstelle() helpers are shared by both parser paths so Shell and non-Shell receipts format the same. The brand is only matched against the receipt header - searching the whole text would let "Total" hit a totals line. Missing parts are dropped instead of leaving empty comma slots, and without a known brand the operator name takes its place. station_address still carries the full street and postcode. test_bekannte_stationen updated to the new format; suite stays green. installationspaket/ is versioned from now on (user request). It contains no real vehicle data - only the example profile with empty FIN/plate placeholders. Keep it in sync whenever pyscript/ or www/ changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |