Smart Home Dashboard
This blog article is featured on the Kickstarter campaign by Soldered, the makers of the Inkplate, for their new product, the Inkplate 2. Awesome!
For quite some time now I’m interested in making my home smart. I’ve started with Homematic (not the IP devices though) but as this was too expensive and not flexible enough for me I didn’t follow through. At the same time I dreamt about a tablet-like display on the wall which displays some metrics – because I love metrics, statistics and graphs – the more information, the better. Although I’m thinking about something like this for years now, this year I finally realized my dream. The dashboard centers around 2 central components – the Inkplate as an e-ink display and Home Assistant as my software, which creates the dashboard to be shown on the Inkplate.

The Inkplate is simply showing a pre-rendered image from a Home Assistant lovelace view. I display a few different things: weather, calendar events, battery stats of my devices, the temperature and humidity in every room, a few metrics of servers and some information of my LAN / internet.
Because I’ve always struggled to find a comprehensive guide to create something like this, I’m doing one of my own, in which I will explain what my experiences are, where I faced issues and what I actually did to make it work. I will also show my entire code, may you choose to recreate this dashboard. As a disclaimer: I’m not using the official Raspberry Pi way to install Home Assistant, but selfhost the Docker container using Kubernetes – many concepts in this guide can be transferred though.
This guide is structured in a few subpages to keep things organized. If you’re just interested in reading about how to display something on the Inkplate, connect a battery and how to get going, read #2 to #4. On pages #5 and #6 I will give an overview on my Home Assistant installation, how my dashboard itself is structured and all the components I’m using. #7 will explain my setup using Kubernetes, which may or may not be helpful if you’re running your services in a different way. If you’re just interested in which components are in my dashboard read #6. However I recommend reading everything in chronological order to get the best understanding of how everything works together.
- Introduction
- Hardware (Inkplate & Intel NUC)
- Concepts and Architecture
- Inkplate Software
- Home Assistant – General Setup
- Home Assistant – Dashboard
- Backend / K3s
If you have some questions, feel free to drop a comment on any of those subpages, use the contact form, or message me directly on Github or Reddit (@it-obey).
Hardware and Devices
Inkplate 10
The Inkplate 10 is a 10″ e-ink display which was crowdfunded by e-radionica on crowdsupply, featuring an ESP32 microcontroller. There were 2 options available for backers, I chose the one coming with the included 3d-printed case. The case itself is quite good, there are buttons for power, an opening for the sd-card and it features holes on the backside to mount it on the wall. However the material seems rather cheap and the case was already a little scratched. Moreover the capacitive buttons to interact with the inkplate on the center bottom are blocked which is unfortunate, but not necessary for my use case.

Battery
The backside features a few screws so it’s easy to open up. I did not tinker a lot with it, but I installed a battery to make it portable – but you’re always free to power it by the USB-C port on the righthand side. The battery connector is JST-PH port. I had no prior experience with anything battery powered on the microcontroller side. I decided to get a battery to fit in the case. I stumbled across a post on the e-radionica forums, which explained the maximum a battery would fit. The only one available in a fitting size with a acceptable power delivery was a 1200 mAh one. I also got a 2500 mAh one just to see if it would fit – but well, it did not, by a few milimeters. The battery can be just inserted into the JST port and because this battery fits snugly it does not move when closed up. The Inkplate also features a charger which will charge the attached battery once a USB-C power source is connected. Neat. As of now I did not need to recharge it. The following screenshot displays the battery for the last few weeks.

My rough guess would be that it lasts 4 weeks, but this also heavily depends on the use case. As explained in a part further down the road I refresh it every 20 minutes to display an image over WLAN and then put it back to sleep.

Intel NUC

The dashboard displayed is just a lovelace view of Home Assistant in kiosk mode (fullscreen). Home Assistant is hosted as in the Docker container core version on my Intel NUC NUC7PJYH2, a fairly cheap NUC with an quad core Intel Pentium Silver J5005 (there’s also a dual core model) with 16 GB RAM and a 512 GB SSD. Although the NUC is not very fast, it handles it’s tasks quite well. Besides Home Assistant there are two dozen other services running, many not necessary for the Inkplate dashboard, but for other home automations. You obviously can use a Raspberry Pi for Home Assistant, but for me a Raspberry Pi probably cannot handle all the load I throw at it with additional services and image rendering.
IoT and Sensors
The Inkplate and the NUC are the two devices used to display the dashboard. Although using this workflow any image can be displayed on the Inkplate. Creating my own dashboard I was in need for some more hardware (IoT devices). There are Kasa HS110 power plugs, a Zigbee USB adapter and a few Zigbee IoT devices.
Kasa HS110
I already owned 2 of these smart power plugs which can display the power usage. The plugs are connected by WLAN and thus are not in need for a central command station as the Hue Bridge or anything like that. When I started out this seemed to be the most cost efficient way to monitor power draw. There are newer devices from the TP-Link Kasa brand, which may or may not work with my approach to get the readings outside of the official Kasa mobile app. I may switch to some Zigbee power plugs in the future.
Zigbee USB adapter
The Zigbee protocol is quite famous in everything smart home related. Many manufacturers leverage the power of Zigbee for their own ecosystem (e.g. the Hue system from Philips). As there are many devices and brands out there, it’s easy to build a system yourself. All you need is some kind of Zigbee adapter to communicate with the devices. On the software side I’m using Zigbee2Mqtt which features a great list of supported adapters. I’m using the Electrolama zig-a-zig-ah! (zzh!) which can be found on top of the recommended devices. This way you can also communicate with the Philips Hue devices.
I’ve also got a better antenna to boost the signal. The one I got from ebay is a 6dBi antenna designed for 2,4Ghz. It depends on which adapter you get, but with the zzh! I needed a male connector on the antenna – a female connector will not work with the zzh! adapter (most antennas are female as far as I know, so chances are, if you do not check it, you will buy a female one). So make sure the antenna you’re buying has a little pin coming out of the connector, if your adapter requires it.
This allowed me to boost my signal to about 20 additional lqi compared to the antenna it came with. That beeing said, the range of the adapter is quite bad. Zigbee is prone to interference from 2,4Ghz WLANs and other signals, but I never imagined it to be that bad. I can hardly cover every room in my apartment, although the adapter sits in the center with this boosted antenna. It’s quite a step up from some $5 Sonoff Zigbee USB adapters sold on Aliexpress. They work – but they are not working stable and their range is worse. On the plus side: the zzh! with Zigbee2Mqtt is really stable for me. My only issue is range.
Zigbee devices
I’m using a few different devices with Zigbee. Prior to me installing the dashboard I’ve purchased Philips Hue, which are working great, but are not part of the dashboard itself. For the dashboard I got SONOFF SNZB-02 which measure temperature and humidity. I’m also using a few other devices which are not part of the dashboard, but which I can recommend: the Aqara motion sensors (RTCGQ11LM) for detecting motion and triggering the Hue lights and a Honeywell smoke sensor. All those Zigbee devices are way cheaper on Aliexpress compared to e.g. Amazon.
Internet
To display the internet traffic and LAN devices I’m making use of a Fritzbox, which was quite a hassle to get the data from. I would really love to have a Router with SNMP, as there are much more usable data and easier usage of said data, but unfortunately I’m stuck with the Fritzbox.
So this is all the hardware I’m using for the dashboard. In the next part I will describe the architecture of my setup and how I designed my approach.
Concepts and Architecture
As already described in the earlier part of this guide I’m using an Intel NUC for most of the hosting of my services. The setup of the services itself will be explained in part 4 and part 5. In this part I will describe the concept and the architecture of my approach to connect the Inkplate to the Home Assistant view from the NUC.
The overview of the componentens and services used to achieve this dashboard is visualized here. I will describe the communication in more detail in the following parts.

Home Assistant or website?
When I first started out with the idea to do something like this, I thought about designing a website myself which is then displayed on the Inkplate. This was even before I got into Home Assistant. Somewhere on Reddit (I guess on the Home Assistant subreddit) I saw a post by someone who designed a weather station on an e-ink display by rendering a Home Assistant view. Seeing this I began looking into Home Assistant myself. It didn’t take long for me to recognize that this will be my tool of choice to get the content of the dashboard for display. The dashboard on the Inkplate is just a website which is screenshotted and entirely interactable in Home Assistant. It just gets rendered in a fullscreen mode. I will explain this in more detail in part 4 and 5.
Inkplate Image Converter
So Home Assistant displays a nice, colorful dashboard. This is to be shown on the Inkplate. There are a few approaches to display something on the Inkplate – you can always render lines, pixels and text for yourself, which is very tedious. Another way is to display an image. There is an image converter tool which takes an image and transforms it to some kind of byte array which can be fed to the Inkplate for display. There’s also a selfhosted version on e-radionicas Github. However I soon noticed that the byte array output is far greater in size than the input image. That’s probably because the image is compressed (jpg / png compression) and about 100kb in size. The output byte array string which has to be transmitted to the Inkplate is over 2MB in size. I suppose because it contains information for every pixel for itself and does not feature any compression. Of course you may be able to compress the data yourself, but as it’s quite easy to just display images on the Inkplate, I figured this to be the way I approach it.
Image renderer
The next question in this line of thinking would be: how do I retrieve an image of the Home Assistant dashboard then? My first idea was to use puppeteer to render an screenshot of the Home Assistant website. This tool spawns a headless browser which can be interacted with and which can save screenshots of the content it displays, so it can run on the NUC. When playing around with puppeteer it just didn’t want to work for me the way I intended. Although I configured puppeteer to handle the authentication with Home Assistant, it just didn’t want to show me my lovelace view. After some research I stumbled across a fantastic tool hass-lovelace-kindle-screensaver by sibbl. This is designed to work with jailbroken Kindle devices to display a lovelace view from Home Assistant on them, but I figured it may work just fine with the Inkplate. It does. However there was some configuration necessary which I will go in to more detail about in part 7 of this guide. Moreover I needed to fork this and make some changes, which I explain in part 3. I configured it to take a screenshot every 20 minutes which works well with the deep sleep cycle I’m using on the Inkplate.
Deep Sleep and cycles
The reason why I was looking into e-ink displays is their ability to be very power efficient. Only changes on the display consume power, if the device is turned off it will keep the image because those little ink pixel thingies stay filled / depleted. This is quite an important aspect for me, as I wanted a dashboard which is not tethered to some kind of power cable and just sits on the wall by itself. Why? For aesthetics of course! So a battery is needed (described in part 1 of this guide). But I also need to limit the activity of the processor. The ESP32 inside the Inkplate features a deep sleep state which allows the device to consume very little power. In this state it can easily wake up by a predefined timer. My approach in this regard is to connect to WLAN, pull the image from the NUC, display the image, send a MQTT message (see next paragraph), disconnect from WLAN and go to sleep. After 20 minutes this cycle repeats. By using this approach the Inkplate only consumes (noticeable) power every 20 minutes for a few seconds. This allows the battery to last for (I guess) a few weeks – or even months. When increasing the gap between the wake up cycles it can last even longer. But 3 times an hour seemed to be a good middle ground for me.
Battery status and MQTT
You’ve probably seen the device percentages on my dashboard. These represent the current battery status of my mobile devices, so I have an overview what I will have to charge. How I get the data for the devices is described in part 6 of this guide, but I will explain the Inkplate here, as it’s important for the design.
There’s no possibility to display a percentage on the battery, just the voltage can be retrieved. I thought about calculating the percentage but with no experience in this regard this just seems to inaccurate to me. So I decided to display the voltage on the dashboard. As I already have a MQTT broker running (mosquitto, explained in parts 4 and 5) and a working integration to display data, I just send a MQTT message to my broker before going back to sleep. With this approach the currently displayed dashboard is 20 minutes behind regarding the voltage of the Inkplate, but this value changes so slowly that I easily can put up with this. Every other approach would be consuming more power.
tl;dr
So in summary: the hass-lovelace-kindle-screensaver tool will save a screenshot every 20 minutes to a specific folder and an Nginx server publishes this folder (why is explained in part 4). The Inkplate wakes up every 20 minutes to retrieve the image from Nginx and displays this image. It then sends an MQTT message back to the NUC with the current battery voltage and goes back to sleep.
I will go into more detail on the Inkplate side and show my code in the next part of this guide.
Inkplate Software
As described in part 3 of this guide, my approach is to display the image itself and not the byte array using the Inkplate Image Converter. I wrote about sibbl’s hass-lovelace-kindle-screensaver and that I use it to render an image of the Home Assistant lovelace view. However rendered images didn’t show up for me on the Inkplate, I had to do a little trial and error to get it working, as hass-lovelace-kindle-screensaver saves images as PNG.
PNGs or JPGs?
Although I have read somewhere that the Inkplate is able to display PNG images, it just didn’t work for me. Naturally I turned to JPG images. There are some code examples which show how to display JPG images on the Inkplate. Because these images did show up for me, I switched to JPG. sibbl’s hass-lovelace-kindle-screensaver uses ImageMagick to render the images and I changed the filetype to save JPGs instead of PNGs. I’m running the tool in a container, so I figured it would be the easiest to just fork the repository and make my changes there. You may just use the container image from my build instead of forking it yourself. More information on this in part 5 of this guide. My fork can be found here: https://github.com/itobey/hass-lovelace-screenshotter Update: Sibbl updated his version and included the changes I made, so I do not maintain my fork but switched to sibbls repository, and I encourage you to do the same.
After my change to save JPGs I noticed the images still not beeing displayed on the Inkplate. My manual test images, which I converted from PNG to JPG using Photoshop got displayed with no issue. Turns out the Inkplate cannot display the grayscale images (ironically) and a change to TrueColor images solved the issue. I’ve written an entire blog post on this issue which can be found here. The necessary change is also included in my fork of sibbl’s repository. Update: And again also in sibbls repository, which you should use.
Please note that images straight from the tool cannot be displayed using the URL on the Inkplate, as the Inkplate needs a full qualified path, and not just localhost:5000. For this reason I needed to configure an Nginx server to display the image saved by the tool, so I get a full qualified URL, e.g. localhost:8080/output.jpg.
Programming the Inkplate
In a recent project I’ve used platform.io to develop on an ESP32. Unfortunately platform.io has an issue with the Inkplate library and I couldn’t get it to work. So I just went back to the Arduino IDE and followed the necessary steps to get it to work with the Inkplate.
My code can be found here. I’m not proficient in C, so excuse any misdeeds. We won’t be needing a loop-block because awakening from deep sleep will restart the setup-block. In the previously linked code examples there are also examples for deep sleep. If you’re interested in just using my approach, important lines are line 14 (how many seconds between deep sleep cycles) and lines 16-18 (SSID and MQTT configuration). The actual image is retrieved in line 45. Another important line is line 90, where the string for the MQTT message is concatenated. The format may seem strange, but I’m using Telegraf to scrape the MQTT message and put it into InfluxDB, from which I can retrieve it in Home Assistant. I also have my data to query over time to see how the battery behaves. I’ve written a blog post on how to achieve this here. If you’re not interested in having it in InfluxDB and just want to read it over MQTT, feel free to edit this line. I’m also getting the battery temperature in the lines prior to this, which is not displayed on the dashboard itself, but on another lovelace view in Home Assistant, that’s why it’s included in the MQTT message.
I am running the Inkplate in 3 bit mode, which allows me to display some grayscale values. You can also switch it to 1 bit so it’s just black and white. I’m a little disappointed in 3 bit, because I thought it covers more nuances of gray, but after some optimization on the colors in Home Assistant it’s alright. Fine lines and text is not very legible – I expected it to be better, but I suppose it’s alright, too. Just make sure your text is bold and no elements are too thin.
Home Assistant – General Setup
This part of my guide explains my general setup of Home Assistant and plugins used to create a useable lovelace view for rendering. Every component of the dashboard / lovelace view itself is explained in part 5 of this guide. The installation of Home Assistant and the services used is explained in part 6.
Grid setup
The Inkplate features a 1200×825 pixel resolution. For this reason I configured the screenshot tool mentioned in earlier parts of this guide to also create a screenshot in this resolution. For readability and aesthetics I found 3 vertical stacks in Home Assistant to be the best setup. This way I can control what element is displayed at which location and it’s quite easy to use. Inside the vertical stacks I sometimes have a horizontal stack to add elements next to each other, for example the temperate and humidity graphs in the middle stack. The entire vertical stack in the middle is composed of horizontal stacks which feature 2 or 3 elements.
Theme
When using an e-ink display the background should be quite bright (white would be best) so you get enough contrast when displaying content. I suppose you could use an inverted setup, but I do like the paperlike look with black text on white background more. For this reason I’ve searched for a nice light theme. The github_light_theme from einschmidt looked promising. However it’s background is colored and I wanted to have it solid white. So I cloned the theme and adjusted the background color. You can find the YAML file here. Just download the file, and save it to the themes folder in your Home Assistant configuration into a new subfolder. You may need to restart Home Assistant to get to choose the theme. When creating a new lovelace view you can choose this theme and have only this view in a light theme and do not influence your nice, handcrafted dark theme everywhere else.
HACS & Kiosk mode
To render the dashboard image without menu elements from Home Assistant it’s necessary to get a fullscreen mode. Kiosk mode allows you to append ?kiosk to your URL to show the lovelace view in fullscreen without the menu on the side and the bar on the top. The plugin can be found here. You may want to install HACS to manage your plugins so you don’t have to deal with every plugin for itself. Many other plugins explained in the next part of this guide are also installed over HACS.
InfluxDB
I’m using InfluxDB to persist all events from Home Assistant which can then be displayed in a Grafana dashboard. Some components explained in the next part of this guide rely on data from InfluxDB. To use the InfluxDB platform for sensors and get data from InfluxDB, you need to include this part in your configuration.yaml to make use of the integration. If you’re just interested in getting data but not persisting events from Home Assistant (so: not bidirectional) uncomment the 2 lines at the bottom. This will stop Home Assistant from reporting data to InfluxDB.
influxdb:
host: influxdb.influxdb
verify_ssl: false
port: 8086
# exclude:
# entity_globs: "*"
Zigbee2Mqtt
Zigbee2Mqtt is used to communicate with Zigbee IoT devices, like a temperature sensor. In Home Assistant you need to install and configure the MQTT integration to receive events by MQTT. A MQTT broker is necessary for this to work. I’m using a selfhosted Mosquitto instance, but you may want to use the Mosquitto addon. In part 1 I described the hardware necessary for Zigbee. For instructions how to configure Zigbee2Mqtt see the official documentation.
Card mod
Because space on the Inkplate is quite limited and some elements need to be styled a bit differently (larger font-size, bold text, less padding of elements) you need to fiddle around with CSS. Home Assistant uses a shadow dom, so it’s not possible to style elements just by throwing in some CSS. A very comfortable way is the lovelace-card-mod by thomasloven. You just install this plugin and are able to style elements by appending a specific property in lovelace. However it only styles elements within the ha-card element, so you cannot style everything unfortunately. I show my usage as an example on the Weather widget in part 6 as well as link to my entire lovelace configuration.
Home Assistant – Dashboard
Part 5 in this guide explained the general setup of Home Assistant and plugins used. This part explains the entire dashboard itself and all the components in it.
The following image shows my dashboard and features a heading number for every component used, which is explained in more detail further down below. My entire lovelace config is uploaded here, so you may clone it.

- Weather
- Battery status
- Changed indicator
- Waste collection
- Calendar events
- Temperature and humidity
- Server stats
- Power consumption
- Internet traffic and WLAN usage
- DDNS uptime
- Calorie tracker
- last updated
1. Weather
This just uses the default weather integration which is probably installed by default. The integration is called Meteorologisk institutt (Met.no). I did no further configuration except some CSS adjustments using the card mod explained in part 4.
- type: weather-forecast
entity: weather.home
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
font-weight: 700 !important;
}
.state {
font-size: 1.5em !important;
}
ha-card > div > div > div > div.attribute {
color: #555 !important;
}
ha-card > div > div > div.templow {
color: #555 !important;
}
2. Battery status
This is just a glance-type card with 4 entities. I’m getting the data from the smartphone and the tablet by using the official Home Assistant app. How to get the voltage of the Inkplate battery is described in part 3. For my laptop I thought a bit about my approach and then just settled on a small python script to get the reading and send it over MQTT to my broker which is then handled in the same way the Inkplate readings get handled. The python script can be found here. I’m using the windows task management (like a cronjob) to execute this script every 5 minutes. The data is then queried by an InfluxDB sensor, which is added into the configuration.yaml. I’ve written a blog post about this here. I’m using 7 days in my where clause to get the last known value in this time. If you just use a day and your device hasn’t been online for 2 days, it will show unknown. There’s probably some option to retain the last known value but I did not find a way in Home Assistant in a short search. If you know an easy way, please comment.
sensor:
- platform: influxdb
queries:
- name: Zenbook-Battery
field: battery
where: 'time > now() - 7d'
group_function: last
database: sensors
measurement: '"sensors"."autogen"."zenbook"'
...
3. Changed indicator
Because I always forget for how long my sheets and towels are in use I designed a small workflow to help me. I stuck a NFC tag beside my towels and sheets inside the closet and added these to Home Assistant. Then I’ve added two automations which are triggered by the scanning of these tags. They don’t do anything else though. In the configuration.yaml I’ve added 2 template sensors which query the last_triggered attribute of the automation and display the days. It’s not the most accurate thing and will only display 1 day ago, once it reached 24h after scanning – but it’s good enough for my use case.
sensor:
- platform: template
sensors:
last_triggered_nfc_bettwaesche:
friendly_name: "Last Trigger NFC Bettwaesche"
entity_id: sensor.time
value_template: "{{(as_timestamp(now()) - as_timestamp(strptime(state_attr('automation.nfc_tag_bettwaesche', 'last_triggered'), '%Y-%m-%d'))) | timestamp_custom('%d', false) | int - 1}} days ago"
...
4. Waste collection
This is a plugin I installed in HACS, the hacs_waste_collection_schedule by mampfes. If the plugin features your city you have almost no further work to do. If not, then there are ways documented to still get your schedule to show up. The images I have got from some Home Assistant forum thread, which I cannot find anymore, I hope it’s okay that I upload them into my repository here, as they were public on the forum as well. If the person who posted them is reading this: just message me the forum post and I will include you as the source in here.
The data is then made available as a sensor.
sensor:
- platform: waste_collection_schedule
name: Flach
count: 4
value_template: 'in {{value.daysTo}} days'
types:
- Flach
...
5. Calendar events
To display the events I’m using the atomic-calendar-revive plugin from HACS. Currently I’m experiencing some issues with it, but it looks quite nice. I hope the dev gets my issue fixed. My configuration of the atomic-calendar-revive plugin can be seen in the linked issue. You may connect your Google calendar with this plugin. I’ve switched from Google to a selfhosted Baïkal calendar. You need to use the official calendar integration to connect your calendar, so atomic-calendar-revive can use it, using the configuration.yaml like this:
calendar:
- platform: caldav
username: myuser
password: mypass
url: https://baikal.nuc.local/dav.php/calendars/myuser/default/
verify_ssl: false
6. Temperature and humidity
For these graphs I’m using the mini-graph-card installed from HACS. The data is queried by Zigbee2Mqtt from the SONOFF sensors mentioned in part 2, Zigbee2Mqtt is explained in part 5 and part 7. My setup for one of these cards looks like this:
type: custom:mini-graph-card
name: Wohnzimmer
line_color: '#b37169'
font_size: 80
decimals: 1
align_state: center
line_width: 8
show:
legend: false
icon: false
entities:
- entity: sensor.sonoff_temp_wohnzimmer_temperature
name: Temperatur
index: 0
y_axis: secondary
- entity: sensor.sonoff_temp_wohnzimmer_humidity
name: Humidity
show_state: true
index: 1
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
}
ha-card > div > div > span {
font-weight: 700 !important;
}
ha-card > div {
font-weight: 700 !important;
}
ha-card > div > div.name > span.ellipsis {
color: #000 !important;
}
...
7. Server stats
For these graphs I’m using the mini-graph-cards from the previous paragraph as well, but I adjusted the look a little to make them better readable. There is unfortunately no way to adjust the height without losing the graph – this way I would be able to preserve some space and maybe squeeze another component in there.
I thought about an integration of this data for quite a while. The NUC is the one Home Assistant runs on (so on premise). The Server and the Odroid are on different locations and I do not want to open ports on them or the NUC, to send data to any of those devices. Because I have a Datadog agent running on every one of those machines (free up to 5 machines btw.) I used Datadog as a intermediary, because Datadog already gets the necessary data. There is no easy way to retrieve the data in the way I want over the API, so I created a little tool to do this and published a blog post about it. The tool is executed every 10 minutes to gather the data for the 3 servers from the API and calculate an average (the last value would be too inaccurate) over those 10 minutes. The data is then sent to InfluxDB. An InfluxDB sensor retrieves the data for display in Home Assistant.
sensor:
- platform: influxdb
queries:
- name: NUC-CPU
field: cpu_used_percentage
where: "time > now() - 1d and \"host\"='NUC'"
group_function: last
database: datadog_metrics
measurement: '"datadog_metrics"."one_day_only"."metrics"'
...
8. Power consumption
As described in part 1 of this guide I’m using Kasa HS110 power plugs (only 2 of them at the moment). They have been reverse engineered and can be communicated with over TCP. I am using the tplink-plug-exporter from fffonion to get the data from the plugs. I have an instance of Prometheus running which scrapes the data from the tplink-plug-exporter. A Grafana dashboard then displays the data from Prometheus. The dashboard I used can be found here. However I made a new Grafana dashboard with only the panel I want and styled it in a way that it works for the embedding. In Home Assistant this is just an iframe card with a little styling as well. In Grafana just click the dropdown on the panel you want and hit share, then copy the link. You may want to append &theme=light to the URL to change the theme. The time frame can be adjusted with a few arguments as well, see my example below.
cards:
- type: iframe
url: >-
https://grafana.nuc.local/d-solo/B6fqNcYGk/power-usage-eink?orgId=1&panelId=24&from=now-12h&to=now&theme=light
aspect_ratio: 50%
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
}
My first idea was to use the external Grafana renderer which just renders a panel as an image which can then be displayed in Home Assistant. However these images looked a bit blurry and the scaling was a little off, so I changed my approach to an iframe. If you’re interested in using the external renderer in a Docker environment, make sure to read my blog post about that.
9. Internet traffic and WLAN usage
The internet traffic and WLAN usage is composed of 4 more iframes which display panels from Grafana, exactly as mentioned in the previous paragraph. Because I’m stuck with a Fritzbox without SNMP (as described in part 2) I had to look for alternatives to get some data. Someone by the name Schmidsfeld created TelegrafFritzBox which uses Telegraf to query data from the Fritzbox. Unfortunately this only worked well for DSL internet contracts and since I’m using a cable one, I relied on a fork by Lexiv. I then made my own fork for a dockerized cable setup.
I also included my Grafana dashboard in that repository, which I got from a fork and customized it a bit to adjust it to my connection. Telegraf is scraping the data from the Fritzbox router and pushing the data to InfluxDB. Grafana then uses the InfluxDB to display the data. I simply created a new Grafana dashboard with the 4 panels I needed, customized them a bit and used an iframe in Home Assistant for display. To calculate the traffic I needed to play around with subqueries, which I posted a blog article on. Unfortunately it seems that the data is not very accurate from the Fritzbox and cannot be used to monitor a metered connection efficiently – but for a general overview it’s neat.
10. DDNS uptime
For monitoring my DDNS services I’m using the uptime-card by dylandoamaral, installed over HACS. The configuration is fairly simple, just put this in your configuration.yaml and edit the host to match the one you’re monitoring for uptime.
binary_sensor:
- platform: ping
name: ddns1
host: example1.com
count: 10
- platform: ping
name: ddns2
host: example2.com
count: 10
In Home Assistant my configuration for this card looks like this. This is a bit work in progress, as I’m not sure if I will keep the colors this way, as I’m thinking about how I can distinguish it better in grayscale and what colors can be displayed by the Inkplate.
- type: custom:uptime-card
entity: binary_sensor.ddns1
name: DDNS 1
hours_to_show: 24
title_adaptive_color: true
average_template: '[[[ return variables.uptime.toFixed(2); ]]]% uptime'
bar:
height: 20
round: 5
spacing: 10
amount: 10
color:
none: '#eee'
ko: '#eee'
ok: '#333'
half: '#aaa'
show:
status: false
icon: false
alignment:
status: spaced
header: center
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
border: none;
background: #fff;
font-weight: 700;
}
ha-card > .footer > div {
color: #333 !important;
}
11. Calorie tracker
This is a based on a little tool I developed in march. A python script retrieves my user data from fddb.info, makes some calculations and persists the daily calories consumed to a Postgres database. This database is then used in Grafana as a datasource to display the data. I plan on adding the retrieval of macronutrients in the future, as this would be a metric I’m more interested in. In Home Assistant it’s just another iframe, like the ones already discussed.
12. last updated
This is my own plugin I created for this use case. It amazed me, that this didn’t exist (or at least I couldn’t find it) because I have seen some dashboards which feature something like that. You can get it from my Github, or install it over HACS. Just search for Update Time Card in the Frontend category. The basis of this plugin is the simple-clock-card plugin by fufar, which I customized to get a non-obtrusive time display.
- type: custom:update-time-card
hide_seconds: true
font_size: 1rem
card_mod:
style: |
ha-card {
font-weight: 700;
}
Well, this is it, my configuration and all the components on my dashboard. If you’re interested in having a deeper dive have a look at the entire lovelace yaml which I uploaded here.
The next and last part of this guide will show my NUC setup featuring services used in this dashboard, like the CalDAV Baikal, Zigbee2Mqtt and of course my hass screenshotter fork to render the dashboard as an image.
Backend / K3s
This part describes my setup and selfhosting Home Assistant and other services by using a containerized approach in Kubernetes. I also describe my setup of hass-lovelace-screenshotter.
Container, Kubernetes, Gitops
Docker and Plugins
Most of my services are hosted on the NUC, I’ve been talking about in previous parts. Recently I switched from a Docker based setup (using docker-compose) to a Kubernetes based setup using K3s. Of course you can always host the official Raspberry Pi Home Assistant software or use any other way to host. On a Docker based setup you will host just the core component whereas on the recommended Raspberry Pi setup some scripts manage all this for you and those scripts will also pull and run Docker images when you decide to use a (official) plugin. HACS still can be installed on your selfhosted container setup, but the official plugin store is not available. So you need to decide in the beginning which way you’re going for: ease of use with less control or selfhosted with a lot more to do. Because I am really into selfhosting the choice was quite easy for me.
Kubernetes and GitOps
Kubernetes heavily relies on declaration of resources which it manages. So in a way you are saying what you want and Kubernetes realizes it for you. Those declarative resources are often created by users in YAML. Some time ago a concept called GitOps emerged, which in a nutshell stores those resource files in a git repository and some software compares the current state of resources in the Kubernetes cluster to the resources in the git repository. If it detects changes it notifies (or applies) automatically to maintain a Kubernetes cluster in the state which is defined in the Git repository.
I am using ArgoCD as my GitOps tool to handle the state of my cluster. For this reason I am able to open source the repository I’m already using to setup my NUC to the public, so you can get an extensive look at my entire setup. The repository can be found here. Please note that I’m using helm-sops in ArgoCD to handle secrets and passwords. I may create a blog post on this topic in the near future.
Hass-Lovelace-Screenshotter
I’ve already described the tool shortly in this guide. This tool just saves a Home Assistant lovelace view as an image. To render JPG images instead of PNG images and keep them TrueColor instead of grayscale (because they won’t work with the Inkplate, see part 2) I created a fork containing the necessary changes. If you’re running container images you can pull my image:
ghcr.io/itobey/hass-lovelace-kindle-screensaver/hass-lovelace-kindle-screensaver:main
The original creator of this tool offered configuration by setting environment variables. Depending on the way you’re hosting the tool this approach is different. As described in the previous paragraph I’m using Kubernetes, so my deployment manifest contains a part with all the environment variables. The entire manifest is available in my repository here. In any case of defining the environment variables, some are important to set.
...
env:
- name: TZ
value: Europe/Berlin
- name: HA_BASE_URL
value: http://home-assistant.home-assistant:8123
- name: HA_SCREENSHOT_URL
value: /lovelace-dashboard/eink?kiosk
- name: HA_ACCESS_TOKEN
value: "{{ .Values.HA_ACCESS_TOKEN}}"
- name: RENDERING_SCREEN_HEIGHT
value: "825"
- name: RENDERING_SCREEN_WIDTH
value: "1200"
- name: RENDERING_DELAY
value: "5000"
- name: LANGUAGE
value: de
- name: CRON_JOB
value: "*/20 * * * *"
- name: OUTPUT_PATH
value: /output/output.jpg
# for Grafana iframes
- name: UNSAFE_IGNORE_CERTIFICATE_ERRORS
value: "true"
...
HA_SCREENSHOT_URL has the appended ?kiosk to get a fullscreen view. If you do not append this, you will get your navigation menu items on the screenshot. To have this working, install Kiosk mode, see part 5 in this guide.
HA_ACESS_TOKEN needs to be created in Home Assistant. Open your profile (bottom left of the menu) and scroll down to the end. You want to create the token here. Take a note, you cannot display it again and need to create a new one, should you forget it.
RENDERING_SCREEN_HEIGHT and RENDERING_SCREEN_WIDTH are set to the resolution of the Inkplate 10.
RENDERING_DELAY is included to wait for 5 seconds before saving a screenshot. This is necessary, because the iframes take a few seconds to load up. Without this delay these components may be missing on the dashboard screenshot.
CRON_JOB defines to wait 20 minutes between taking screenshots. This can be adjusted by using a cron expression.
OUTPUT_PATH saves the image to a specific folder under a specific filename. This is important as this folder is mounted as well in the Nginx server which just publishes the output.jpg (see part 4 for details).
UNSAFE_IGNORE_CERTIFICATE_ERRORS lets you ignore certificate errors. This is important for me, because I equipped Home Assistant with a longliving selfsigned certificate to have it running over HTTPS and not get the “untrusted” message in my browser (see my blog post on how to do this). However the screenshot tool does not trust this certificate and I would have to install my certificate inside the container. This is just way more comfortable and not really an security issue, because everything is running on premise.
Closing remarks
Well, that’s all. You have reached the end of my guide. I hope it was helpful and interesting to you. If you have any questions regarding anything of this, just drop me a comment or message me directly on Github or Reddit (@it-obey).
Comments
Comments are hosted on comments.itobey.dev. Loading them sets cookies and shares your IP address with that service.