So I picked up one of these TRMNL e-ink displays recently:
They’re very open and developer-friendly in the sense that you can write your own plugins for it, all the server and firmware code is open source, and so on. (It’s also very easy to point it at a different server URL instead of using TRMNL’s cloud service, which will become relevant in a moment.)
But there’s no Home Assistant plugin for it yet.
Anyway, after a few hours hacking, I have this:
It’s clearly not finished but it’s a start.
The approach that I’m taking is perhaps a little bit weird but I think it makes sense. Usually, you would write a “private plugin” which runs on TRMNL’s server and which has to get data from your HA instance somehow - tricky if that’s only available inside a LAN. Instead I’m running my own replacement server locally which fulfils the TRMNL API and feeds back information from HA. The API is very simple, there’s only about three endpoints to implement, so the “server” part of it is about 100 lines of Python code.
The interesting part comes when the device asks for a new “screen”; the server has to produce a bitmap image for it to display. TRMNL’s own server handles this by generating HTML and screenshotting it with Selenium, then massaging the screenshot with ImageMagick to make it render better on a 1-bit screen. So my first thought was to do the same: generate a separate kiosk-style dashboard in HA for each TRMNL device, have Selenium load that up and screenshot it, and then post-process.
The result was completely unreadable; generic HTML pages won’t look great on a small 1-bit screen, which is why TRMNL has its own HTML/CSS design system optimised for 1-bit rendering. I guess with a lot of messing about with global-mod you could probably style a dashboard to be somewhat TRMNL-friendly, but I wanted to produce output which fits with the Framework styling so I’ve completely over-engineered it.
Instead, I’m using HA’s WS API to get the JSON description of a dashboard, then rendering each card using the TRMNL Framework. As you can see I’ve added code to render badges and gauges so far, with custom elements not yet supported. (I think it’s reasonable to only support a limited set of cards for this purpose - the idea is to have something you can design in the Lovelace dashboard editor which will render on your TRMNL.)
As I said I’m still not convinced this is the easiest approach but it’s certainly the one which made most sense to me. The code is a bit scrappy with lots of hard-coded constants and only supports a single TRMNL device, but I’ll try and clean it up and put it on GitHub soon.
At any rate, if you’re thinking of getting a TRMNL and the lack of HA support is putting you off, give me a ping and we’ll see if we can fix it.