Avid readers of this blog may know that I have add a few temperature sensors to my heating setup (exactly 8 of them), in order to troubleshoot an issue we had as we moved into our new house. The description how I did that is described in this post.
I used DS18B20 sensors and a Raspberry Pi to monitor temperature changes which delivered measurements to my Homeassistant installation over MQTT using rpi-temperature-mqtt.
Over time, I added more and more functionality to this RPi: controlling the boiler via relays and also monitoring the serial bus of my Buderus boiler.
Adding all these functions incrementally was pretty simple, but as a professional software engineer, I was feeling increasingly uncomfortable with how I would reproduce the same installation should the RPi fail. As a software professional I believe in CI/CD systems, automated tests and deployment. Infrastructure as Code and all that.
I have to confess that this deployment was completely unlike show it should have been done: one off installation, functionality added over time, no backups.
And as with all SD cards over time, at one point it failed to boot. The kernel was oopsing in an endless loop. It was a wonder it worked for so long.
At this point I had some experience with ESPHome and had a few ESP8266/ESP32s lying around, so I've figured I can do all what the RPi used to do with an ESP.
For those software folks who have not yet jumped on the ESP bandwagon, here's a short introduction:
- RISC V based CPU/MCU from single core 26Mhz to dual core 240Mhz.
- up to 8MB of RAM (on ESP32)
- up to 32MB flash
- ~15 GPIO pins
- on-board WiFi and Bluetooth Low Energy (ESP32 only) with a PCB antenna
All this for the size of a coin. Complete boards, ready to use with an USB connector for something like $5-8 on AliExpress for a beefy ESP32 board, but you can get a simpler one for $2-3 on the same site. Be sure to order a few at a time, you will need it. :)
You can program these using their native SDK or Arduino, but there are also complete firmware packages, which you can configure instead of having to code the functionality you want to achieve. Such firmware package is Tasmota or ESPEasy but for my use-cases ESPHome seems to be the best solution.
The ESPHome project aims to be the IoT counterpart of Homeassistant, e.g. its integration is the best out there and the configuration model plus the syntax is very similar to how you do things in Homeassistant.
With all of this said, I set out to configure the 8 temperature sensors, the 4 relays and the boiler monitoring functionality using a D1 mini board.
Installing esphome
ESPHome is written in Python, so it's a pip install away. I installed mine as a user within my home directory. But you can also set up a virtualenv or just use a docker image with all the necessary things installed for you.
$ pip install esphome
Creating the initial configuration
A configuration for ESPHome is a YAML file. You can create such a file from scratch, but it's always easier using the esphome wizard command, which will ask a few questions and give you a nice and simple .yml file to work on.
This initial config would give you a good starting point, once deployed to a board, it will try to connect to a WiFi network automatically (or automatically provide a WiFi Access Point as a fallback if it can't connect). Once connected the board can be updated remotely (over-the-air updates) and can also be autodetected by Homeassistant.At this point the board does not do much interesting stuff, apart from being accessible and upgradeable over-the-air.
Adding temperature sensors
The temperature sensors I was using are W1 (or onewire) devices, which was originally specified by Dallas, thus ESPHome refers to this bus as "dallas". To connect up these sensors, I need to dedicate one GPIO pin as the data pin for the bus. This can be achieved by adding this to the ESPHome configuration:
dallas:
- pin: 13
With that present I can create sensors that attach to this bus:
sensor:
- platform: dallas
name: "Lakás Primer Vissza"
address: 0x8601191F191D2028
resolution: 12
filters:
- delta: 0.1
You can use index or address based identification of sensors, I am using the address here to be sure I know which sensor is which. You can see that I've requested 12bit resolution (slower but more accurate) and that only changes over 0.1C are reported to Homeassistant. You can find more details in ESPHome's documentation.
Adding relays
Relays were simpler as I could dedicate a GPIO pin for each of the relays I wanted to control.
switch:
- platform: gpio
name: "MelegvÃz Keringetés"
pin:
number: 5
inverted: true
This tells ESPHome to expose a switch to Homeassistant, which when activated would flip GPIO #5, so that when the switch is on, the GPIO pin would be raised to HIGH and LOW otherwise (note the inverted attribute).
I've listed each of my relays in this manner.
Buderus bus monitoring
This was the most involved function, as the Raspberry Pi I used previously was running a Perl script to decode the bytes sniffed from the Buderus bus. I obviously could not deploy the Perl script on the D1 Mini. The solution here was a serial to TCP/IP bridge where the serial port communication is directly mirrored to a TCP connection. I then modified the Perl script to connect using TCP instead of opening a local serial port, then I've deployed it on my NAS running Linux.
For the serial bridge, I've used a 3rd party extension of ESPHome, like this:
uart:
stream_server:
You can see that I've referenced the 3rd party component using "external_components" and I've even forked the esphome-stream-server repository as I had a compilation issue back then, which I am pretty sure is fixed by now.
With that, the Perl script happily running on a more resourceful Linux server would connect to port 6638 on the D1 mini where it will get the sniffed Buderus communication.
Deploying it all
Homeassistant integration
Reproducibility
If this all would not be convincing enough, the YAML file that encapsulates the entire firmware configuration can be added to my home-automation git repository. Should the D1 mini ever fail, I can replace it, either the same kind or a newer one, without a hitch.
Comments
Interesting things I've been reading on your blog, being the owner of a Buderus boiler with a Logamatic 4211 control. I recently started my endeavor to find a communication solution with the boiler. I began with https://github.com/flyingflo/heat_can together with https://github.com/flyingflo/logamatic, but didn't manage to go anywhere. I'm stuck at the very beginning and I suppose I'm missing some of the basics of how this project was implemented. I was aware of Peter Holzleitner's solution, but I thought that communicating via the native bus would be a more elegant solution. Failing to make it work brought me back to Peter Holzleitner. I ordered a ready-made level shifter and while waiting for it to arrive I am struggling with the software. My programming skills are very rusty to say the least, having seldom been used during the past two decades. Not having a clue of Perl, I am currently trying to understand it and translate it to Python with the help of chatGPT. :)) I like the idea of using the ESP32 for exposing the serial over the wifi and will probably tried to replicate it. I use a few ESP32 devices with ESPhome for various home automation tasks, therefore I am optimistic about being able to replicate it. I am more concerned about the Perl software (and my Python translation), therefore I took a chance in contacting to you to ask if you would care to share anything about your specific implementation. I am mainly interested in the software, but also the wiring and other details you may consider to be relevant. Thank you in advance!