Review des main-Branch als Dokument ablegen
15 Befunde aus den 18 neuen Commits, nach Schaden sortiert und mit
Datei-Zeile-Belegen. Die drei schwersten liegen im neuen Setup-Menue:
Speichern bei noch nicht geladenem Katalog ueberschreibt entitaeten.json
mit {} und loescht damit alle Zuordnungen, Zuruecksetzen wirkt bei 15 von
17 Feldern nicht, und alle vier Listenpositionen bekommen denselben Sensor,
wodurch "Sicher abgestellt" gesichert meldet, obwohl drei Tueren nie
geprueft wurden.
Jeder Befund ist als belegt oder plausibel gekennzeichnet; die belegten
sind am Code nachvollzogen, die Zuruecksetz-Regel zusaetzlich isoliert
nachgestellt.
This commit is contained in:
@@ -219,6 +219,11 @@ vendored MIT library served from Home Assistant itself, which satisfies the actu
|
||||
|
||||
## Pending: this branch has diverged from `main` (noted 2026-08-13)
|
||||
|
||||
A full review of `main`'s 18 new commits is in `REVIEW_main_2026-08-13.md` — 15 findings, the
|
||||
three most serious in the new setup menu (saving with an unloaded catalogue wipes the whole
|
||||
mapping; "reset" has no effect on 15 of 17 fields; all four list positions get the same sensor,
|
||||
which makes "securely parked" report safe while three doors were never checked).
|
||||
|
||||
`main` has moved 18 commits ahead of `umsetzung-datametric360` (FMM003 switch, sensor-mapping setup
|
||||
menu, iOS/large-screen overlay from Claude Design). **Deliberate decision: do not merge yet** — the
|
||||
owner keeps working on `main` first.
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
# 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:**
|
||||
|
||||
1. `ENTITAETEN` wird an genau einer Stelle gefüllt (`audi-dashboard-app.js:3723`), aus `hass.states`.
|
||||
2. Der Nachlade-Pfad nach einem HA-Neustart (`:3699-3703`) holt Profil, Fahrten, Tankvorgänge,
|
||||
Status und Batterieverlauf nach — **nicht** aber `pyscript.audi_dashboard_entitaeten`.
|
||||
3. `DATEN_GELADEN` hängt allein am Profil. Die App gilt also als geladen, während der Katalog fehlt.
|
||||
4. Der Knopf „Setup — Sensoren zuordnen" (`:1773`) ist nur an `einrichtenOffen` gekoppelt, nicht an
|
||||
den Katalog. `setupKatalog()` liefert `[]`, das Popup öffnet **ohne eine Zeile und ohne
|
||||
Fehlermeldung**, `setupZuordnung` bleibt `{}`.
|
||||
5. „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:
|
||||
|
||||
```python
|
||||
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`:
|
||||
|
||||
```js
|
||||
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:
|
||||
|
||||
```python
|
||||
["","","",""] 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:
|
||||
|
||||
```python
|
||||
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_SENSOR` und
|
||||
`STANDORT_TRACKER` sind mit den `testzone_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.json` steht 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, obwohl `fahrzeug.wlan_name` im 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:
|
||||
|
||||
1. **Befund 1** (Datenverlust) — zwei Riegel, wenige Zeilen.
|
||||
2. **Befunde 2 und 5** (Zurücksetzen) — ein gemeinsamer Fix in `overrides_anwenden()`.
|
||||
3. **Befunde 3 und 4** (falsche Vorbelegung) — Index in den Vorschlag einbeziehen, Schwelle auf 5.
|
||||
4. **Befund 6** (Sicherung) — eine Zeile in `backup.py`, plus Wiederherstellung.
|
||||
5. **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.
|
||||
Reference in New Issue
Block a user