Homeassistant Kindle Display

I use a kindle to display status information like next waste disposal and weather. This was the last consumer of my custom written sensor backend that I migrated to Homeassistant in the last months.

A website that can be displayed on an old Kindle4 is not able to use a lot of Javascript. I tried the basic solution described by nirkons on Github, but it was really annoying to debug for the stuff I want to display. So I decided to choose a different solution: Render a HTML file using a Template in Homeassistant and updating it via cron.

First the Template. I used the developer-tools inside Homeassistant to fiddle around with everything I want. The resulting template is stored in kindle.jinja in config/custom_templates. Important here: changing a template file on disk needs a Homeassistant restart.

The file has lots of CSS on the top and quite a bit of HTML, but a minimal version of kindle.jinja looks like this:

{% macro kindle_html() %}
<html>
  <head>
    <title>Kindle Status Display</title>
  </head>
  <body>
    Current time and date: <p id="time"></p>, <p id="date"></p><br>
    next Recycling collection: {{ as_timestamp(states('sensor.yellow_bag')) | timestamp_custom('%d.%m.%Y') }}
    <pre>
    temperatures tomorrow:
    min: {{ states.weather.forecast_home.attributes.forecast[1].templow }}&#176;C
    max: {{ states.weather.forecast_home.attributes.forecast[1].temperature }}&#176;C
    </pre>
  </body>
  <script src="kindle.js"></script>
</html>
{% endmacro %}

The kindle.js is important to update the current time and date on the kindle and to trigger a regular reload. The code for this is as old school as possible:

function updateDate(){
  d = new Date();
  document.getElementById("date").innerHTML = d.getDate().toString() + "." + parseInt(d.getMonth()+1).toString() + "." + d.getFullYear();
  document.getElementById("time").innerHTML = d.getHours().toString() + ":" + d.getMinutes().toString();
}

updateDate();

setInterval(function(){
  updateDate();
}, 1000*60);

setInterval(function () {
  location.reload();
}, 1000*60*60);

The version I actually use adds extra '0' if needed and is a bit more messy. We store kindle.js and the rendered html template output later in config/www/ which can be accessed without any authentication via http://your-homeassistant-ip:8123/local/kindle.html. For more information about hosting html files with Homeassistant, see https://www.home-assistant.io/integrations/http/#hosting-files.

To render the macro we stored we need a long lived token which can be generated in the profile of Homeassistant. This curl command renders a template and stores it to kindle.html:

curl -s -H "Authorization: Bearer YOUR_LONG_LIVED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template": "{% from \"kindle.jinja\" import kindle_html %}{{ kindle_html() }}"}' \
  http://localhost:8123/api/template > ~/.homeassistant/www/kindle.html

The template command {% from "kindle.jinja" import kindle_html %}{{ kindle_html() }} imports the macro and calls it. This can of course be tested in the developer-tools like we did before. I put the curl command inside a script file and call this script via cron every 10 minutes. For later debugging on the bottom of the rendered html is a {{ now }} to see when the file was last rendered.

My kindle display now looks like this:

img1

The html/css can be optimized a bit more and some sensor averages may be nice, but this is enough for today.