Flashing ESPHome onto a Magic Hue LED Controller and integrating it into Home Assistant
A while back I have ordered a cheap, 5m LED strip with Wi-Fi capabilities. The hardware was perfectly fine, but the Wi-Fi controls only worked through the manufacturer’s own, questionable Chinese app that I didn’t really want to keep around on my phone. I set out to modify and configure the controller to work with both Home Assistant for home automation as well as Apple HomeKit for easy voice control.
Enter ESPHome and Home Assistant!
What is needed:
- LED controller with an ESP8266 chip (or derivatives thereof, mine has an ESP8285)
- FT232RL USB/TTL converter
- A configured Home Assistant client
While the controller has WiFi built in and can be flashed OTA, the first flash needs to be done wired. For that the controller needs to be wired up with the converter, connected to a computer, and flashed with a tool.
The first step is cracking open the casing of the controller. On the back side, the controller has 5 pads:
- Tx (transfer)
- Rx (receive)
- Vcc (power)
- Gnd (ground)
- GPIO 0
All 5 pads are needed for this, so I soldered jumper cables onto all of them.
After I used a multimeter to confirm that despite my horrible soldering skills the wiring was fine, I hooked it up with the serial converter.
The wiring is relatively simple; the one catch is that the transfer pad needs to be connected to the receive pin, and vice versa.
Another important thing is connecting the GPIO 0 pin to ground. This is needed to enable programming mode on the board, otherwise it won’t be possible to flash ESPHome onto it.
After wiring everything up, I installed the two pieces of software I needed to set up and flash ESPHome: esptool and ESPHome itself.
To set ESPHome up using docker, I first pulled the image:
$ docker pull esphome/esphome
The output of
runlike for my container is:
docker run --name=esphome --hostname=myhostname \ --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ --env=LANG=C.UTF-8 \ --env=LC_ALL=C.UTF-8 \ --env=USERNAME= \ --env=PASSWORD= \ --volume=/path/to/your/configs:/config \ --volume=/config \ --network=host \ --workdir=/config \ --expose=6052/tcp \ --restart=unless-stopped \ --detach=true \ esphome/esphome /config dashboard
Running this gave me access to an incredibly useful web UI, through which I could create the config that needed to be uploaded to the controller. Once the initial flash of the controller is done, this is also the platform through which OTA updates can be done – the new versions of your config can be loaded onto the controller through the UI. It is accessible on
I set up the node that I will use for the LED by clicking the “pulsating button at the bottom right of the page”.
The important settings are:
- Node Name: what will appear in the integrations
- Device Type: Generic ESP8266
- WiFi settings: the SSID and password of the access point that the controller will connect to
After the node has been set up, it was time to edit the config for it. The Edit button pulled up the editor, where I could edit the YAML for the node. Some of it was filled already, but it was still missing the actual light control. I added the following to the end of the file:
light: - platform: rgb name: "Media Center LED Strip" red: red_channel green: green_channel blue: blue_channel output: - platform: esp8266_pwm id: red_channel pin: GPIO5 - platform: esp8266_pwm id: blue_channel pin: GPIO13 - platform: esp8266_pwm id: green_channel pin: GPIO12
The GPIO pins for the colour channels might be different between devices, but most of them should match the configurations listed here.
Once set up, I downloaded the config by selecting Compile from the kebab menu on the freshly configured node.
With the above done, there was but one thing left to do: actually flash ESPHome onto the device. There are some GUI tools available for this (such as esphomeflasher), but I used esptools through CLI.
First, I installed esptools:
$ pip install esptool
Once installed, it can be used both to get some details about the connected device and to flash new software onto it.
This will display some info about the device:
$ esptool.py --port /dev/ttyUSB0 chip_id
The new binary can be uploaded to the controller with:
$ esptool.py --port /dev/ttyUSB0 write_flash 0x00000 /path/to/downloaded/binary
This flashes the downloaded binary onto the device at the specified port, starting from the
0x00000 address in memory.
If you do not know what port the device is connected to, you can watch the output of
# dmesg -w
to see where the converter is located.
With this, ESPHome was flashed to the controller!
The finishing touch was adding it to Home Assitant. This was probably the easiest step: the integration automatically shows up in the notifications of Home Assistant, which pretty much completely sets itself up.
It was then time for the finishing touches: I removed the wires form the pads, popped the controller back into the case, and the project was done!