MCPcopy Index your code
hub / github.com/cryptomilk/hass-eink-dashboard

github.com/cryptomilk/hass-eink-dashboard @v0.5.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.0 ↗ · + Follow
1,534 symbols 7,319 edges 75 files 378 documented · 25%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

E-Ink Dashboard for Home Assistant

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.

Features

  • 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 server-rendered SVG preview that matches your device's exact pixel dimensions
  • Pull and push delivery - devices can fetch the image on their own schedule (Kindle, OpenDisplay) 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 - heading 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

Installation

HACS (recommended)

  1. Open HACS in your Home Assistant instance.
  2. Click the three-dot menu → Custom repositories.
  3. Add https://github.com/cryptomilk/hass-eink-dashboard with category Integration.
  4. Search for "E-Ink Dashboard" and click Download.
  5. Restart Home Assistant.

Once the repository is included in the HACS default store, steps 2–3 can be skipped.

Manual

  1. Download eink_dashboard.zip from the latest release.
  2. Extract into 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/

  1. Restart Home Assistant.

Setup

Go to Settings -> Devices & Services -> Add Integration and search for E-Ink Dashboard.

Step 1 -- Device

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

Step 2 -- Image delivery

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.

Reconfigure

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

Dashboard setup

The component ships a WYSIWYG Lovelace card for editing the dashboard layout.

Quick start

  1. Go to Settings -> Dashboards -> Add Dashboard. Give it a name (e.g. "Kitchen Kindle") and save.

  2. Open the new dashboard, click the three-dot menu -> Edit dashboard -> Raw configuration editor.

  3. 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.

  1. Save. The card shows a live server-rendered SVG preview at the exact pixel dimensions of your device.

Editing widgets

  1. Click Edit Widgets to open the editor panel.
  2. Add widgets from the dropdown, reorder them with the up/down buttons, and configure each widget's properties in the form.
  3. Click Save to persist the layout. The image entity is refreshed immediately.
  4. Click Show rendered image to fetch the actual server-rendered PNG for a preview of what the device will display.

Available widgets

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.

Device setup

Kindle

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.

Kindle and HTTPS (nginx)

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.

TRMNL

  1. Go to usetrmnl.com -> Plugins -> Webhook Image.
  2. Give the plugin a name, set Image Fit Mode to Contain, and click Save.
  3. Copy the Webhook URL (looks like https://trmnl.com/api/custom_plugins/<uuid>).
  4. 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.

OpenDisplay

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.

License

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.

Extension points exported contracts — how you extend this code

BaseCondition (Interface)
Discriminant base shared by all structured condition types.
custom_components/eink_dashboard/frontend/src/types/ha.d.ts
WidgetBase (Interface)
* Common fields shared by every widget type. * * All positional and sizing fields are optional because some widget *
custom_components/eink_dashboard/frontend/src/types/ha.d.ts
EinkWidgetPicker (Interface)
(no doc) [1 implementers]
custom_components/eink_dashboard/frontend/src/types/ha.d.ts
EinkEditorElement (Interface)
(no doc) [1 implementers]
custom_components/eink_dashboard/frontend/src/types/ha.d.ts
CardConfig (Interface)
(no doc)
custom_components/eink_dashboard/frontend/src/eink-dashboard-card.ts

Core symbols most depended-on inside this repo

get
called by 466
custom_components/eink_dashboard/http.py
render_to_image
called by 270
tests/helpers.py
render_widget_svg
called by 214
custom_components/eink_dashboard/svg_render.py
assert_has_dark_pixels
called by 146
tests/helpers.py
_compute_metrics
called by 137
custom_components/eink_dashboard/render.py
render_dashboard
called by 85
custom_components/eink_dashboard/render.py
assert_all_white
called by 75
tests/helpers.py
color_to_hex
called by 71
custom_components/eink_dashboard/const.py

Shape

Method 1,129
Function 227
Class 120
Interface 56
Route 2

Languages

Python89%
TypeScript11%

Modules by API surface

tests/test_render_graph.py141 symbols
tests/test_config_flow.py94 symbols
tests/test_render_utils.py80 symbols
tests/test_conditions.py69 symbols
tests/conftest.py65 symbols
custom_components/eink_dashboard/frontend/src/types/ha.d.ts59 symbols
tests/test_http.py51 symbols
tests/test_render_calendar.py49 symbols
custom_components/eink_dashboard/frontend/src/eink-dashboard-card.ts48 symbols
tests/test_render_sensor_card.py46 symbols
tests/test_render_waste_schedule.py45 symbols
tests/test_render_gauge.py42 symbols

For agents

$ claude mcp add hass-eink-dashboard \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page