diff --git a/AGENTS.md b/AGENTS.md index 0d73752..ca06732 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11598,3 +11598,69 @@ Der eigentliche Grund auf der **realen** Instanz ist ein anderer und heute zuerst gefunden worden: dort wurden ueberhaupt keine Fahrten erkannt, weil die Erkennung still das Trip-Signal des Dongles bevorzugte, das nie ankam. Ohne Fahrten kein Radstand. + +## CT. Kachelueberschriften: der Abstand war das Problem, nicht die Schrift (2026.9.5.11) + +Auftrag: *"Kachelueberschriften im Panel wie in der App setzen"*. Der Auftrag +beruhte auf einer Falschaussage von mir - ich hatte behauptet, die App setze +dort 10px in Grossschrift mit 0.2em Sperrung. Das steht so im **Design-System**, +das die App an dieser Stelle aber absichtlich ueberschreibt. Live gemessen sind +beide identisch: + +| | Panel `.label` | App `.ads-eyebrow` | +|---|---|---| +| Groesse | 13px | 13px | +| Gewicht | 400 | 400 | +| Farbe | rgb(142,142,147) | rgb(142,142,147) | +| Grossschrift | nein | nein | +| Sperrung | 0.13px | 0.13px | + +`companion-app/src/stile/audi-schrift.css` traegt die Begruendung seit dem +29.08.2026: die App soll optisch moeglichst identisch zum Panel sein. "Panel wie +App" waere also folgenlos geblieben. **Lehre: die gerenderte Oberflaeche messen, +nicht die Quelle des Pakets lesen** - dieselbe Verwechslung wie beim +Ringe-Fehlalarm in Abschnitt CS, am selben Tag. + +### Was tatsaechlich fehlte + +Der Abstand zwischen Ueberschrift und erster Inhaltszeile haengt davon ab, ob +das folgende Element zufaellig einen eigenen oberen Rand mitbringt. Gemessen +ueber fuenf Seiten: **0px, 10px, 12px** - je nach Kachel. Bei 0px klebt die +Ueberschrift an der ersten Zeile und liest sich als deren Beischrift. + +Der Rand sitzt jetzt an der Ueberschrift selbst, nicht am folgenden Element: + + .tile > .label:first-child { margin-bottom: 14px } + .ads-tile > .ads-eyebrow:first-child { margin-bottom: 14px } + +Drei Gruende fuer genau diese Bauweise: + +* `.tile`/`.ads-tile` sind normale Blockcontainer - benachbarte Raender fallen + zusammen. Vorhandene 10 oder 12px werden dadurch auf 14 **angehoben statt + addiert**. Ein `+ *`-Selektor haette sie addiert. +* Absolut gesetzte Nachbarn (Zahnrad, Chevron) stehen nicht im Fluss und + bleiben unberuehrt. Ein `margin-top` auf ihnen haette das Zahnrad erneut aus + der Ecke geschoben - genau der Fehler aus Abschnitt CS. +* `:first-child` trifft nur die Ueberschrift. `.label`/`.ads-eyebrow` tragen + auch Inhaltszeilen (die Anschrift des Autohauses), und die bleiben wie sie + sind - Entscheidung des Eigentuemers. + +Nachgemessen: alle Kachelkoepfe auf beiden Seiten bei 14px, Anschrift +unveraendert 13px, Zahnrad weiter bei 8/8. + +### Einmalige Bereinigung des Profils + +Auf Wunsch des Eigentuemers entfernt `_profil_aufraeumen()` in `koordinator.py` +ausgemusterte Profilfelder beim Start - Anlass ist +`fahrzeug.hauptuntersuchung_faellig` aus Abschnitt CR. Ohne das bliebe der tote +Schluessel fuer immer stehen: beide Oberflaechen lesen das Profil, aendern +einzelne Felder und schreiben es vollstaendig zurueck, unbekannte Schluessel +ueberleben das also. + +Geschrieben wird nur, wenn wirklich etwas wegfaellt. An der Testinstanz +geprueft: Schluessel gesetzt, Neustart, Logzeile *"Ausgemusterte Profilfelder +entfernt: fahrzeug.hauptuntersuchung_faellig"*, Schluessel weg - und beim +zweiten Neustart keine Meldung und kein Schreibvorgang. + +Weitere ausgemusterte Felder gehoeren in `AUSGEMUSTERTE_PROFILFELDER`, nicht in +neuen Sondercode. diff --git a/companion-app/src/stile/screens.css b/companion-app/src/stile/screens.css index 17f1200..178aa88 100644 --- a/companion-app/src/stile/screens.css +++ b/companion-app/src/stile/screens.css @@ -522,6 +522,26 @@ button.dm-serviceblock:active { } /* `.zahnrad` im Panel: rechts oben in der Kachel, 44px Trefferfläche, 17px Symbol. */ +/* Luft unter der Kachelueberschrift. + + Der Abstand zur ersten Inhaltszeile haengt heute davon ab, ob das + folgende Element zufaellig einen eigenen oberen Rand mitbringt - am + 05.09.2026 gemessen: 0px, 10px oder 12px, quer durch die Kacheln. Wo er + 0 war, klebte die Ueberschrift an der ersten Zeile und las sich als deren + Beischrift statt als Titel (gemeldet: "Anstehende Termine" wirkte, als + gehoere es zu Oelwechsel). + + Der Rand steht bewusst an der UEBERSCHRIFT, nicht am folgenden Element: + .ads-tile ist ein normaler Blockcontainer, benachbarte Raender fallen + also zusammen. Vorhandene 10 oder 12px werden dadurch auf 14 angehoben + statt addiert, und absolut gesetzte Nachbarn - Zahnrad, Chevron - bleiben + unberuehrt, weil sie gar nicht im Fluss stehen. + + Nur die ERSTE Beschriftung einer Kachel: .ads-eyebrow traegt auch + Inhaltszeilen wie die Anschrift des Autohauses, und die sollen bleiben, + wie sie sind (Entscheidung des Eigentuemers, 05.09.2026). */ +.ads-tile > .ads-eyebrow:first-child { margin-bottom: 14px; } + .dm-kachel--zahnrad { position: relative; } diff --git a/custom_components/audi_dashboard/frontend/app/bundle.json b/custom_components/audi_dashboard/frontend/app/bundle.json index e48bbc3..6cb24d4 100644 --- a/custom_components/audi_dashboard/frontend/app/bundle.json +++ b/custom_components/audi_dashboard/frontend/app/bundle.json @@ -1 +1 @@ -{"version":"2026.9.5.10","sha256":"6bdd14f277d1d3f6f2c24dc0ab660f2751daac8fc71efdb14440df87fe7a5af6","bytes":324448,"gebaut":"2026-09-05T00:22:21Z"} \ No newline at end of file +{"version":"2026.9.5.11","sha256":"66b5170e70ed6879bea70b44bebef30a04b6f0a7ea3d072bd32b7cc0c1c9e412","bytes":324454,"gebaut":"2026-09-05T00:34:25Z"} \ No newline at end of file diff --git a/custom_components/audi_dashboard/frontend/app/bundle.zip b/custom_components/audi_dashboard/frontend/app/bundle.zip index 8cafcb6..25bf657 100644 Binary files a/custom_components/audi_dashboard/frontend/app/bundle.zip and b/custom_components/audi_dashboard/frontend/app/bundle.zip differ diff --git a/custom_components/audi_dashboard/frontend/audi-dashboard.css b/custom_components/audi_dashboard/frontend/audi-dashboard.css index ff4d960..3965563 100644 --- a/custom_components/audi_dashboard/frontend/audi-dashboard.css +++ b/custom_components/audi_dashboard/frontend/audi-dashboard.css @@ -345,6 +345,26 @@ button.tile, .tilebtn { transition: background .15s, transform .1s; } .zahnrad:hover { background: var(--tile-2); color: var(--fg); } .zahnrad:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); } .zahnrad svg { width: 17px; height: 17px; } +/* Luft unter der Kachelueberschrift. + + Der Abstand zur ersten Inhaltszeile haengt heute davon ab, ob das + folgende Element zufaellig einen eigenen oberen Rand mitbringt - am + 05.09.2026 gemessen: 0px, 10px oder 12px, quer durch die Kacheln. Wo er + 0 war, klebte die Ueberschrift an der ersten Zeile und las sich als deren + Beischrift statt als Titel (gemeldet: "Anstehende Termine" wirkte, als + gehoere es zu Oelwechsel). + + Der Rand steht bewusst an der UEBERSCHRIFT, nicht am folgenden Element: + .tile ist ein normaler Blockcontainer, benachbarte Raender fallen + also zusammen. Vorhandene 10 oder 12px werden dadurch auf 14 angehoben + statt addiert, und absolut gesetzte Nachbarn - Zahnrad, Chevron - bleiben + unberuehrt, weil sie gar nicht im Fluss stehen. + + Nur die ERSTE Beschriftung einer Kachel: .label traegt auch + Inhaltszeilen wie die Anschrift des Autohauses, und die sollen bleiben, + wie sie sind (Entscheidung des Eigentuemers, 05.09.2026). */ +.tile > .label:first-child { margin-bottom: 14px; } + /* Titelzeile nie unter dem Zahnrad/Chevron hindurchlaufen lassen - und die Zeile hoch genug für die 44px-Trefferfläche des Zahnrads machen. Ohne die Mindesthöhe ragte es in den Kachelinhalt und lag auf dem ersten Knopf diff --git a/custom_components/audi_dashboard/koordinator.py b/custom_components/audi_dashboard/koordinator.py index df2f73e..754b352 100644 --- a/custom_components/audi_dashboard/koordinator.py +++ b/custom_components/audi_dashboard/koordinator.py @@ -93,6 +93,15 @@ from .zuordnung import Zuordnung _LOGGER = logging.getLogger(__name__) +# Profilfelder, die es einmal gab und die niemand mehr liest. +# +# Sie einfach stehenzulassen ist keine Loesung: beide Oberflaechen lesen das +# Profil, aendern einzelne Felder und schreiben es vollstaendig zurueck - +# unbekannte Schluessel ueberleben das fuer immer. Siehe _profil_aufraeumen(). +AUSGEMUSTERTE_PROFILFELDER: dict[str, tuple[str, ...]] = { + "fahrzeug": ("hauptuntersuchung_faellig",), +} + # Wie weit zurück nach dem letzten Zündungswechsel gesucht wird, wenn der # Parkbeginn nach einem Neustart fehlt. Sieben Tage decken jede realistische # Standzeit ab und bleiben eine Abfrage, die der recorder in einem Rutsch @@ -191,6 +200,7 @@ class Koordinator: "Fahrzeug einrichten eingetragen." ) await self.zuordnung.anwenden() + await self._profil_aufraeumen() await self._laufzeit_laden() # Die "Zustand"-Kachel soll die zuletzt gemessene Batteriespannung # auch direkt nach einem Neustart zeigen, nicht erst "unbekannt" bis @@ -213,6 +223,38 @@ class Koordinator: async_at_started(self.hass, self._nach_start) ) + async def _profil_aufraeumen(self) -> None: + """Entfernt ausgemusterte Felder einmalig aus dem Fahrzeugprofil. + + Beide Oberflächen lesen das Profil, ändern darin einzelne Felder und + schreiben es vollständig zurück - unbekannte Schlüssel überleben das + also für immer. Ein ausgemustertes Feld bliebe damit in jeder + Profildatei stehen, obwohl es niemand mehr liest. + + `hauptuntersuchung_faellig` ist der Anlass (Abschnitt CR in + AGENTS.md): es hatte in keiner Oberfläche ein Eingabefeld und im + Backend kein Schema, überstimmte von dort aber die Ableitung der + Hauptuntersuchung. Seit 2026.9.5.3 liest es niemand mehr. + + Geschrieben wird nur, wenn wirklich etwas wegfällt - sonst wäre das + bei jedem Start ein Schreibvorgang ohne Änderung.""" + profil = await self.ablage.profil_lesen() + if profil is None: + return + entfernt: list[str] = [] + for bereich, felder in AUSGEMUSTERTE_PROFILFELDER.items(): + teil = profil.get(bereich) + if not isinstance(teil, dict): + continue + for feld in felder: + if feld in teil: + teil.pop(feld) + entfernt.append(bereich + "." + feld) + if not entfernt: + return + await self.ablage.profil_schreiben(profil) + _LOGGER.info("Ausgemusterte Profilfelder entfernt: %s", ", ".join(entfernt)) + async def _nach_start(self, _hass: HomeAssistant) -> None: await fahrterkennung.nach_neustart_fortsetzen(self) await self._parkbeginn_nachholen() diff --git a/custom_components/audi_dashboard/manifest.json b/custom_components/audi_dashboard/manifest.json index 2b905bd..61f9f31 100644 --- a/custom_components/audi_dashboard/manifest.json +++ b/custom_components/audi_dashboard/manifest.json @@ -1,7 +1,7 @@ { "domain": "audi_dashboard", "name": "Audi Dashboard", - "version": "2026.9.5.10", + "version": "2026.9.5.11", "documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md", "issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues", "codeowners": [