Creating and maintaining firmware on the various IoT devices in your home automation setup can become a tedious and time consuming task. This post is about a tool I discovered which helps simplify this problem.
Flashing firmware itself does not take much time. However, as your system grows in size and complexity, that little overhead is multiplied by the number of devices on your network. If you need to spend time flashing firmware, debugging when things break and maintaining individual devices then the time spent doing low-level firmware maintenance is enormous. This time is better spent implementing useful automations for your home automation setup.
ESPHomeYAML is a Python tool that generates microcontroller firmware binaries for ESP microcontrollers based on YAML configuration. What this means is that you define, in a few lines of YAML, a desired configuration and the tool will parse this config, then generate, compile and upload wirelessly the firmware to your ESP.
Features (from project page):
- No programming experience required: just edit YAML configuration files like you’re used to with Home Assistant.
- Flexible: Use esphomelib’s powerful core to create custom sensors/outputs.
- Fast and efficient: Written in C++ and keeps memory consumption to a minimum.
- Small binaries: Only the sensors/devices you actually use will appear in the binary.
- Made for Home Assistant: Almost all Home Assistant features are supported out of the box. Including RGB lights and many more.
- Easy reproducible configuration: No need to go through a long setup process for every single node. Just copy a configuration file and run a single command.
- Smart Over The Air Updates: esphomeyaml has OTA updates deeply integrated into the system. It even automatically enters a recovery mode if a boot loop is detected.
- Powerful logging engine: View colorful logs and debug issues remotely.
- It’s Open Source
In addition to this: * it supports MQTT discovery, which allows Home Assistant to discover these devices on the fly * deep sleep mode (power saving) * web server (a web UI running on a microcontroller! That’s 99/10 awesome in my books.) * an extensive API allowing you to define common features such sensor inputs, relays, lights, switches, fans, covers and more miscellaneous components in YAML. The tool will generate and compile C++ code to be flashed to the device over the air (Wifi).
Consider this simple configuration:
output:
- platform: esp8266_pwm
id: basic_green_led
pin:
number: GPIO13
inverted: True
- platform: gpio
id: relay_light
pin: GPIO12
light:
- platform: monochromatic
name: "Basic Green LED"
output: basic_green_led
- platform: binary
name: "Living Room Table Lamp"
output: relay_light
It defines two output pins and two corresponding lights. These entities are discovered automatically by Home Assistant and can be controlled out of the box!
Make sure you enable MQTT Discovery by setting discovery: true
in your mqtt
configuration.
{: .notice–warning}
The tool supports a multitude of different light platforms, performing standard tasks such PWM controls, binary lights, LED strip controls and even controlling addressable LED strips via FastLED!
This is absolutely insane considering you can define this with a handful of lines of YAML. I remember trying to get BRUH Automations ESP MQTT JSON LED Controller to work. It was a nightmare both from the hardware and software perspective due to my inexperience.
Here’s a WS2801 LED strip configuration example from the documentation:
# Example configuration entry
light:
- platform: fastled_spi
chipset: WS2801
data_pin: GPIO23
clock_pin: GPIO22
num_leds: 60
rgb_order: BRG
name: "FastLED SPI Light"
The beauty of it is that you can now define your firmware as code. Which–as a devops enthusiast– really blows my mind. I’ve seen pipelines-as-code, even infrastructure-as-code, but firmware defined declaratively in a few key/value pairs (rather than thousands of lines of code written in C++) is mental.
It took only 20 minutes to get one of my ESP based lamp controllers converted to YAML, reflashed and hooked into home assistant! Most of my time was spent installing Python and configuring the path to the pip
command to work.
After uploading the firmware using the CLI, the light did not seem to work first try… I spent a few seconds flicking the switch in Home Assistant impatiently, playing with the brightness slider and checking the real time OTA debug logs that were streamed to the Python console. The logs indicated all commands were being received and processed without any issues.
I continued flicking the switch and, walking back towards the lamp on the table, I realised what happened. The default configuration, to my surprise, did not switch the relay on and off as expected. Instead, it controlled the little status LED on the chip, making it fully Home Assistant controllable including brightness slider, transition
times and beautifully smooth PWM fading. I was completely blown away by the fact that I had configured all this by accident.
Well… I copy and pasted the default configuration but I got this working with only 10 lines of YAML in under 20 minutes! Amending the configuration to control the relay was very simple of course.
Conclusion
This is a great tool and I look forward to converting all my lamps to YAML config and reflashing them OTA. This way, you could even write a script to update the tool and recompile all lamp firmwares before reflashing them once every 3 months or so. This ensures that they are always running the latest versions (including security patches and new features).
The issue with letting your IoT devices get out of date is security holes and that, when you are forced to upgrade, the latest version is unlikely to be fully compatible with the outdated setup. Keeping on top means you can fix small issues as they occur rather than being tasked with debugging a completely broken configuration at once.