{"slug": "tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels", "title": "Tesserae: E-ink dashboard companion. Compose dashboards and push to e-ink panels", "summary": "Developer Kayden released Tesserae, an open-source, self-hosted dashboard companion for e-ink displays that renders tile-based dashboards in headless Chromium (Playwright) at panel resolution and pushes frames to panels over MQTT or HTTP. Tesserae, licensed AGPL-3.0-or-later, applies Floyd-Steinberg dithering against each panel's measured color palette, using calibrated measurements from epdoptimize, then packs frames into the panel's native byte format — packed 4-bit Spectra 6, 1-bit mono, or 4-bit grayscale. The server requires no account and contacts api.tesserae.ink only for update checks, an anonymous install count and an opt-in daily heartbeat, while a separate hosted Tesserae Cloud is offered for users who do not want to run a server.", "body_md": "*Nine panels, one Tesserae server.*\n\nSelf-hosted dashboard companion for e-ink displays. Compose tile-based dashboards in a browser, render the frame headless, push it to one or more panels over MQTT or HTTP.\n\nNote\n\n**Available for contract work.** I'm Kayden. I created Tesserae and maintain\nit, with help from a growing group of contributors. I take on contracts\nbuilding with AI: custom agents, MCP\nservers that connect AI models to your tools and data, and AI-assisted\ndevelopment workflows for teams. I also take on full-stack, embedded and Home\nAssistant projects, the same work Tesserae is built from.\n\nIf Tesserae is useful to you, sponsoring helps keep it independent and actively maintained.\n\n**[Email me about a contract](mailto:dmellok@icloud.com?subject=Contract%20work%20enquiry)** · **[Sponsor on GitHub](https://github.com/sponsors/dmellok)** · [Support on Ko-fi](https://ko-fi.com/dmellok)\n\nOpen source under AGPL-3.0-or-later. The self-hosted server needs no\naccount and never has to talk to us: the only outbound contact is\n`api.tesserae.ink` for update checks, an anonymous install count, and a\ndaily aggregate heartbeat, off by default and opt-in (you're asked once at\nfirst-run setup; toggle in Settings → System → Online features).\n\n[Tesserae Cloud](https://cloud.tesserae.ink/) is a separate hosted Tesserae\nfor people who would rather not run a server: sign in, create a dashboard, and\nconnect your display. This self-hosted server stays the full product and stays\nfree, and a supported panel is not tied to the cloud: it can be pointed at a\nserver of your own at any time, though dashboards made in the cloud are\nspecific to it and would need recreating here.\n\n**📖 [Full documentation](https://docs.tesserae.ink/):**\ninstall guides, [hardware quickstarts](https://docs.tesserae.ink/quickstart/),\n[widget gallery](https://docs.tesserae.ink/widgets/gallery/),\n[community catalog](https://tesserae.ink/catalog/),\n[architecture deep dive](https://docs.tesserae.ink/dev/architecture/),\n[how to build a widget](https://docs.tesserae.ink/dev/writing-a-widget/),\n[how to add hardware support](https://docs.tesserae.ink/dev/adding-hardware/).\n\n```\nmkdir tesserae && cd tesserae\ncurl -fsSLO https://raw.githubusercontent.com/dmellok/tesserae/main/docker-compose.yml\ndocker compose up -d\n```\n\nOpen [http://localhost:8765](http://localhost:8765). First request walks through password setup\nand the onboarding wizard.\n\nOther install paths:\n[Home Assistant App](https://docs.tesserae.ink/install/home-assistant/),\n[Proxmox VE helper script](https://docs.tesserae.ink/install/lxc/#proxmox-ve-helper-script),\n[LXC / MicroCloud](https://docs.tesserae.ink/install/lxc/),\n[macOS / Linux / Pi shell installer](https://docs.tesserae.ink/install/server/),\n[Windows PowerShell](https://docs.tesserae.ink/install/server/),\n[manual venv](https://docs.tesserae.ink/install/server/#manual-install).\n\nServer is running? Pick a [hardware quickstart](https://docs.tesserae.ink/quickstart/) to get a panel on the wall.\n\nDashboards are plain HTML. The editor preview and the production render\nload the **same URL**: a headless Chromium (Playwright) screenshots the\ncomposition at panel resolution, so \"looked fine in the editor, broke on\nthe panel\" is impossible by construction.\n\nThe frame then goes through a per-device renderer: Floyd-Steinberg\ndithering against the panel's **measured** color palette (Spectra 6 and\nACeP panels don't actually produce sRGB primaries; calibrated\nmeasurements come from [epdoptimize](https://github.com/paperlesspaper/epdoptimize)),\nthen packing into the exact byte format the panel wants: packed 4-bit\nSpectra 6, 1-bit mono, or 4-bit grayscale.\n\nDevices are deliberately **thin clients** with no on-device image\ndecoding. Always-on clients (a Pi driving an Inky) get frames pushed\nover MQTT the moment a page changes. Battery clients (ESP32) wake, `GET`\ntheir frame over REST with `If-None-Match` (a 304 skips both the\ndownload and the slow e-ink refresh), `POST` battery + RSSI telemetry,\nand deep-sleep on a server-driven interval. Wall-clock time comes from\nthe HTTP `Date` header, so there's no SNTP on-device.\n\n```\nbrowser editor          Tesserae server                    panels\n┌──────────┐   HTTP   ┌──────────────────────┐   MQTT   ┌─────────────┐\n│ composer │─────────▶│ headless render      │─────────▶│ Pi + Inky   │\n│ /compose │          │ dither (measured     │          ├─────────────┤\n└──────────┘          │   palettes)          │   REST   │ ESP32,      │\n                      │ pack panel-native    │◀────────▶│ Kindle,     │\n                      │ schedule / rotate    │          │ TRMNL       │\n                      └──────────────────────┘          └─────────────┘\n```\n\nEvery layer is a drop-a-folder plugin: widgets, themes, renderers,\ntransports, and device kinds. The seams are real directories:\n[`plugins/`](https://github.com/dmellok/tesserae/blob/main/plugins) · [` renderers/`](https://github.com/dmellok/tesserae/blob/main/renderers) ·\n[`transports/`](https://github.com/dmellok/tesserae/blob/main/transports) · [` devices/`](https://github.com/dmellok/tesserae/blob/main/devices).\n\n**Build dashboards with AI (MCP).** Tesserae exposes an\n[MCP](https://modelcontextprotocol.io) API so an agent can lay out a freeform\ndashboard, render a preview to check its work, and push it to a panel. It's on\nby default; run the\n[`tesserae-mcp`](https://github.com/dmellok/tesserae-mcp) bridge on your agent's\nmachine (a remote agent needs the token from Settings → System → MCP). See [the docs](https://docs.tesserae.ink/dev/mcp/).\n\n**Server-side rendering, dumb firmware.** The server pre-renders each\nframe into the exact bytes the panel controller wants; the\n[device firmware](https://github.com/dmellok/tesserae-device-firmware)\nstreams them straight to the panel. Adding a new panel is a board header\nplus one driver. The network, power, and provisioning stack never\nchanges.\n\n**Widget network egress is allowlisted.** Third-party widgets declare the\nnetwork hosts they need in a `requires:` block in `plugin.json`, and the\nhost enforces the allowlist at the socket layer. An undeclared connection\nraises `CapabilityDenied` instead of phoning home. That is the extent of\nthe containment: widgets otherwise run in-process, and the trust model is\nPR review of the community catalog, not a sandbox. The\n[threat model](https://docs.tesserae.ink/dev/publishing-a-widget/) is\ndocumented honestly, including what it doesn't catch.\n\n**One server, a fleet of panels.** Tesserae splits rendering from\ntransport from hardware, so a single instance drives every panel in the\nhouse, each with its own dashboards, schedules, and rotations.\n\n**Community widgets install from an audited catalog.** Pinned release\ntarballs, sha256-verified, schema-validated, PR-reviewed:\n[tesserae-widgets](https://github.com/dmellok/tesserae-widgets).\n\nTesserae renders to one of several panel families through drop-a-folder\ndevice plugins. In the tables below, ✅ means the panel has been\nconfirmed on real hardware (on my bench or via a community report);\nTBD means a client and hardware profile ship but nobody has confirmed a\nframe on the physical panel yet. The per-renderer bench matrix lives at\n[Screens & compatibility](https://docs.tesserae.ink/compatibility/).\n\n**Some links below are affiliate links.** Seeed product links and the\nPimoroni Inky Frame and Inky Impression links carry a Tesserae affiliate tag:\nbuying through one pays a small commission that goes back into the project,\nand a Seeed link also gets you a discount at checkout. Nothing is listed here because of it,\nand a panel's ✅ / TBD status means exactly what it says above. Links without\nthe tag are plain product links.\n\nThe reTerminal E-Series and XIAO ePaper family run the [Tesserae-native firmware](https://github.com/dmellok/tesserae-device-firmware); flash from the browser in one click at [tesserae.ink/flash](https://tesserae.ink/flash) (Chrome / Edge, Web Serial, no toolchain). Battery-powered, no assembly required.\n\n| Model | Panel | Client | Status | \n|---|---|---|---|\n| [reTerminal E1001](https://www.seeedstudio.com/reTerminal-E1001-p-6534.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 7.5\" mono, 800×480 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [reTerminal E1002](https://www.seeedstudio.com/reTerminal-E1002-p-6533.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 7.3\" Spectra 6, 800×480 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [reTerminal E1003](https://www.seeedstudio.com/reTerminal-E1003-p-6731.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 10.3\" mono, 16-level grey, 1872×1404 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [reTerminal E1004](https://www.seeedstudio.com/reTerminal-E1004-p-6692.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 13.3\" Spectra 6, 1200×1600 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [reTerminal Sticky](https://www.seeedstudio.com/reTerminal-Sticky-p-6861.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 3.97\" mono, 4-level grey, 480×800 portrait | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [XIAO ePaper EE02](https://www.seeedstudio.com/XIAO-ePaper-DIY-Kit-EE02-for-13-3-Spectratm-6-E-Ink.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 13.3\" Spectra 6, 1200×1600 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [XIAO ePaper EE03](https://www.seeedstudio.com/XIAO-ePaper-DIY-Kit-EE03-for-10-3-Monochrome-ePaper-Display.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 10.3\" mono, 16-level grey, 1872×1404 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | TBD | \n| [XIAO 7.5\" ePaper Panel](https://www.seeedstudio.com/XIAO-7-5-ePaper-Panel-p-6416.html) | 7.5\" mono, 800×480 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | TBD | \n| [TRMNL 7.5\" OG DIY Kit](https://www.seeedstudio.com/TRMNL-7-5-Inch-OG-DIY-Kit-p-6481.html?sensecap_affiliate=YcT0R1h&referring_service=link) | 7.5\" mono, 800×480 | TRMNL firmware | ✅ via BYOS | \n\nThe PaperS3's screen has no controller chip: the ESP32-S3 drives the glass directly and the 16 grey levels come from a waveform table in the firmware rather than from the panel. Greyscale tuning is therefore a firmware change. Partial refresh is not implemented yet, so this panel has no tap echo or on-device touch controls, and its touch digitiser is not wired up.\n\nThe link goes to M5's documentation rather than their store: M5 have marked the PaperS3 end of life and it is sold out, so this entry is for people who already own one.\n\nThe original **M5Paper** (pre-S3, classic ESP32-D0WDQ6-V3) drives the same\n4.7\" glass through an IT8951 controller over SPI, so it reuses the reTerminal\nE1003's greyscale driver. Also discontinued; this entry is for existing owners.\n\nThe **PaperMono** (2026, Pro and Lite) is a 3.97\" 480x800 4-level greyscale\nhandheld on the reTerminal Sticky's controller family, so it reuses that\ndriver and wire format; its panel rails sit behind an I2C IO expander and\nits battery is read from the on-board PMIC. Confirmed on hardware; touch,\nmicroSD and the frontlight are not wired yet.\n\n| Model | Panel | Client | Status | \n|---|---|---|---|\n| [M5Paper](https://docs.m5stack.com/en/core/m5paper) | 4.7\" mono, 16-level grey, 960×540 (IT8951) | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n| [PaperS3](https://docs.m5stack.com/en/core/PaperS3) | 4.7\" mono, 16-level grey, 960×540 | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | TBD | \n| [PaperMono / PaperMono Lite](https://docs.m5stack.com/en/core/PaperMono) | 3.97\" mono, 4-level grey, 480×800 portrait (SSD1677) | [tesserae-device-firmware](https://github.com/dmellok/tesserae-device-firmware) | ✅ | \n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| [Inky Impression 4\"](https://collabs.shop/ko5ulg) (6-colour Spectra 6) | 600×400 | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | ✅ | \n| Inky Impression 4\" (legacy 7-colour ACeP) | 640×400 | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | ✅ | \n| [Inky Impression 5.7\"](https://shop.pimoroni.com/products/inky-impression-5-7) (7-colour ACeP) | 600×448 | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | ✅ | \n| [Inky Impression 7.3\"](https://collabs.shop/ko5ulg) (6-colour Spectra 6) | 800×480 | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | ✅ | \n| [Inky Impression 13.3\"](https://collabs.shop/ko5ulg) (6-colour Spectra 6) | 1600×1200 | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | ✅ | \n| Inky [pHAT](https://shop.pimoroni.com/products/inky-phat) /[wHAT](https://shop.pimoroni.com/products/inky-what) | various | [tesserae-device-pi](https://github.com/dmellok/tesserae-device-pi) | works via `pi_png` | \n\nThe Inky Frame and the Badgers carry their own microcontroller, so they need no\nRaspberry Pi. The Inky Frame runs\n[tesserae-device-inkyframe](https://github.com/dmellok/tesserae-device-inkyframe)\n(Pico SDK firmware, the Tesserae fork of Carl Partridge's client: setup from a\nphone, button letters, signed over-the-air updates); flash it from the browser\nat [tesserae.ink/flash/inky-frame](https://tesserae.ink/flash/inky-frame)\n(Chrome / Edge, WebUSB, no toolchain). The Badgers run\n[tesserae-device-badger](https://github.com/dmellok/tesserae-device-badger), an\napp inside the badge's own launcher, so the badge keeps its other apps.\n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| [Inky Frame 7.3\"](https://collabs.shop/7ab9wa) (6-colour Spectra 6, Pico 2 W) | 800×480 | [tesserae-device-inkyframe](https://github.com/dmellok/tesserae-device-inkyframe) | ✅ | \n| Inky Frame 7.3\" (legacy 7-colour ACeP) | 800×480 | [tesserae-device-inkyframe](https://github.com/dmellok/tesserae-device-inkyframe) | TBD | \n| [Badger 2350](https://shop.pimoroni.com/products/badger-2350) | 264×176, 4-level grey | [tesserae-device-badger](https://github.com/dmellok/tesserae-device-badger) | ✅ | \n| [Badger 2040 W](https://shop.pimoroni.com/products/badger-2040-w) | 296×128, mono | [tesserae-device-badger](https://github.com/dmellok/tesserae-device-badger) | TBD | \n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| [Waveshare 13.3\" Spectra 6 (ESP32-S3)](https://www.waveshare.com/esp32-s3-epaper-13.3e6.htm) | 1200×1600 | [esp32-bin](https://github.com/dmellok/tesserae-device-esp32-bin) | ✅ | \n| [Waveshare 7.3\" PhotoPainter (ESP32-S3)](https://www.waveshare.com/esp32-s3-photopainter.htm) | 800×480 | [photopainter-7.3-bin](https://github.com/dmellok/tesserae-device-photopainter-7.3-bin) | ✅ | \n| [Waveshare 4.2\" B/W (ESP32)](https://www.waveshare.com/4.2inch-e-paper-module.htm) | 400×300 | [esp32-bw](https://github.com/dmellok/tesserae-device-esp32-bw) | TBD | \n\nXteink's X-series e-readers run [CrossInk](https://github.com/uxjulia/CrossInk)\nfirmware with Tesserae client support: the dashboard becomes the reader's\nsleep screen, painted on the sleep transition rather than on a timer.\n\n| Model | Panel | Client | Status | \n|---|---|---|---|\n| Xteink X3 (4-level grayscale) | 792×528, gray | CrossInk | ✅ | \n| Xteink X3 (mono) | 792×528, mono | CrossInk | TBD | \n| Xteink X4 | 800×480, mono | CrossInk | ✅ | \n| Xteink X4 (4-level grayscale) | 800×480, gray | CrossInk | ✅ | \n| Xteink X4 Pro | 800×480, mono | CrossInk | TBD | \n\nCommunity-authored clients, contributed and maintained by their authors (not in the Tesserae org). Thanks to everyone building these.\n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| [PicPak 4.2\" BWRY](https://docs.tesserae.ink/hardware/picpak/) | 400×300 (4-colour BWRY) | [picpak-tesserae-client](https://github.com/varanu5/picpak-tesserae-client) by[@varanu5](https://github.com/varanu5) | ✅ | \n| [ZecTrix NOTE4C Devkit](https://docs.tesserae.ink/hardware/note4c/) | 400×300 (4-colour BWRY) | [note4c-tesserae-client](https://github.com/varanu5/zectrix-note4c-devkit-tesserae-client) by[@varanu5](https://github.com/varanu5) | ✅ | \n| [Soldered Inkplate 10](https://soldered.com/products/inkplate-10) | 1200×825 (9.7\" 16-level grey) | [tesserae.inkplate](https://github.com/partridgeworks/tesserae.inkplate) by[@partridgeworks](https://github.com/partridgeworks) | ✅ | \n| [Soldered Inkplate 6COLOR](https://soldered.com/products/inkplate-6color-e-paper-display) | 600×448 (5.85\" 7-colour ACeP) | [inkplate-tesserae-driver](https://github.com/ripking/inkplate-tesserae-driver) by[@ripking](https://github.com/ripking) | ✅ | \n| [Soldered Inkplate 13SPECTRA](https://soldered.com/products/inkplate-13spectra) | 1600×1200 (13.3\" Spectra 6) | [inkplate-tesserae-driver](https://github.com/ripking/inkplate-tesserae-driver) by[@ripking](https://github.com/ripking) | ✅ | \n| [Pimoroni Inky Frame 7.3\"](https://shop.pimoroni.com/products/inky-frame-7-3) (7-colour ACeP) | 800×480 | [tesserae.inkyframe](https://github.com/partridgeworks/tesserae.inkyframe) by[@partridgeworks](https://github.com/partridgeworks) | ✅ | \n| Pimoroni Inky Frame 7.3\" (6-colour Spectra 6) | 800×480 | [tesserae.inkyframe](https://github.com/partridgeworks/tesserae.inkyframe) by[@partridgeworks](https://github.com/partridgeworks) | TBD | \n| [reMarkable 2](https://remarkable.com/products/remarkable-2) | 1404×1872 (10.3\" 16-level grey) | [tesserae.remarkable](https://github.com/partridgeworks/tesserae.remarkable) by[@partridgeworks](https://github.com/partridgeworks) | ✅ | \n| [reMarkable 1](https://remarkable.com) | 1404×1872 (10.3\" 16-level grey) | [tesserae.remarkable](https://github.com/partridgeworks/tesserae.remarkable) by[@partridgeworks](https://github.com/partridgeworks) | TBD | \n| [reMarkable Paper Pro](https://remarkable.com/products/remarkable-paper/pro) | 1620×2160 (11.8\" colour) | [tesserae.remarkable](https://github.com/partridgeworks/tesserae.remarkable) by[@partridgeworks](https://github.com/partridgeworks) | TBD | \n\nE-readers running [KOReader](https://koreader.rocks) with the\n[Tesserae plugin](https://github.com/dmellok/tesserae-koreader). The plugin\npairs with a claim code, decodes 16-level greyscale frames on the reader, and\nsleeps between refreshes where KOReader exposes the hardware alarm. Kindles need\na jailbreak to run KOReader; Kobo does not.\n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| Kindle Paperwhite 2 (jailbroken) | 758×1024 | [tesserae-koreader](https://github.com/dmellok/tesserae-koreader) | TBD | \n| Kindle Paperwhite 3/4, Voyage, Basic 4 | 1072×1448 | [tesserae-koreader](https://github.com/dmellok/tesserae-koreader) | TBD | \n| Kindle Paperwhite 5, Oasis 3, Scribe | 1236×1648, 1264×1680, 1860×2480 | [tesserae-koreader](https://github.com/dmellok/tesserae-koreader) | TBD | \n| Kobo Clara HD, Libra 2, Sage, Aura | various | [tesserae-koreader](https://github.com/dmellok/tesserae-koreader) | TBD | \n\nAny client implementing the [TRMNL BYOS spec](https://help.trmnl.com/en/articles/12263392-connect-your-device-to-terminus-byos)\nworks against the `trmnl_png` renderer.\n\n| Panel | Resolution | Client | Status | \n|---|---|---|---|\n| [TRMNL OG](https://shop.trmnl.com/products/trmnl) | 800×480 | TRMNL firmware | TBD via BYOS | \n| [TRMNL X](https://shop.trmnl.com/products/trmnl-x) | 1872×1404 (10.3\") | TRMNL firmware | TBD | \n| Amazon Kindle Paperwhite 2 (jailbroken) | 758×1024 | [KOReader trmnl-display plugin](https://github.com/koreader/koreader) (1-bit; see the KOReader section above for the Tesserae plugin) | ✅ | \n\nAnything else: pick `custom` in **Settings → Panel** and set the\ndimensions. If a client drives your panel, Tesserae can push frames\nto it. A generic CircuitPython client (400+ boards) is in development;\nfollow [discussion #24](https://github.com/dmellok/tesserae/discussions/24).\n\nPer-client setup walkthroughs (the firmware repos in the Client column):\n[Install a client](https://docs.tesserae.ink/install/clients/).\nFull renderer / device-kind compatibility matrix:\n[Screens & compatibility](https://docs.tesserae.ink/compatibility/).\n\nPre-1.0 and moving fast. Every release is documented in the\n[CHANGELOG](https://github.com/dmellok/tesserae/blob/main/CHANGELOG.md). CI runs pytest (7,700+ tests), the Lineups\nbrowser tests in Chromium, ruff, and mypy (strict on the render/push\npipeline modules) on every push; coverage (86% at last count) is measured\nweekly, report only.\n\nBuilt with AI assistance (Claude Code). Architecture decisions, code review, hardware testing, and what ships vs. what doesn't are mine. The changelogs document the debugging in the open.\n\nTesserae contacts one first-party endpoint, `api.tesserae.ink`, for\nupdate checks, an anonymous marketplace install count, and a daily\naggregate heartbeat (version, platform, deployment kind, device kinds; no\nexact counts). No accounts, no personal data, no IP addresses stored, no\nthird-party analytics. It is **off by default** and opt-in: a fresh install asks once\nat first-run setup, and it's a single switch at **Settings → System →\nOnline features**. Per-device diagnostics (battery, RSSI, sleep cadence)\nstay on the box. [Privacy](https://docs.tesserae.ink/privacy/).\n\n- **[Discussions](https://github.com/dmellok/tesserae/discussions)** for show-your-dashboard, widget pitches, and install help.\n- **[Contributing guide](https://github.com/dmellok/tesserae/blob/main/.github/CONTRIBUTING.md)** for dev setup, the three checks (pytest / ruff / mypy), and commit conventions.[Good first issues](https://github.com/dmellok/tesserae/labels/good%20first%20issue) .\n- **[Hardware reports](https://github.com/dmellok/tesserae/issues/new?template=hardware_compat.yml)** : running an unlisted panel? A compat report is a real contribution.\n- **[Security policy](https://github.com/dmellok/tesserae/blob/main/.github/SECURITY.md)** ·**[Code of conduct](https://github.com/dmellok/tesserae/blob/main/.github/CODE_OF_CONDUCT.md)**\n\nThe server stays free even when someone runs it as a service: improvements have to stay public. And a dashboard for your home shouldn't report home. No analytics, no accounts, nothing phones out. Don't take the README's word for it; read the source.\n\nTesserae stands on generously-licensed open source: Phosphor Icons,\nChart.js, 20 typefaces under SIL OFL / Apache 2.0, the TRMNL BYOS\nprotocol, the KOReader trmnl-display plugin, and\n[paperlesspaper/epdoptimize](https://github.com/paperlesspaper/epdoptimize)'s\nSpectra 6 + ACeP calibrated palette measurements (also shipped as\nselectable presets in the Calibration tab under Apache 2.0). Full\nattribution:\n[Credits](https://docs.tesserae.ink/credits/),\n[NOTICES.md](https://github.com/dmellok/tesserae/blob/main/NOTICES.md).\n\nAGPL-3.0-or-later, see [LICENSE](https://github.com/dmellok/tesserae/blob/main/LICENSE).", "url": "https://wpnews.pro/news/tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels", "canonical_source": "https://github.com/dmellok/tesserae", "published_at": "2026-11-12 07:46:26+00:00", "updated_at": "2026-11-12 08:22:53.322309+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "agent-protocols"], "entities": ["Tesserae", "Kayden", "Tesserae Cloud", "Playwright", "epdoptimize", "Home Assistant", "GitHub", "MQTT"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels", "markdown": "https://wpnews.pro/news/tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels.md", "text": "https://wpnews.pro/news/tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels.txt", "jsonld": "https://wpnews.pro/news/tesserae-e-ink-dashboard-companion-compose-dashboards-and-push-to-e-ink-panels.jsonld"}}