Files
espresso_frame/server/app/templates/widget_html/weather_current.html.jinja
T
tfaour 8ea1c53ec3
Build and push server image / test (push) Successful in 39s
Build and push server image / build-and-push (push) Failing after 2m34s
Build and push server image / deploy (push) Has been skipped
Add experimental HTML/CSS "modern" render style for weather widget
The weather widget's icons/layout are hand-drawn PIL primitives -- clean
under quantization but flat, no gradients/shadows. Adds an opt-in
render_style="modern" (current/daily modes only) that instead renders a
Jinja2 template through a persistent headless-Chromium browser
(app/html_render.py), following the approach of Tesserae, an open-source
e-ink dashboard targeting this same panel family.

Key design points:
- The Chromium dependency (Playwright) is lazily imported only when a
  weather widget actually uses "modern" style, and the background browser
  itself only launches on first use -- every other widget type, and this
  one's own classic/hourly/multi_city paths, never pay for it.
- No Frame-level dithering setting needed: html_render dithers its own
  rendered widget to exact palette colors (Bayer/ordered, not
  Floyd-Steinberg) before compositing, so the shared whole-canvas
  Floyd-Steinberg pass sees zero quantization error there and leaves it
  untouched -- same trick draw_text/hand-drawn icons already use. Floyd-
  Steinberg keeps working unchanged for photos and every other widget.
- A "Load calibrated Spectra 6 preset" button in Advanced configuration
  offers a community-measured palette (data ported from
  paperlesspaper/epdoptimize, Apache 2.0) as an alternative starting
  point to the existing idealized DEFAULT_PALETTE_RGB -- fills the
  existing palette table, doesn't save by itself.

Known open risk, not resolved here: a headless Chromium binary is far
larger than the ~100MB single-layer limit that already forced this
project's pip/npm installs into split layers, and (unlike those) is a
single ~180MB file that can't be split across layers by ordinary
Dockerfile restructuring. Flagged prominently in server/Dockerfile and
docs/widgets.md -- treat this render style as experimental/local-only
until that's resolved.
2026-07-30 22:18:43 +00:00

31 lines
1.2 KiB
Django/Jinja

<!doctype html>
<html><head><style>
@font-face { font-family: "Inter"; src: url("file://{{ font_dir }}/Inter-Regular.ttf"); font-weight: 400; }
@font-face { font-family: "Inter"; src: url("file://{{ font_dir }}/Inter-Bold.ttf"); font-weight: 700; }
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Inter", sans-serif; }
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
.card {
width: {{ w - gutter * 2 }}px;
height: {{ h - gutter * 2 }}px;
margin: {{ gutter }}px;
border-radius: {{ radius }}px;
overflow: hidden;
background: #ffffff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
}
.icon { font-size: {{ icon_size }}px; line-height: 1; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.18)); }
.temp { font-weight: 700; font-size: {{ temp_size }}px; color: #17233b; }
.city { font-weight: 400; font-size: {{ label_size }}px; color: #5b6674; }
</style></head>
<body>
<div class="card">
<div class="icon">{{ emoji }}</div>
<div class="temp">{{ temp }}&deg;{{ unit_suffix }}</div>
{% if city_label %}<div class="city">{{ city_label }}</div>{% endif %}
</div>
</body></html>