Managing ESPHome devices at home with GHA
Rational
If you are anything like me(!smart) you probably have a lot of smart devices. Smart Energy Meters, Temperature Sensors, Presence Sensors, Smart Lights etc. For me the ideal smart device should be managed localy, should not require any account and should be easily integrated to Home Assistant. ESPHome devices are all that and much more…
Let’s start
ESPHome
ESPHome is a system to control your esp32 microcontrollers by simple yet powerful configuration files. It was created by no other than the Home Assistant developers. The beauty of it is that you can configure the whole device with one yaml. More and more vendors are using esp32 boards for their smart devices. Many of those vendors also decide to use esphome. This is the best case for me since I can configure the device with yaml files, keep everything in a git repo and integrate the device to HASS seamlessly. This file is for my Athom Energy Meter device.
First I connect the device to my WiFi and note down the IP address. Then I have to download the file and modify it with the correct IP address/WiFi password etc and save it.
I then need to install the esphome cli, and run esphome run energy_meter.yaml
. This will compile and upload the binary to the device over the air.
Voila my device is ready with proper settings like wifi password/IP Address, Name etc.
Another way if OTA(Over The Air) is not possible is over USB. You connect the device to the PC and do the same procedure as above but select usb instead for the connection.
Why not CI?
The above way is simple enough but it has some minor downsides(at least for me):
- Installing esphome on my laptop, might require to create a venv, activate it and deactivate it eachtime.
- Some manual work each time I need to change something. Running the actual esphome cli.
- The more devices I have the more manual work it will require.
Now since I will already save my yaml files in a git repo, I decided to create an automation for it. I already had github action runners installed on my home network so I decided to create a Github Action for compiling and uploading like so:
name: upload new esphome binary
on: [pull_request, push]
jobs:
prepare:
runs-on: [self-hosted]
outputs:
output1: ${{ steps.out.outputs.files }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Get changed files
id: changed-yaml
uses: tj-actions/changed-files@v45
with:
files: '**/*.yaml'
- name: output
id: out
run: echo "files=${{ steps.changed-yaml.outputs.all_changed_files }}" >> "$GITHUB_OUTPUT"
compile:
runs-on: [self-hosted]
needs: prepare
container:
image: esphome/esphome
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: compile and upload
env:
OUTPUT1: ${{needs.prepare.outputs.output1}}
run: | #echo "$OUTPUT1"
for file in $OUTPUT1; do
echo "compiling $file"
esphome compile $file
echo "uploading $file"
esphome upload $file
done
The first step will calculate all the yaml files that changed since my last commit and the second will go over each one of them and run the easphome cimplile/upload procedure. This approach has some advantages for me:
- Makes for a good Blog post.
- Puts my k8s cluster at work so I dont feel bad for buying it and maintaining it.
- Gives me another opportunity to automate things I dont need to do or remember to how to do.
- Makes me write code instead of documentation.
So that was it! CI can be usefull even at home. Its not as simple as just running the esphome cli, but if you already have some infrastructure then its simpler. Thank you for stopping by!