Home Assistant custom component that renders e-ink dashboard images as PNG directly from entity state using Pillow, and serves them to Kindle and TRMNL devices. No Chromium, no ImageMagick, no Node.js.
- Multiple e-ink displays - create a separate dashboard for each device with its own layout, resolution, and refresh interval
- Device presets - built-in profiles for Kindle 4/5, Paperwhite 1-4, Oasis 2/3, TRMNL OG/X/RGB, or enter a custom resolution
- Portrait and landscape - rotation is handled automatically based on the device preset and chosen orientation
- WYSIWYG Lovelace editor - drag, resize, and configure widgets on a canvas preview that matches your device's exact pixel dimensions
- Pull and push delivery - devices can fetch the image on their own schedule (Kindle) or have HA push it via webhook (TRMNL)
- E-ink optimization - optional post-processing pipeline: autocontrast, sharpness, contrast adjustment, and grayscale quantization (2/4/16/256 levels with Floyd-Steinberg dithering)
- Jinja2 templates - text widgets support Home Assistant templates
(e.g.
{{ now().strftime('%H:%M') }}) - ETag support - conditional HTTP responses so devices skip the download and e-ink refresh when the image has not changed
- Webhook rate limiting - push targets are throttled to one push per 5 minutes with a 5 MB size cap
- Open HACS in your Home Assistant instance.
- Click the three-dot menu → Custom repositories.
- Add
https://github.com/cryptomilk/hass-eink-dashboardwith category Integration. - Search for "E-Ink Dashboard" and click Download.
- Restart Home Assistant.
Once the repository is included in the HACS default store, steps 2–3 can be skipped.
-
Download
eink_dashboard.zipfrom the latest release. -
Extract into
custom_components/eink_dashboard/:mkdir -p /path/to/homeassistant/custom_components/eink_dashboard unzip eink_dashboard.zip -d /path/to/homeassistant/custom_components/eink_dashboard/
-
Restart Home Assistant.
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) |
| Custom | user-defined | 16 |
For Custom devices, you get a choice:
- Pull only - the device fetches the image from HA on its own schedule. Choose this for Kindle.
- TRMNL webhook - HA pushes the rendered PNG to TRMNL after each render. See TRMNL setup below.
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:
- Device settings - change device model, orientation, or area
- Display settings - update interval, e-ink optimization toggle, grayscale levels, sharpness, contrast
- Add / remove push target - manage TRMNL webhook URLs
- Copy card YAML - get the Lovelace card snippet for this device
- Copy dashboard YAML - get a full dashboard YAML with cards for all configured devices
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:
views: - title: E-Ink Dashboard cards: - type: custom:eink-dashboard-card config_entry: <entry_id>
The
config_entryfield 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 omitconfig_entryand the card will auto-discover it. -
Save. The card shows a live canvas preview at the exact pixel dimensions of your device.
- Click Edit Widgets to open the editor panel.
- Add widgets from the dropdown, reorder them with the up/down buttons, and configure each widget's properties in the form.
- Click Save to persist the layout. The image entity is refreshed immediately.
- Click Show rendered image to fetch the actual Pillow-rendered PNG for a pixel-exact comparison with the canvas preview.
| Type | What it renders |
|---|---|
| Text | Static or Jinja2 template text (e.g. {{ now().strftime('%H:%M') }}) |
| Line | Horizontal or diagonal line |
| Separator | Full-width horizontal rule |
| Weather | Current conditions + N-day forecast with icons |
| Sensor Rows | Label / value rows for a list of sensors |
| Battery Bar | Horizontal battery level bar with percentage |
| Status Icons | Row of filled/outline squares for binary sensors |
| Waste Schedule | Upcoming waste collection dates (today, tomorrow, in N days) |
All widgets support x, y positioning and font_size. 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.
- Go to usetrmnl.com -> Plugins -> Webhook Image.
- Give the plugin a name, set Image Fit Mode to Contain, and click Save.
- Copy the Webhook URL (looks like
https://trmnl.com/api/custom_plugins/<uuid>). - During the HA config flow, choose TRMNL webhook and paste the URL.
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.
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.