Home Assistant custom component that renders e-ink dashboard images as PNG from entity state using SVG templates rasterised by resvg, and serves them to Kindle, TRMNL, and OpenDisplay devices. No headless browser or other server component required running.
{{ now().strftime('%H:%M') }})https://github.com/cryptomilk/hass-eink-dashboard with
category Integration.Once the repository is included in the HACS default store, steps 2–3 can be skipped.
eink_dashboard.zip from the
latest release.custom_components/eink_dashboard/:bash
mkdir -p /path/to/homeassistant/custom_components/eink_dashboard
unzip eink_dashboard.zip -d /path/to/homeassistant/custom_components/eink_dashboard/
Go to Settings -> Devices & Services -> Add Integration and search for E-Ink Dashboard.
| Field | Description |
|---|---|
| Name | Label for this dashboard (e.g. "Kitchen Kindle") |
| Device model | Select your e-ink display from the preset list, or choose Custom to enter a resolution manually |
| Orientation | Portrait or landscape layout |
| Area | Optional - assign the device to a Home Assistant area |
| Update interval | How often to re-render, in seconds (default: 60) |
Supported device presets:
| Preset | Resolution | Grayscale levels |
|---|---|---|
| Kindle 4/5 | 600 × 800 | 16 |
| Kindle Paperwhite 1/2/3 | 758 × 1024 | 16 |
| Kindle Paperwhite 4 | 1072 × 1448 | 16 |
| Kindle Oasis 2/3 | 1264 × 1680 | 16 |
| TRMNL OG | 800 × 480 | 2 (black & white) |
| TRMNL X | 1872 × 1404 | 16 |
| TRMNL RGB | 2560 × 1440 | 2 (black & white) |
| Seeed reTerminal E1001 | 800 × 480 | 4 |
| Seeed reTerminal E1003 | 1404 × 1872 | 16 |
| Custom | user-defined | 16 |
For Custom devices, you get a choice:
For Kindle presets, the integration is configured in pull mode automatically. For TRMNL presets, you are guided through the webhook setup.
After setup, click Configure on the integration entry to:
The component ships a WYSIWYG Lovelace card for editing the dashboard layout.
Go to Settings -> Dashboards -> Add Dashboard. Give it a name (e.g. "Kitchen Kindle") and save.
Open the new dashboard, click the three-dot menu -> Edit dashboard -> Raw configuration editor.
Paste the YAML. You can get it from the integration's Configure menu (Copy card YAML or Copy dashboard YAML), or write it manually:
yaml
views:
- title: E-Ink Dashboard
cards:
- type: custom:eink-dashboard-card
config_entry: <entry_id>
The config_entry field selects which display to edit. Find the entry ID
in the integration URL or use the Copy card YAML option. If you only
have one E-Ink Dashboard entry, you can omit config_entry and the card
will auto-discover it.
| Type | What it renders |
|---|---|
| Heading | Static or Jinja2 template text (e.g. {{ now().strftime('%H:%M') }}) |
| Separator | Full-width horizontal or vertical rule |
| Entity | Label / state row for a single entity |
| Entities | Label / state rows for a list of entities, with optional title |
| Tile | Card-style tile with icon and entity state |
| Sensor | Entity state with sparkline history graph |
| Graph | Time-series line or bar chart for one or more numeric entities |
| Gauge | Arc-style gauge for a single numeric entity |
| Weather | Current conditions + N-day forecast with icons |
| Calendar | Upcoming events from a Home Assistant calendar entity |
| Device Battery | Battery level indicator for a device |
| Frame | Decorative rounded-corner box for visual grouping |
| Waste Schedule | Upcoming waste collection dates (today, tomorrow, in N days) |
All widgets support x, y positioning. Most support a w (width) override
to constrain rendering to a sub-region of the display.
Use kndl-online-screensaver on your Kindle. It supports ETag-based conditional fetching (skips the download and e-ink refresh when the image has not changed) and battery reporting.
Point it at the public image endpoint:
http://<ha-ip>:8123/api/eink_dashboard/<entry_id>/image.png
This endpoint requires no authentication.
Older Kindles cannot connect to modern HTTPS servers. If Home Assistant is behind an HTTPS reverse proxy, add an HTTP-only location for the image endpoint:
server {
listen 80;
server_name homeassistant.example.com;
# E-Ink dashboard image - plain HTTP for Kindle
location ~ ^/api/eink_dashboard/[^/]+/image\.png$ {
proxy_pass http://127.0.0.1:8123;
}
# Everything else → HTTPS
location / {
return 301 https://$host$request_uri;
}
}
This exposes only the unauthenticated image endpoint over HTTP. The authenticated layout API remains HTTPS-only.
https://trmnl.com/api/custom_plugins/<uuid>).HA pushes the rendered PNG to TRMNL whenever the image changes, subject to a minimum interval of 5 minutes and a 5 MB size cap per push.
You can add multiple TRMNL webhook targets per dashboard entry via Configure -> Add push target.
OpenDisplay fetches images from Home Assistant's Media Browser. The integration registers a Media Source platform that exposes each dashboard entry as a media item, so OpenDisplay can pull the latest rendered PNG without any additional configuration.
In the OpenDisplay app, point it at your Home Assistant instance and select the dashboard entry from the Media Browser. OpenDisplay will refresh the image on its own schedule, respecting the ETag so it only re-renders the display when the image has actually changed.
Apache 2.0 -- see LICENSE.
Weather icons from erikflowers/weather-icons, licensed under SIL Open Font License 1.1.
Roboto font by Google, licensed under Apache 2.0.
$ claude mcp add hass-eink-dashboard \
-- python -m otcore.mcp_server <graph>