Tesserae: open-source self-hosted dashboard companion for e-ink panels

Hi all. I've been building this for a few weeks and it's at a place where I'd love to put it in front of HA folks for some early feedback.

Tesserae is a self-hosted dashboard companion for e-ink panels: compose tile-based dashboards out of widgets in a web UI, render them headless, then push the frames to physical displays. Works with Pimoroni Inky (pHAT, wHAT, Impression 4"/5.7"/7.3"/13.3"), Waveshare Spectra 6 driven by an ESP32, TRMNL devices (Seeed Studio hardware running the TRMNL firmware, pictured above with the resident QA inspector), and Kindles running KOReader's trmnl-display plugin.

One Tesserae instance drives a whole household of panels at once, each with its own dashboard. Above each card is a live preview of what's currently on the device.

Dashboards are tile-based. Pick a layout preset (single cell, 2×2 grid, hero top/bottom, etc.), assign a widget per cell, pick a theme. The dashboard's panel block sizes to the device you're binding to, so the same composition retargets to a different panel just by ticking a different device.

Landscape panels work the same way. This Bedside dashboard binds to a landscape waveshare photo painter running custom firmware.

Where it fits with HA specifically:

  • Installs as a Home Assistant App with Ingress, so it lives in your sidebar like any other App. The HA App repo handles the install; the main repo has docs covering the App path.
  • MQTT auto-discovery publishes every Tesserae-managed device as an HA entity. Battery percentage, signal strength, IP, current frame as an image entity, current dashboard name, last refresh time. They appear under the Tesserae hub device card and group cleanly.
  • HA-aware widgets bundled in: lights, locks, climate, cameras, sensors, history graphs, energy / solar, zones, todo lists, plus battery + heartbeat tiles for your other HA devices. They use HA's WebSocket API so reactivity is essentially live (subject to your e-ink refresh cadence).
  • Webhook endpoint for HA automations: trigger an on-demand render when someone leaves home, when sunset hits, when a button is pressed. Token-authenticated, single POST.
  • Rotations: cycle a single panel through several dashboards on a daily anchor. Morning dashboard at 06:00, midday at 12:00, evening at 18:00, repeat. Any HA-triggered schedule with a higher priority preempts the rotation, so a doorbell-pressed automation can interject a "someone's at the door" dashboard.

There's also a small but growing community widget catalog you can browse and install from inside the UI: extra calendar views, a Spotify now-playing widget, AI-image-generation if you want a different wallpaper every morning, plus a few utility bundles.

It works just as well as wall art. This one (in our hallway) cycles between batteries, Spotify, and a litter-box weight tracker.

It's AGPL-3.0-or-later licensed, fully self-hosted, no cloud calls Tesserae itself makes (widgets you opt into may, e.g. weather and AI image generation hit their respective APIs).

Code + docs:

I'd genuinely love feedback on the HA integration shape, what's missing, and which widgets would be most useful for HA people. The community catalog is small but growing and PRs for new widgets are very welcome.

Disclaimer: built with AI assistance (Claude Code). All architecture decisions, code review, hardware testing, and the choice of what ships vs what doesn't are mine.

5 Likes

Hi! I love this! I have a really old Nook Simple Touch I've tried to use as a display for Home Assistant. I've installed TRMNL on it using https://nooks.bpmct.net/ and got Tesserae to run on my Home Assistant. I can push stuff to the Nook so it seems it work BUT there's something wrong when editing dashboards in the Tesserae interface. The UI is very (very) slow and unresponsive. I've tried in several browsers. Any idea why it's so laggy?

Most likely the editor is waiting on per-widget server.py fetch()
calls on page load. Every widget runs its data fetch once when the
editor opens; slow upstreams (weather APIs, HA's own /api/states
on a busy HA host, GitHub, etc.) block the page. Particularly harsh
on HA-hosted Tesserae because ha_* widgets call back into HA's own
API on a box that's already doing real work.

A few checks:

  1. What's your HA host? (Pi 3 / 4 / 5, Yellow / Green, NUC, etc.)
  2. How many cells, and which widget kinds? ha_* and webpage are
    the heavy ones; clock and calendar are self-contained.
  3. Reload the editor twice. Is the second load faster? If yes,
    it's cold-cache load and will settle once upstreams are cached
    (5 to 15 min TTL per widget).
  4. Browser dev tools > Network while loading the editor: one slow
    XHR or several?

I'm running HA on a NUC. Trying a dashboard with just one cell that show entities from HA, nothing fancy. It's just the Dashboards view that are very slow, the rest of the GUI works fine.

Could you grab a screenshot of browser dev tools > Network tab
during the slow load, sorted by Time descending? That'll name the
bottleneck in one image instead of us guessing.

(Filter to XHR / Fetch if it's noisy, and the Waterfall column is
the useful one for spotting serial-vs-parallel patterns.)