Zwei Dokumente, beide reine Analyse - kein Code geaendert.
REVIEW_main_2026-08-13.md: 15 Befunde aus den Commits c66ed82..d5562c7,
nach Schaden sortiert, jeder mit Datei-Zeile und der Kette vom Ausloeser zur
Auswirkung. Die drei schwersten liegen im neuen Setup-Menue:
1. Speichern, solange der Katalog noch nicht geladen ist, ueberschreibt
entitaeten.json mit {} und loescht alle Zuordnungen. Faellt erst beim
naechsten Neustart auf, weil die setattr-Werte im Prozess bestehen
bleiben - und entitaeten.json wird von backup.py nicht gesichert.
2. "Zuruecksetzen" wirkt bei 15 von 17 Feldern nicht, weil
overrides_anwenden() leere Werte ueberspringt und der Standardwert bei
fast allen Feldern leer ist. Isoliert nachgestellt.
3. Alle vier Listenpositionen bekommen denselben Sensor, weil der
Vorschlag den Index nicht auswertet. Folge: der Sicherheitscheck prueft
viermal dieselbe Tuer und meldet "Sicher abgestellt", obwohl drei Tueren
nie geprueft wurden.
Jeder Befund ist als belegt oder plausibel gekennzeichnet.
ha_install.md: Plan fuer die Umstellung von pyscript auf eine eigene
Integration mit Konfigurationsdialog - Einrichtung komplett ueber die
Oberflaeche, kein YAML, Updates als Knopfdruck. Alle genannten
Schnittstellen sind an der laufenden 2026.8.1-Instanz geprueft, inklusive
Signaturen.
Zur Verteilung: HACS kann ausschliesslich GitHub und scheidet fuer das
Gitea-Repository aus. App-Repositories akzeptieren zwar beliebige Git-URLs,
Apps sind aber Docker-Container und damit der falsche Behaelter fuer eine
Integration. Nativ bleibt eine eigene UpdateEntity, deren Logik in
updateverwaltung.py bereits zu grossen Teilen existiert.
Festgehalten ist ausserdem, welche der Review-Befunde die Umstellung
konstruktionsbedingt aufloest - unter anderem alle drei oben genannten sowie
die Token-Datei im Klartext, weil eine Integration den Recorder direkt
abfragen kann statt sich selbst ueber HTTP.
21 KiB
Review: Branch main, Commits c66ed82..d5562c7
Datum: 2026-08-13 · Umfang: 18 Commits, 24 Dateien, +2752/−259 Zeilen Gegenstand: Setup-Menü zur Sensor-Zuordnung, Umstellung von WLAN/VAG auf FMM003, Standort-Kachel mit Live-Position, iOS-/Großbildschirm-Optikauflage, DuckDNS und Zertifikate.
Geprüft wurde gegen eine Arbeitskopie von origin/main. Die mit [belegt] markierten Befunde
sind am Code nachvollzogen oder nachgestellt; [plausibel] heißt: aus dem Code abgeleitet, aber
nicht im Browser reproduziert.
Gesamteindruck
Handwerklich stark. Das Setup-Menü ersetzt „vor der Installation einstellungen.py editieren"
durch eine Oberfläche mit Live-Wertvorschau, Unavailable-Warnung, Duplikat-Prüfung und einem
ehrlichen Neustart-Hinweis für die drei triggergebundenen Felder. Der Kniff dahinter — setattr
auf dem laufenden Modul-Objekt, weil alle Leser einstellungen.KM_SENSOR als lebenden
Attributzugriff machen — ist elegant und im Kopfkommentar sauber begründet.
Positiv außerdem: Escaping ist im neuen Code durchgängig (kein XSS gefunden), Karten-Ebenen werden vor dem Neuaufbau entfernt, die Haversine-Distanz ist mathematisch korrekt, Listenfelder sind gegen zu kurze Arrays abgesichert, und die Python-Syntax aller acht geänderten pyscript-Dateien ist in Ordnung.
Die Fehler unten liegen fast alle im selben Bereich — dem neuen Setup-Menü — und drei davon werden erst nach einem Neustart sichtbar, also mit maximalem zeitlichem Abstand zur Ursache.
Übersicht
| # | Befund | Wirkung | Ort |
|---|---|---|---|
| 1 | Speichern bei fehlendem Katalog löscht alle Zuordnungen | Datenverlust | audi-dashboard-app.js:1773, 2031 |
| 2 | „Zurücksetzen" wirkt bei 15 von 17 Feldern nicht | falscher Zustand | entitaeten.py:188 |
| 3 | Alle vier Listenpositionen bekommen denselben Sensor | falsche Sicherheitsaussage | audi-dashboard-app.js:1976 |
| 4 | Vorschlagsschwelle akzeptiert beliebige Sensoren | falscher Fahrt-Trigger | audi-dashboard-app.js:1980 |
| 5 | Geleerte Listen setzen ["","","",""] |
Status dauerhaft „unbekannt" | entitaeten.py:188 |
| 6 | Zuordnung wird nirgends gesichert | Verlust bei Wiederherstellung | backup.py:32 |
| 7 | Kaputte entitaeten.json legt das Panel lahm |
Totalausfall | entitaeten.py:159 |
| 8 | Standortabfrage im Dauerfeuer bei abgelehnter Freigabe | Akku, Netz | audi-dashboard-app.js:553/557 |
| 9 | Kein Tastaturweg in die Einstellungen unter 860 px | Bedienbarkeit | audi-dashboard-app.js:3849 |
| 10 | .navmarke nur in der iOS-Auflage versteckt |
Tab-Leiste zerfällt | audi-dashboard-ios.css:194 |
Schwerwiegend
1. Speichern bei fehlendem Katalog löscht die gesamte Zuordnung [belegt]
Kette:
ENTITAETENwird an genau einer Stelle gefüllt (audi-dashboard-app.js:3723), aushass.states.- Der Nachlade-Pfad nach einem HA-Neustart (
:3699-3703) holt Profil, Fahrten, Tankvorgänge, Status und Batterieverlauf nach — nicht aberpyscript.audi_dashboard_entitaeten. DATEN_GELADENhängt allein am Profil. Die App gilt also als geladen, während der Katalog fehlt.- Der Knopf „Setup — Sensoren zuordnen" (
:1773) ist nur aneinrichtenOffengekoppelt, nicht an den Katalog.setupKatalog()liefert[], das Popup öffnet ohne eine Zeile und ohne Fehlermeldung,setupZuordnungbleibt{}. - „Speichern" schickt
"{}"(:2031).overrides_schreiben()ersetzt die Datei vollständig, ohne Zusammenführen (entitaeten.py:166-173).
Auswirkung: data/entitaeten.json enthält danach {}. Weil die setattr-Werte im laufenden
Prozess bestehen bleiben, fällt der Verlust erst beim nächsten Neustart auf. Zusammen mit
Befund 6 (keine Sicherung) gibt es dann nichts zurückzuholen.
Vorschlag: Setup-Knopf sperren, solange ENTITAETEN null ist, und in
setupSpeichernAusfuehren() abbrechen, wenn setupZuordnung leer ist. Zusätzlich die Entität in
den Nachlade-Pfad aufnehmen.
2. „Zurücksetzen" wirkt bei 15 von 17 Feldern nicht [belegt, nachgestellt]
entitaeten.py:188 überspringt leere Werte:
if wert in (None, "", []):
continue
Der Kopfkommentar derselben Datei beschreibt das Problem exakt richtig — setattr verändert das
Modul dauerhaft, „Zurücksetzen" muss den Standardwert aktiv zurückschreiben. Das Frontend tut das
auch (setupStandardwert). Nur ist der Standardwert bei 15 der 17 Katalogfelder "" oder [] —
und genau die werden übersprungen.
Nachgestellt:
nach Zuordnung: KM_SENSOR = 'sensor.alt_vag_mileage'
nach Zurücksetzen: KM_SENSOR = 'sensor.alt_vag_mileage' ← erwartet: ''
Auswirkung: Für den Nutzer sieht es aus, als hätte das Speichern versagt — aktueller_stand()
liest aus dem laufenden Modul, das Feld zeigt beim nächsten Zeichnen wieder den alten Wert.
Funktioniert nur bei ZUENDUNG_SENSOR, BATTERIE_SENSOR und STANDORT_TRACKER, den drei Feldern
mit nicht-leerem Standard.
3. Alle vier Listenpositionen bekommen denselben Sensor [belegt]
audi-dashboard-app.js:1976-1981:
zuordnung[feld.key] = feld.positionen.map((_, i) => {
const vorhanden = (werte[feld.key] || [])[i];
if (vorhanden) return vorhanden;
const vorschlag = entitaetKandidaten(feld.key, "", "")[0]; // i geht nicht ein
return vorschlag && entitaetScore(feld, vorschlag, "") >= 3 ? vorschlag.id : "";
});
entitaetKandidaten() hängt nicht vom Index ab und schließt bereits vergebene IDs nicht aus —
alle vier Positionen bekommen dieselbe Entität. Betrifft TUER_SENSOREN, FENSTER_SENSOREN,
TUERSCHLOSS_SENSOREN.
Auswirkung: Bei einer Frischinstallation (genau der Fall, für den das Menü gebaut wurde) prüft
_sicherheitscheck() danach viermal dieselbe Tür. „Sicher abgestellt" meldet gesichert, obwohl
drei Türen nie geprüft wurden. Die Duplikat-Warnung fängt das beim Speichern ab, ist aber mit
„Trotzdem speichern" wegklickbar.
4. Die Vorschlagsschwelle akzeptiert beliebige Sensoren [belegt]
entitaetScore() (:1936) vergibt: Stichwort +5, Domain +3, device_class +3, Einheit +2. Die
Schwelle ist >= 3 — ein Domain-Treffer allein genügt, ohne dass ein einziges Stichwort passt.
Verschärfend: setupNurPassend wird zwei Zeilen vorher auf true gesetzt (:1971), wodurch
entitaetKandidaten() ohnehin hart auf die Domain filtert. Die Schwelle ist damit immer erfüllt.
Die Reihenfolge kommt aus Object.keys(HASS.states), ist also faktisch willkürlich.
Auswirkung: Ohne passenden Zündungssensor wird ZUENDUNG_SENSOR stumm mit dem erstbesten
binary_sensor.* vorbelegt — Bewegungsmelder, Fensterkontakt, was zuerst kommt. Das Feld sieht
ausgefüllt aus, wird mitgespeichert, und die gesamte Fahrterkennung hängt an einem
Zufallssensor. Bei Einzelfeldern greift keine Duplikat-Warnung. Dasselbe für TANK_SENSOR (jeder
%-Sensor, etwa Luftfeuchte) und REFRESH_BUTTON (jedes button.*).
Vorschlag: Schwelle auf >= 5 — also mindestens ein Stichworttreffer.
5. Geleerte Listenfelder setzen ["","","",""] [belegt]
Die Skip-Regel aus Befund 2 prüft auf []. Ein Array aus vier leeren Zeichenketten ist das nicht:
["","","",""] in (None, "", []) # False -> wird per setattr gesetzt
_sicherheitscheck() zippt dann über vier leere Entity-IDs und erzeugt vier „unbekannt"-Zeilen —
mal drei Listen sind das zwölf.
Auswirkung: Weil die Gesamtaussage bewusst None wird, sobald eine Prüfung unbekannt ist,
steht die Übersicht danach dauerhaft auf „Zustand unbekannt" statt auf grün.
Kurios ist die Kombination mit Befund 2: Bei Einzelfeldern wirkt „Zurücksetzen" gar nicht, bei
Listenfeldern zu stark. Beides verschwindet mit demselben Fix — statt leere Werte zu überspringen,
immer den Standardwert aus _STANDARDWERTE zurückschreiben:
def overrides_anwenden():
overrides = overrides_lesen()
for key in _SCHLUESSEL:
wert = overrides.get(key)
leer = wert in (None, "", []) or (isinstance(wert, list) and not any(wert))
setattr(einstellungen, key, _STANDARDWERTE[key] if leer else wert)
6. Die Sensor-Zuordnung wird nirgends gesichert [belegt]
backup.py:32 sichert fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl —
entitaeten.json fehlt. Auch audi_dashboard_backup_wiederherstellen kennt es nicht, update.ps1
fasst data/ bewusst nicht an, und in homeassistant/.gitignore steht es nicht neben den anderen
Laufzeitdateien.
Auswirkung: Nach einer Wiederherstellung ist die komplette Sensor-Zuordnung still weg. In Verbindung mit Befund 1 gibt es keinen Rückweg.
7. Eine beschädigte entitaeten.json legt das Panel lahm [belegt]
overrides_lesen() (entitaeten.py:159) ruft json.loads ohne Absicherung. Der Aufruf steht in
beim_start() vor alles_veroeffentlichen() — wirft er, wird gar nichts veröffentlicht, das
Panel bleibt komplett leer.
Geschrieben wird zwar atomar über .tmp + os.replace, das Risiko ist also gering — der Ausfall
wäre aber total. Dieselbe Fehlerklasse, die im Branch umsetzung-datametric360 bei profil_lesen()
bereits abgefangen wurde.
Mittel
8. Standortabfrage im Dauerfeuer, Karte bei jedem Render neu [belegt]
USER_POS_TS wird nur im Erfolgs-Callback gesetzt (:553), nicht im Fehlerfall (:557). Die
30-Sekunden-Drossel in standortErfassenFallsNoetig() (:560) greift damit nie, wenn der Nutzer
die Standortfreigabe ablehnt oder kein Fix zustande kommt.
Parallel dazu zerstört render() die Vorschaukarte und baut sie neu (:2879-2880), sobald die
Route home ist — bei jedem Backend-Update.
Auswirkung: Mit einem GPS-Tracker als Quelle (genau der FMM003-Fall) sind das dutzende
getCurrentPosition({enableHighAccuracy:true})-Anfragen pro Stunde plus sichtbares Kachelflackern.
Vorschlag: USER_POS_TS = Date.now() auch im Fehlerpfad; Karte nur bei echtem Ansichtswechsel
neu bauen — die Variable gleicheAnsicht gibt es in render() bereits.
9. Kein Tastaturweg in die Einstellungen unter 860 px [belegt]
audi-dashboard-ios.css:81 versteckt .profilbtn — den echten <button aria-label="Einstellungen"> —
und holt ihn erst in der Container-Abfrage ab 860 px zurück (:230). Der Ersatz ist ein
Klick-Handler auf #marke (:2965), und das ist ein <div class="rings" aria-label="Audi">
(:3849): ohne role, ohne tabindex.
Auswirkung: In Telefonbreite gibt es für Tastatur- und Screenreader-Nutzer keinen Zugang zu
den Einstellungen. Ein <div> mit aria-label ohne Rolle wird von den meisten Screenreadern nicht
einmal angesagt. Gleiche Fehlerklasse wie das Swipe-Löschen aus AUDIT_2026-08-10.md.
Vorschlag: #marke zu einem <button aria-label="Einstellungen"> machen; dann kann auch
pointer-events:auto in audi-dashboard-ios.css:78 entfallen.
10. .navmarke nur in der iOS-Auflage versteckt [belegt]
audi-dashboard-app.js:2956-2963 hängt den Ringklon unbedingt in #tabbar.
.navmarke{display:none} steht ausschließlich in audi-dashboard-ios.css:194. .tabbar ist ein
display:grid mit repeat(5, 1fr) (audi-dashboard.css:211).
Auswirkung: Lädt /local/audi-dashboard-ios.css nicht (404, Cache), wird der Klon ein sechstes
Grid-Element — alle Tabs rutschen eine Spalte weiter, „Tanken" fällt in eine zweite Zeile, die
Menüleiste zerfällt. Kein theoretischer Fall: Commit 3548f77 dokumentiert genau dieses
Deployment-Loch.
Vorschlag: .navmarke{display:none} gehört in die Basis-CSS, die Sichtbarkeit in die Auflage.
11. Standort-Menü ohne pointercancel [belegt]
standortMenuVerdrahten() (:706-731) setzt smY0 nur in pointerup zurück. Alle drei anderen
Zeigergesten der Datei haben einen pointercancel-Handler (:2929, :3055, :3122), diese nicht.
Auswirkung: Übernimmt das System die Berührung (iOS-Randgeste, Multitouch, eingehender Anruf),
bleibt smY0 gesetzt. Der pointermove-Handler ruft dann preventDefault() für jede weitere
Bewegung — Scrollen ist in der ganzen App blockiert, bis irgendwo ein pointerup kommt, der
dann ein dy aus einem veralteten Startpunkt auswertet.
12. Fehlgeschlagenes Reverse-Geocoding wird dauerhaft gecacht [belegt]
:572-586 setzt STANDORT_ADRESSE_KEY auch im catch-Zweig.
Auswirkung: Ein einziger fehlgeschlagener Nominatim-Abruf (Rate-Limit, kurzer Netzausfall) für eine Zelle führt dazu, dass für dieselbe Zelle die gesamte Sitzung lang nur Koordinaten angezeigt werden, auch wenn das Netz längst wieder da ist.
Vorschlag: Key nur im Erfolgsfall setzen.
13. Setup-Popup hält den role="dialog"-Vertrag nicht ein [belegt]
:2774 deklariert role="dialog" aria-modal="true". Es fehlen: Escape zum Schließen (in der Datei
gibt es keinen keydown-Handler), eine Fokusfalle (Tab wandert in den überdeckten Hintergrund),
und der Schalter „Nur passende Sensoren anzeigen" (:2779) hat keinen zugänglichen Namen — der
Beschriftungstext steht im Geschwister-<span> außerhalb des <label>.
Dazu: Die Entitäts-Auswahl öffnet ausschließlich im click-Handler (:3181). Wer per Tab ins Feld
springt und tippt, löst zwar den input-Handler aus, der bricht aber ab, weil setupSucheOffen
noch null ist — sichtbar passiert nichts. role="combobox", aria-expanded und aria-controls
fehlen ebenfalls.
14. Standort-Menü nicht per Tastatur bedienbar [belegt]
Im eingeklappten Zustand steht das Blatt per transform überwiegend außerhalb des Sichtbereichs,
bleibt aber vollständig im DOM und im Tab-Fokus — Adresse, Route-Link und Teilen-Knopf sind
fokussierbar, ohne sichtbar zu sein (kein inert, kein aria-hidden). Öffnen geht gar nicht per
Tastatur: .standortmenu-griffzone ist ein <div> mit reinen Pointer-Handlern. Der Umschalter
Straße/Satellit (:773) hat kein aria-pressed, sein Label bleibt in beiden Zuständen gleich.
15. disconnectedCallback() räumt nur eine von drei Karten ab [belegt]
:3815-3817 zerstört MAP, nicht aber SMAP/TMAP. Wird das Panel abgehängt, während Standort-
oder Übersichtsseite offen ist, bleibt eine Leaflet-Instanz samt Resize-Listener und
Kachel-Abrufen am Leben.
Klein
| Ort | Befund |
|---|---|
audi-dashboard-ios.css:88, 208 |
main{padding:…} (0,0,1) verliert gegen main#view (1,0,1) in audi-dashboard.css:197. Auf Großbildschirmen bleibt der Seitenrand bei 20 px statt der beabsichtigten 44 px. Achtung: .standort-vollbild{margin:0 -20px} (audi-dashboard.css:704) passt heute genau dazu — beides gehört zusammen angefasst. |
audi-dashboard-app.js:3190/3612 |
„Nur passende Sensoren anzeigen" wirkt nicht, solange ein Dropdown offen ist: Der Klick-Handler ersetzt das Overlay-DOM, bevor das change-Event des Kontrollkästchens ausgeliefert wird. [plausibel] |
audi-dashboard-app.js:2966 |
Theme-Umschalten ruft kein render() — die Leaflet-Kacheln bleiben bis zum nächsten Backend-Update im alten Stil. Durch die neue Dauerkarte auf der Übersicht deutlich sichtbarer als früher. |
audi-dashboard-app.js:804 |
${de(CAR.tankPct)} % zeigt ohne Tanksensor „0 %“, während direkt daneben korrekt „Reichweite unbekannt“ steht. |
audi-dashboard-app.js:496, 518, 117 |
Toter Code: fahrzeugGlyphPfade() nie aufgerufen, zustand.parkplatz nie gelesen, standortGenauigkeitM/standortZeit gemappt aber ungenutzt. Kommentare behaupten das Gegenteil. |
audi-dashboard-app.js:595 |
Einzige Interpolation im neuen Code, die ohne esc() in ein Attribut geht. Heute nicht ausnutzbar, weil _zu_zahl() im Backend nur Zahlen durchlässt — als Härtung trotzdem sinnvoll, ebenso Number.isFinite in standortBekannt(). |
Dokumentation
AGENTS.md widerspricht sich an sechs Stellen [belegt]
Die Datei ist auf 427 Zeilen gewachsen; neue Einträge wurden angehängt statt eingearbeitet.
| Stelle | Aussage | Widerspruch |
|---|---|---|
| Z. 94 | „trip detection via the iPhone WLAN sensor" | Z. 249 ff.: läuft über ZUENDUNG_SENSOR, WLAN „fully removed" |
| Z. 110 | „Codec JSON → MQTT/TLS → Mosquitto" | Z. 227 ff.: Schwenk auf flespi, „not MQTT at all" |
| Z. 93 | „4 modules" | tatsächlich 5 (entitaeten.py neu) |
| Z. 97 | „3.130 lines" | tatsächlich 3.873 |
| Z. 100 | „einstellungen.py — the one file edited before install" |
genau das ersetzt jetzt das Setup-Menü |
| Z. 320 | STANDORT_TRACKER „left empty" |
steht auf device_tracker.testzone_fmm003 |
Dazu veraltete Codeverweise: fakeTrack() liegt bei :421 statt :414, die Statistik-Behauptung
in INSTALL.md bei Z. 229 statt Z. 204.
Die Datei verlangt selbst „nicht festhalten, was Code und Git-History schon zeigen" (Z. 47) — Z. 282–401 sind 120 Zeilen Changelog-Prosa für fünf Einträge, und Z. 249–279 dupliziert inhaltlich Z. 133–153.
INSTALL.md [belegt]
- Zirkuläre Schrittfolge: Schritt 4 verweist auf „siehe Schritt 9 zuerst" (Z. 96), Schritt 7 setzt Schritt 4 voraus (Z. 176). Die Reihenfolge 4→9→7→4 wird nirgends aufgelöst.
- Ausgelieferte Default-Entities werden verschwiegen:
ZUENDUNG_SENSOR,BATTERIE_SENSORundSTANDORT_TRACKERsind mit dentestzone_fmm003-Entities der Autoren-Instanz vorbelegt. Bei einer Frischinstallation zeigen sie ins Leere. Z. 108–110 behauptet nur für KM/TANK/RANGE „unbelegt". - Override-Datei nicht benannt: Z. 104 spricht von „einer Override-Datei" — der Pfad
/config/audi_dashboard/entitaeten.jsonsteht nirgends, und ihre fehlende Sicherung (Befund 6) ist nicht erwähnt. - Schritt 2 verweist auf
fahrzeugprofil.example.json, deren Z. 2 weiterhin den „WLAN-Namen" verlangt, obwohlfahrzeug.wlan_nameim selben Branch entfernt wurde.
WLAN-Reste in der übrigen Doku [belegt]
Im Code ist die Entfernung vollständig (keine Fundstelle). In der Doku nicht:
SPECIFICATION.md (Z. 16, 147, 181, 196, 217), homeassistant/README.md:106 und die Profilvorlage
nennen WLAN-Sensor und TommiG1/HA_VAG-EU-Data-Act weiterhin als aktuellen Stand.
update.ps1 [belegt]
Für www/ ist das Skript nach dem Fix vollständig — audi-dashboard-ios.css und badges/
sind ergänzt, Cache-Busting greift auch für die neue CSS-Datei.
Verbleibende Lücke: homeassistant/data/shell_beleg_parser.py ist Code, kein Datenbestand —
belegverarbeitung.py:41 lädt ihn aus /config/audi_dashboard/. update.ps1 schließt data/
pauschal aus, INSTALL.md behandelt ihn als Einmal-Kopie. Änderungen am Beleg-Parser, dem
einzigen getesteten Teil des Repos, kämen auf keiner Instanz an.
design/ [belegt]
dm360-host.html lädt audi-dashboard-app.js (Z. 12) und audi-dashboard-ios.css (Z. 33) — beide
existieren in design/ nicht. Aus der Repo-Kopie ist das Board funktionslos; es läuft nur im
Claude-Design-Projekt. Nirgends dokumentiert.
design/README.md:19 führt audi-dashboard-ios.css in der Inhaltstabelle des Ordners (die Datei
liegt in homeassistant/www/) und behauptet, die Auflage „rührt audi-dashboard-app.js nicht an" —
Z. 57–59 derselben Datei beschreibt, dass genau dort der Stylesheet-Loader ergänzt wurde.
Markenassets: Der Diff fügt keine neuen Binärdateien hinzu. DataMetric360 Board.dc.html
verwendet die vorhandenen Audi-Type-Dateien per @font-face — das Lizenzrisiko bleibt unverändert,
nicht erhöht.
.gitignore [belegt]
installationspaket/ ist korrekt ergänzt und schließt nichts Getracktes aus. Es fehlt
data/entitaeten.json neben den anderen drei Laufzeitdateien — heute harmlos, weil die Datei nur
unter /config/audi_dashboard/ entsteht, aber inkonsistent zum eigenen Grundsatz der Datei.
Was den Branch umsetzung-datametric360 betrifft
Der flespi-Schwenk macht homeassistant/FMM003_MAPPING.md überholt. Das Dokument beschreibt
Codec JSON über MQTT/TLS mit eigener CA und einem mosquitto_sub-Mitschnitt. Mit flespi läuft es
über den nativen Codec8/TCP-Kanal mit IMEI-Authentifizierung, ohne Zertifikate und ohne eingehenden
Port; die Feldzuordnung entstünde aus der flespi-REST-API. Beim Zusammenführen anpassen oder
ersetzen.
Das CORS-Rätsel ist damit auch erklärt. Die Notiz auf main, der http:-Block sei aus der
configuration.yaml entfernt worden, „nachdem HA angefangen hat, ihn zu migrieren beziehungsweise
zu ignorieren", erklärt, warum cors_allowed_origins in HA 2026.8 wirkungslos blieb — auch bei
gleichem Ursprung. Gehört in homeassistant/REVERSE_PROXY.md nachgetragen.
Die Falle beim Zusammenführen steht bereits in AGENTS.md dieses Branches: profil_lesen()
gibt hier bei fehlender Profildatei None zurück, profil.py ist auf main unverändert und geht
konfliktfrei durch — die dortigen Aufrufstellen prüfen das aber nicht.
Empfehlung
Reihenfolge nach Schaden:
- Befund 1 (Datenverlust) — zwei Riegel, wenige Zeilen.
- Befunde 2 und 5 (Zurücksetzen) — ein gemeinsamer Fix in
overrides_anwenden(). - Befunde 3 und 4 (falsche Vorbelegung) — Index in den Vorschlag einbeziehen, Schwelle auf 5.
- Befund 6 (Sicherung) — eine Zeile in
backup.py, plus Wiederherstellung. - Befund 7 (Absicherung beim Lesen), 8 (Akku), 9/10 (Bedienbarkeit, Robustheit).
Die Punkte 1 bis 4 betreffen alle das neue Setup-Menü und lassen sich in einem Zug erledigen.