HomePlate uses a WiFi captive portal for configuration. No config.h file is required.
Visit the HomePlate Web Installer in Chrome or Edge on desktop. Select your board variant, connect your Inkplate via USB, and click Install. No development tools required. Pre-built firmware is also available on the Releases page.
Install PlatformIO and flash via USB. See the Development Guide for full build and flash instructions.
On first boot (or when the device is unconfigured), HomePlate will:
- Create a WiFi access point named HomePlate-Setup
- Display the AP name and a QR code on the e-ink screen
- Wait up to 15 minutes for configuration before sleeping
Connect to the HomePlate-Setup WiFi network from your phone or computer. A captive portal page will open automatically (or navigate to 192.168.4.1).
The portal has several pages:
- Configure WiFi — Select your WiFi network, enter the password, and configure all HomePlate settings (see Settings Reference below)
- Display Message — Send a custom text message to the e-ink display for testing
- Show WiFi QR — Display the Guest WiFi QR code on the screen
- Show Info Screen — Display the device info screen (battery, IP, version, etc.)
| WiFi & Network | Network, Time & Sleep | Content, TRMNL & QR | MQTT, Display & OTA |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
After saving, the device will reboot and connect to your WiFi network with the new settings.
If MQTT is configured, most settings are exposed as native Home Assistant entities via MQTT Discovery and can be changed directly from HA without entering the config portal. Exposed settings include sleep duration, default activity, image URL, TRMNL credentials, dither kernel, show-update-time, timezone, and the guest WiFi QR fields, plus Reboot and Enter Setup Mode buttons. Changes persist to NVS. Network-critical settings (WiFi, MQTT broker, hostname, OTA, static IP) remain portal-only. See hass.md for the full list and topic layout.
Hold the wake button while the device boots (press reset or wait for a sleep wake cycle) to force the config portal to open. The device will connect to your saved WiFi and open the HomePlate-Setup AP simultaneously, allowing you to reconfigure any settings.
Inkplate 6 (original): This board does not have a dedicated wake button. Instead, short GPIO 13 to GND during boot to enter config mode. (a paperclip should to the trick)
You can also re-flash the firmware to trigger setup mode again — the config portal will open if the device detects its activity is missing required settings.
To clear all saved settings and start fresh, use the Web Installer and select the option to erase the device during installation. For PlatformIO users, see the Development Guide.
All settings below can be configured through the WiFi portal. They are saved to the device's non-volatile storage (NVS) and persist across reboots and firmware updates. A subset can also be changed at runtime via Home Assistant / MQTT — see hass.md.
| Setting | Description | Default |
|---|---|---|
| Hostname | Device hostname (mDNS, OTA, MQTT topics) | homeplate |
| Static IP | Static IP address (blank = DHCP) | blank |
| Static Subnet | Subnet mask for static IP | blank |
| Static Gateway | Gateway for static IP | blank |
| Static DNS | DNS server for static IP | blank |
| Setting | Description | Default |
|---|---|---|
| NTP Server | NTP time server | pool.ntp.org |
| Timezone | POSIX TZ string (see Timezone Strings) | UTC0 |
| Setting | Description | Default |
|---|---|---|
| Sleep Minutes | Minutes between display refreshes | 20 |
| Quick Sleep Seconds | Sleep duration for Info/QR activities | 300 (5 min) |
| Always On | Never sleep; stay connected (external power only) | false |
Normally the device deep-sleeps between refreshes. It is off the network while asleep, so nothing — including Home Assistant — can reach it; MQTT commands are retained on the broker and applied at the next wake.
Always On keeps the device awake and connected instead. MQTT commands take effect immediately rather than at the next wake, which is the point of the mode: the panel updates when a state actually changes, not on a timer. The default activity still re-runs every Sleep Minutes as a backstop, so the panel stays current even if MQTT drops.
This requires external power. A HomePlate that never sleeps will flatten a battery in well under a day. Nothing stops you enabling it on battery, and the low-battery cutoff still forces a deep sleep to avoid deep-discharging the cell, but the device is not designed to run this way unpowered.
Pair this with an image server that sends ETag or Last-Modified (see
Unchanged images) — otherwise the panel does a full e-ink
refresh every Sleep Minutes whether or not anything changed.
| Setting | Description | Default |
|---|---|---|
| Image URL | URL of PNG image to display (for HomeAssistant activity) | blank |
| Default Activity | Activity to run on boot: HomeAssistant, Trmnl, Info, GuestWifi |
HomeAssistant |
| Setting | Description | Default |
|---|---|---|
| TRMNL URL | TRMNL API endpoint | https://trmnl.app/api/display |
| TRMNL ID | Device ID from trmnl.com/devices | blank |
| TRMNL Token | API Key from TRMNL Device Credentials | blank |
| TRMNL Logging | Send device logs to TRMNL (true/false) |
true |
| Setting | Description | Default |
|---|---|---|
| QR WiFi SSID | WiFi network name for QR code | blank |
| QR WiFi Password | WiFi password for QR code | blank |
| Setting | Description | Default |
|---|---|---|
| MQTT Host | MQTT broker hostname (blank = disabled) | blank |
| MQTT Port | MQTT broker port | 1883 |
| MQTT User | MQTT username | blank |
| MQTT Password | MQTT password | blank |
| MQTT Device Name | HA device name (blank = hostname) | blank |
| MQTT Expire After Sec | Sensor expiry time in seconds (0 = auto) | 0 |
| Setting | Description | Default |
|---|---|---|
| Show Update Time | Display timestamp on image updates (true/false) |
true |
| Enable OTA | Enable over-the-air firmware updates (true/false) |
false |
When the image server sends an ETag or Last-Modified header, HomePlate
remembers it and sends a conditional request on the next refresh. If the server
answers 304 Not Modified, the download body and the e-ink refresh are both
skipped and the panel is left as-is — saving the most expensive part of a wake
cycle when the image has not actually changed. Servers that send neither header
never get a conditional request and behave exactly as before.
Two things worth knowing:
- Show Update Time goes stale on skipped refreshes. The timestamp is drawn during a render, so if nothing changed for an hour the on-screen time still reads from the last real update.
- The on-screen boot message is suppressed on wakes that might skip the render, since a skip would leave it stranded over the unchanged image. It still appears on cold boots and is always logged to serial.
- Anything that repaints the panel (a message, the info or QR screen, an error banner, a low-battery warning) drops the cached validator, so the next refresh redraws the image unconditionally.
The timezone setting uses POSIX TZ strings. Common examples:
| Timezone | POSIX String |
|---|---|
| US Pacific | PST8PDT,M3.2.0,M11.1.0 |
| US Mountain | MST7MDT,M3.2.0,M11.1.0 |
| US Central | CST6CDT,M3.2.0,M11.1.0 |
| US Eastern | EST5EDT,M3.2.0,M11.1.0 |
| UTC | UTC0 |
| UK / Ireland | GMT0BST,M3.5.0/1,M10.5.0 |
| Central Europe | CET-1CEST,M3.5.0,M10.5.0/3 |
| Australia Eastern | AEST-10AEDT,M10.1.0,M4.1.0/3 |
| Japan | JST-9 |
| India | IST-5:30 |
For a full list, see POSIX TZ database.
For advanced users who build from source, compile-time defaults and additional settings are available. See the Development Guide for details.



