Fix broken map rendering, split GPS cleanup, receipt parser and design backlog
Leaflet's stylesheet was appended to document.head, so it never reached the
panel's shadow root: .leaflet-tile{position:absolute} never applied, tiles laid
out as in-flow images (~1040px inside a 190px box) and the marker pane ended up
far below the visible area. That is the real cause of the long-standing
"fragmented Leaflet rendering" finding and of the invisible vehicle pin - every
tile request had actually succeeded. The stylesheet now goes into the shadow
root and is awaited before the map is built.
Also in this round:
- Map tiles are always light (Google-Maps-style), no dark variant at night.
- Vehicle marker uses the real CI poi-car icons (poi-car-l >=34px, poi-car-s
below), with a white halo so the outline stays readable on tiles.
- Removed the obsolete combined STANDORT_TRACKER field; only the split
lat/lon sensors remain.
- Receipt upload: widened the try block so base64/save failures surface, and
the frontend call site now reports a rejected service call.
- Generic receipt parser: total detection is line-based (letter-spaced
headings, no more matching the SUMME-EUR column header, tax lines excluded),
address heuristic handles 4-digit postcodes and single-line address blocks,
and "Preis/L" matches without a spelled-out "Liter".
- Design backlog: red hairline frame on list rows (delete button bled through
at fractional row heights) and select fields now use the grey background box.
Shell 10-receipt regression suite still passes; all changes verified live in
the audi_ha_test container.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,14 @@ oversized toggle switches, and fixed a desktop-layout audit (settings button / r
|
||||
overflowing past the capped content column) — see `DESIGN_AUDIT_2026-08-13.md`; 2026-08-16: fixed
|
||||
five user-reported bugs — removed Türschloss/Haubenschloss checks, fixed a translucent confirm-
|
||||
sheet, added a flespi-style split lat/lon location source, hardened the "Lädt …" bootstrap race,
|
||||
and added a generic (station-independent) fuel-receipt parser fallback — see section C). This file
|
||||
is the entry point for every new agent
|
||||
and added a generic (station-independent) fuel-receipt parser fallback; later the same day: removed
|
||||
the now-unused combined `STANDORT_TRACKER` field entirely (flespi never provides it), closed a real
|
||||
silent-failure gap in the receipt-upload error path, and replaced the vehicle's map marker with a
|
||||
two-tone pin+car icon — see section C; a third round the same day found and fixed the long-standing
|
||||
"fragmented Leaflet rendering" defect at its root — the Leaflet stylesheet was loaded into
|
||||
`document.head` and therefore never reached the panel's shadow root — plus light-only map tiles,
|
||||
the CI `poi-car` marker, the red frame on list rows, the select-field grey box, and two more
|
||||
generic-receipt-parser gaps). This file is the entry point for every new agent
|
||||
session: what this repo is, what is finished, what is missing, and how to work here. Detail lives in
|
||||
the linked documents — this file points, it does not duplicate.
|
||||
|
||||
@@ -150,7 +156,9 @@ the `design/` export's RS-6 error extends into the technical sample data (73 l t
|
||||
FIN series 4G). Four browser-verified rendering defects: switches stretched by
|
||||
`.feld label{flex:1 1 auto}` (state display becomes ambiguous), double "offen" in the trip list,
|
||||
empty oil-change tile when the service book is empty, and fragmented Leaflet rendering in all
|
||||
three maps (verify on a real device). Positives: the 300/400 font-weight rule and de-DE
|
||||
three maps (✅ **fixed 2026-08-16** — root cause was Leaflet's stylesheet being loaded into
|
||||
`document.head`, which never reaches the panel's shadow root; see the third-round entry in
|
||||
"Open items"). Positives: the 300/400 font-weight rule and de-DE
|
||||
formatting hold everywhere; `design-system/` is verifiably brand-free.
|
||||
|
||||
### HA panel — known gaps (most also in SPECIFICATION.md §7)
|
||||
@@ -666,6 +674,107 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
|
||||
card by deliberately triggering it (this container's limited entity set causes a real
|
||||
duplicate auto-suggestion); pyscript reload clean, no new console errors beyond the
|
||||
pre-existing placeholder-image 404s. Synced to `installationspaket/`.
|
||||
- [x] Follow-up round the same day (2026-08-16), three more items:
|
||||
(1) **Removed `STANDORT_TRACKER` entirely** — user confirmed the combined device_tracker
|
||||
field is no longer needed (flespi only ever provides the split lat/lon sensors added earlier
|
||||
that day). Deleted the field from `einstellungen.py` and `entitaeten.py`'s Setup catalog, and
|
||||
simplified `_standort()` in `frontend_veroeffentlichung.py` down to the single split-sensor
|
||||
path (no more two-branch fallback). `overrides_schreiben()`'s existing "only known keys
|
||||
survive" behavior (see its docstring) meant no explicit migration was needed for stale
|
||||
`STANDORT_TRACKER` entries already sitting in `data/entitaeten.json` — confirmed live: this
|
||||
container's own leftover override file still had `STANDORT_TRACKER` from earlier testing
|
||||
(plus stale `TUERSCHLOSS_SENSOREN`/`HAUBENSCHLOSS_SENSOR` from before finding (1) of the
|
||||
previous entry), all silently dropped on the next Setup save, which is exactly why the GPS
|
||||
tile was still showing "Kein GPS-Signal" after the user's own remap attempt earlier — that
|
||||
attempt happened to save while the old combined field was still in the catalog, so nothing
|
||||
ever actually persisted `STANDORT_LAT_SENSOR`/`STANDORT_LON_SENSOR`. Redid the Setup save
|
||||
live (mapped both to `sensor.testcar_b9_fmm003_testintegratoin_lat/longitude_coordinate_value`)
|
||||
and confirmed the Übersicht/fullscreen Standort map switched from the "no signal" placeholder
|
||||
to a real rendered map at the correct coordinates (South Tyrol terrain, "Burgleralm" label
|
||||
visible).
|
||||
(2) **Fuel-receipt "silently does nothing", root cause found** — reproduced the exact
|
||||
real upload flow (button click → real `<input type=file>` → synthetic `File`/`DataTransfer`
|
||||
dispatch → `FileReader` → `hass.callService`) via browser instrumentation: the happy path
|
||||
works completely (backend parses, publishes `pyscript.audi_dashboard_beleg_ergebnis`, frontend
|
||||
fills the form) — `belegverarbeitung.py`'s existing `try/except` around `_parser_aufrufen()`
|
||||
already publishes a visible `fehler` for parser failures specifically. The actual gap:
|
||||
`base64.b64decode()` and `_pdf_speichern()` in `audi_dashboard_beleg_hochladen()` were
|
||||
*outside* that try block — any failure there (corrupted upload, disk full, ...) raised an
|
||||
unhandled exception with zero UI feedback, since `serviceRufen()`'s generic `.catch()` only
|
||||
does `console.error()`. Widened the try block to cover all three steps. Also stopped using
|
||||
`serviceRufen()` for this one call site specifically (`audi-dashboard-app.js`, the
|
||||
`eingabe.onchange` handler) — it now calls `HASS.callService()` directly with its own
|
||||
`.catch()` that sets `belegFehler` and re-renders, so a rejected service call (network,
|
||||
timeout — anything that bypasses the backend's own state-publish) is visible too, not just
|
||||
logged. Verified against the real 10-receipt Shell suite (still passing) both before and
|
||||
after this change.
|
||||
(3) **Vehicle map marker replaced with a two-tone pin+car icon** — added `CI.pinCar` (a
|
||||
balloon/pin path + white badge circle + a simplified car-front glyph built from rects, not
|
||||
circles, after an isolated-DOM-injection test round showed a circles-for-headlights version
|
||||
read as a face/animal rather than a car) to `audi-dashboard-app.js`, replacing the single-color
|
||||
`poiCar` teardrop previously used by `fahrzeugMarkerSVG()`. Updated both marker call sites'
|
||||
`iconAnchor` to the new pin's actual tip position and simplified `.fahrzeug-pin` in
|
||||
`audi-dashboard.css` (no more `color:var(--red)`/white-halo-filter hack, since the new icon
|
||||
carries its own fixed colors). Verified the icon markup renders correctly via an isolated
|
||||
DOM-injection test (bypassing Leaflet); could **not** get a final on-map screenshot in
|
||||
`audi_ha_test` — the Standort map tiles themselves only ever partially load in this container
|
||||
(reproduced on a fully fresh reload, unrelated to this change), consistent with a previously
|
||||
documented network limitation of this specific sandbox (see the Standort-Kachel entry above:
|
||||
reverse-geocoding via Nominatim had the same kind of container-specific network issue).
|
||||
Structurally verified only; needs a look on a real device/network to confirm final visual
|
||||
placement.
|
||||
All three deployed to `audi_ha_test` (version `1786758000`) and synced to `installationspaket/`.
|
||||
- [x] Third round the same day (2026-08-16) — **the "fragmented Leaflet rendering" defect is solved
|
||||
at its root**, plus four smaller items:
|
||||
(1) **Leaflet CSS never reached the shadow root.** `leafletLaden()` appended
|
||||
`leaflet.min.css` to `document.head`, but the panel renders inside `this.shadowRoot` — and
|
||||
document stylesheets do not cross a shadow boundary. Inside the panel, `.leaflet-tile
|
||||
{position:absolute}` and friends therefore never applied: the tiles laid themselves out as
|
||||
ordinary in-flow `<img>` elements (two per row, ~1040 px of stacked height inside a 190 px
|
||||
box), so only a thin strip of map was ever visible, and the marker pane ended up ~1009 px
|
||||
below the visible area — which is exactly why the new vehicle pin appeared "missing". This
|
||||
also explains the earlier misdiagnosis as a container/network limitation: every tile request
|
||||
succeeded (`complete:true`, `naturalWidth:512`), the geometry was the problem. Fixed by
|
||||
injecting the stylesheet into `ROOT` and awaiting it before the map is built; the script tag
|
||||
stays in `document.head` (it must, `window.L` is global). The CSS injection is deliberately
|
||||
re-checked on every `leafletLaden()` call rather than guarded by the `window.L` check, because
|
||||
a HA panel remount produces a fresh shadow root while `window.L` is already set. Verified live:
|
||||
both the Übersicht preview map and the fullscreen Standort map now fill their containers and
|
||||
show the pin at the vehicle position.
|
||||
(2) **Maps are now always light.** `TILES[theme]` switched to CARTO `dark_all` in Nacht mode;
|
||||
replaced by a single themeless `TILE_URL` (`light_all`), matching how Google Maps & co. keep
|
||||
the standard road map light regardless of app theme.
|
||||
(3) **Vehicle marker now uses the real CI `poi-car` icons** (`poi-car-l.svg` / `poi-car-s.svg`
|
||||
from the delivered icon set) instead of the hand-built two-tone pin from the previous round:
|
||||
`CI.poiCarL` (48-grid) at ≥34 px, the existing `CI.poiCar` (24-grid) below, anchors recomputed
|
||||
per variant. Since these are single-color outline forms in `currentColor`, `.fahrzeug-pin`
|
||||
regained a stacked white drop-shadow halo so the outline stays readable on map tiles.
|
||||
(4) **Red partial frame on Fahrten/Tanken list rows** (open since the 2026-08-13 design audit,
|
||||
finding 3) — reproduced and confirmed by recoloring the delete button live. Row heights are
|
||||
fractional (66.28 px), so `.swipe-content`'s edges miss the device-pixel grid and the red
|
||||
`.swipe-delete` behind it bled through as a hairline around every row. Fixed by only painting
|
||||
the delete button while a swipe is actually happening: `.swipe-delete{visibility:hidden}` plus
|
||||
a `wischt` class set on the first movement of the gesture (and the existing `swiped` class for
|
||||
the open row). Verified the full gesture still works — button appears at the first pixel of
|
||||
drag and the row settles open at −84 px.
|
||||
(5) **Select fields now show the grey background box** (design audit finding 1) — replaced
|
||||
`.feld select{color:var(--ios-tint)}` with `background:var(--ios-fill);padding:8px 10px`,
|
||||
matching `.mitEinheit input` ("Pause bis [15] Minuten"), as the user asked. Verified on
|
||||
Modell / Ölwechsel-Intervall / Bildposition; free text fields stay plain, so the box now
|
||||
genuinely marks "there is a choice here".
|
||||
(6) **Generic receipt parser: total and station name** — a real Austrian non-Shell receipt
|
||||
returned the right litres but 6,00 € and no station. Two causes, both fixed: the free-running
|
||||
total pattern matched the *column heading* `SUMME-EUR` and read the next line's article number
|
||||
as the amount, and bon printers letter-space headings (`G E S A M T BETRAG EUR: 92,60`), which
|
||||
the keyword never matched. Total detection is now line-based — keyword checked against the
|
||||
whitespace-stripped line, amount must be a real money value (`_GELD`, decimals required), tax
|
||||
lines (`MWST`/`UST`/`VAT`/`STEUER`/`NETTO`) excluded, largest remaining candidate wins. The
|
||||
address heuristic no longer demands three fixed lines with a 5-digit postcode (AT uses 4
|
||||
digits, and this receipt carries `SHELL TANKSTELLE, 6450 SÖLDEN` on one line): it finds the
|
||||
first postcode line in the header and takes the name from the line above. `Preis/L` without a
|
||||
spelled-out "Liter" now matches too. Result on that receipt: 42,13 l · 92,60 € · 2,198 €/l ·
|
||||
no discount · `AUTO B. FRISCHMANN GMBH`. The 10-receipt Shell regression suite still passes.
|
||||
All deployed to `audi_ha_test` (version `1786765000`) and synced to `installationspaket/`.
|
||||
- [ ] Fix remaining documentation drift (statistics claim, README gaps, obsolete TODO comment) —
|
||||
text-only changes; INSTALL.md's WLAN/TommiG1 drift and stale variable names were fixed
|
||||
2026-08-12 (see section B); `DESIGN_REVIEW_2026-08-13.md` and `REVIEW_main_2026-08-13.md`
|
||||
|
||||
Reference in New Issue
Block a user