Hi all,
I’ve been building an e-ink dashboard (ESP32 + Waveshare 7.5") using Puppet 2.6.0 to render a Home Assistant Lovelace markdown card, and I ran into a reproducible bug that I wanted to document here since issue creation is currently restricted on the GitHub repo.
Setup: A markdown card renders weather forecast text plus condition icons loaded via <img src="/local/icons/rainy.svg" width="50" height="50"> (referencing local files served from /config/www/).
Symptom: The icons are completely missing from the final image — but only in one specific output configuration.
What I ruled out along the way:
- Not a network/loading issue — confirmed via the live browser’s DevTools Network tab: all icon requests return
200 OK, zero console errors. - Not a sanitizer issue — the
<img>tags render fine in the actual Lovelace dashboard. - Not a theme/contrast issue — tested with Dark Mode on/off and Invert Colors on/off; icons stayed absent in every combination.
- Not a dithering setting — tested None, Floyd-Steinberg, Atkinson, and Jarvis-Judice-Ninke; no difference.
What actually isolates it: Comparing output formats for the identical page/URL:
format=png→ icons render correctly
format=jpeg→ icons render correctly
format=bmp&bmp_mode=binary→ icons are completely absent
(confirmed by downloading and inspecting the raw .bmpfile directly, not just the web UI preview panel)
So the bug appears to be isolated specifically to the 1-bit binary BMP conversion/quantization step — everything upstream of that (page render, sanitizer, network) works correctly.
Why I haven’t switched to PNG/JPEG as a workaround: ESPHome’s online_image component decodes the image at runtime on the ESP32 itself, and for a 480×800 display the final 1-bit framebuffer needs a single ~48KB contiguous memory allocation. On a plain ESP32-WROOM-32 (no PSRAM), PNG/JPEG decoding fragments the heap enough that this allocation intermittently fails (Failed to allocate 48000 bytes), whereas raw BMP 1-bit requires no decompression and copies almost directly into the framebuffer. So for memory-constrained boards like mine, the binary BMP path is the only one that reliably works — which makes this bug particularly relevant for exactly the e-ink use case Puppet is designed for.
Has anyone else run into this, or found a workaround? Happy to share the raw BMP/PNG files or full HA card config if it helps someone dig into it.
Thanks!