wolfgang ziegler


„make stuff and blog about it“

Integrating a Custom LED Device into Home Assistant

August 19, 2022

TL;DR: In this project I integrated a custom LED lamp into Home Assistant using the Custom Light Output template for ESPHome.

I recently wrote about modding this Stars Wars LED device so that I could control it with an Arduino instead of the IR remote it came with originally.

Acrylic Yoda LED

Home Assistant Integration

The next step was integrating this LED device into my Home Assistant installation, so that it would be turned on and off together with a few other devices I already had programmed routines for.

Adding WIFI

The first prerequisite was adding WIFI to this LED device so that it could actually be controlled remotely via Home Assistant. Luckily, there's is a whole slew of Arduino-compatible devices available that come with built-in WIFI. One of these devices that I had readily available, is the WeMos D1 Mini that's based on the popular ESP8266 microcontroller.

The WeMos D1 Mini board

This board has a compact form factor which made it fit nicely into the LED's case.

ESPHome

The simplest way to integrate custom hardware into Home Assistant is via the ESPHome Add-on for Home Assistant. ESPHome brings a ton of new functionality to Home Assistant as long as the hardware is based on the ESP8266 or ESP32 microcontrollers (which is the case with the WeMos D1 Mini). The installation and configuration of ESPHome with Home Assistant is really straight-forward and well-documented.

Custom Light Output

While ESPHome brings a lot of built-in and out-of-the-box functionality for all kinds of sensors and devices, in this case a bit of custom code was required to integrate the custom LED device.

Fortunately, there is already a good template for integrating custom light output.

The example code snippet already provides everything I needed for my integration.

  • The setup method can be used to initialize the device.
  • The get_traits method lets the device report its capabilities (e.g. "RGB and brightness is supported"). With this information, Home Assistant knows what user interface to display (e.g. a color-wheel).
  • The write_state method then receives the actual command. In my case that's the RGB color information so I knew what LED color to display.
#include "esphome.h"

class MyCustomLightOutput : public Component, public LightOutput {
 public:
  void setup() override {
    // This will be called by App.setup()
    pinMode(5, INPUT);
  }
  LightTraits get_traits() override {
    // return the traits this light supports
    auto traits = LightTraits();
    traits.set_supported_color_modes({ColorMode::RGB, ColorMode::BRIGHTNESS});
    return traits;
  }

  void write_state(LightState *state) override {
    // This will be called by the light to get a new state to be written.
    float red, green, blue;
    // use any of the provided current_values methods
    state->current_values_as_rgb(&red, &green, &blue);
    // Write red, green and blue to HW
    // ...
  }
};

The only small challenge in my case was to map the RGB colors to well-known color-commands represented by the buttons originally on the IR remote.

E.g. an incoming RGB value of 255, 0, 0 needs to be mapped to the RED command.

A simple table that maps commands to RGB values and a mapping function did the trick here.

uint8_t mapColor(int r, int g, int b)
{
  uint8_t cmd = 0;
  int minDiff = 10000000;  
  for (int i = 0; i < sizeof(colorCommands) / sizeof(ColorCommand); i++)
  {
    auto diff = 
      abs(r - colorCommands[i].R) + 
      abs(g - colorCommands[i].G) + 
      abs(b - colorCommands[i].B);
    if (diff < minDiff)
    {
      minDiff = diff;
      cmd = colorCommands[i].Code;
    }
  }
  return cmd;
}

The complete source code of this custom component together with the yaml definition for the Home Assistant integration can be found here.

Home Assistant

The only remaining thing to do is the actual Home Assistant integration.

Note: The easiest way to work with the Home Assistant configuration is using the Visual Studio Code Server Add-on.

Simply copying the .h and the . yaml files into the esphome folder of your Home Assistant installation is all that needs to be done.

Configuring ESPHome in Home Assistant

The new custom device will then automatically show up via the ESPHome integration.

The ESPHome integration

Lights On!

I then added the new light device to an existing lights group called "Wohnzimmer LEDs" (that's German for "Living Room LEDs")


light:
  - platform: group
    name: Wohnzimmer LEDs
    entities:
      - light.tv_light_strip_couch
      - light.extended_color_light_8
      - light.fake_ir_led      

The next time my pre-configured automation was turning this light group on, LED Yoda already took part in it 😆.

The Star Wars LED lamp joins the light group