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.
Because of changes in Homeassistant 2024.4 there is no forecast
in the weather state anymore.
To get this back we need a new template in the configuration.yaml
:
template:
- trigger:
- platform: time_pattern
minutes: "*"
- platform: homeassistant
event: start
- platform: event
event_type: event_template_reloaded
action:
- service: weather.get_forecasts
target:
entity_id: weather.forecast_home
data:
type: daily
response_variable: daily_forecast
sensor:
- name: "Weather Daily Forecast"
unique_id: home_daily_forecast
state: "{{ states('weather.forecast_home') }}"
attributes:
forecast: "{{ daily_forecast['weather.forecast_home'].forecast[:3] }}"
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: {{ state_attr('sensor.weather_daily_forecast', 'forecast')[1].templow|round }}°C
max: {{ state_attr('sensor.weather_daily_forecast', 'forecast')[1].temperature|round }}°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:
The html/css can be optimized a bit more and some sensor averages may be nice, but this is enough for today.