Matthew Dunlap
Already have some cheap LED strips? Hack them to work on Home Assistant!
#home_assistant #esphome #hack_the_planet

Long before I was interested in home automation, I purchased extra-cheap RGB LED strips to place underneath two sets of cabinets in the kitchen. These strips were the kind that attached to a little control box which has a through-hole IR receiver chip dangling from it via a wire. After opening the box and performing some tests, I discovered the circuit is a simple design: a micro-controller is attached to three MOSFETs that voltage control the red, green, and blue LEDs. When a color's MOSFET was given a voltage range of ~0.1 - 5V, the brightness of that LED will change from dark to light.
Planning
Having installed Home Assistant onto my home server and experimenting with ESPHome I was already accustomed to rapidly deploying privacy-focused IOT projects. All I needed was a ESP8266 or ESP32 micro-controller board and a 12V to 5V DC to DC converter. ESPHome has excellent support for RGB lighting strips via three GPIO outputs on the micro-contoller board using PWM (pulse-width modulation) for the dimming control of each color. I required temperature, humidity, and motion sensors in the kitchen and decided it would be best to place these on one of the strips to piggy-back off of the power supply and micro-controller.
After some testing, I discovered that the built-in 5V regulator could not supply enough current to support all of the components in the design. Luckily, I already had some cheap LM2596 based buck converters lying around that would do the trick. Therefore, I scraped off the little micro-controller and 5V linear regulator off the original controller board using my soldering iron This left the remaining circuitry behind. Because both the ESP micro-controllers GPIO pins operate on 3.3V rather than the original's 5V, the resistors between the PWM output and the gate side of the MOSFET were a bit higher value (470Ω instead of 330Ω). After some more testing, I discovered that leaving the 470Ω resistors would result in the lights being slightly dimmer; the voltage output could never reach the full 12V (it was ~11.2ish volts). Therefore, I did not change that value as I was willing to sacrifice the extra lumen for laziness.
Design and Build
For the first revision, I designed the version with the sensors as I wanted to get temperature sensing up and running to control a fan nearby. This version used a 3D printed case that contained a BME280, motion sensor, and an ESP32 controller board with an attached OLED display. The unit connected to the original control box via a repurposed Ethernet cable. Upon hooking everything up, I discovered that the original controller board's 5V regulator could not handle the load of all of the added stuff. This is when I de-soldered the regulator and added the buck-converter board using hot glue. The 12V power supply seems to handle the load okay but I upgraded from a 1 amp to a 2 amp version to be safe.
The case clasps together using cheap 6mm x 3mm rare-earth magnets. The lid is attached to the wall so that the entire unit and all of its wiring may be easily removed. This allows for future upgrade/repairs with little to no hassle. Plus the case makes a satisfying "click" sound when clasped.
The second version is a much simpler design owing to the fact it doesn't contain as much stuff. However, this time, I placed the new components around the original board and made it into a single unit. I will make a derivative of this design to house the first version's buck converter and MOSFET board.
Hardware / Bill of Materials
If you wish to make this project, the following are the materials that will be needed. I suggest that this should only be done if you already have the LED strip with the control box as described above. If not, compatible LED strips, MOSFETS, resistors, and a compatible power supply may be obtained cheaply. In this case, perfboard may cut to the size of the original board and placed in the case.
No Sensors Version
NAME | QTY | COST |
ESP8266 Board (make sure it is compatible with ESPHome) | 1 | ​$8 USD |
​3D Printer Plastic (I use PETG; PLA should work well) | ~40g | ~$0.88 USD ($22 per 1kg spool) |
With Sensors Version
NAME | QTY | COST |
ESP32 (w/OLED) Board | 1 | $20 USD |
​BME280 (temperature/humidity/pressure) | 1 | $15 USD |
PIR Sensor (motion) | 1 | $10 USD |
​3D Printer Plastic (I use PETG; PLA should work well) | ~75g | ~$1.65 USD ($22 per 1kg spool) |
Case Files
The following STL files were printed in PETG using 0.2mm layer height, no supports, and 15% infill. Feel free to adjust your print settings accordingly. The magnets are press-fit into the holes and shouldn't require any glue. However, I have successfully used super glue to hold magnets into other projects.
ESPHome YAML Code
No Sensors Version
esphome:
name: kitchen-sink
esp8266:
board: nodemcuv2
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxxxxxxxxxx"
ota:
password: "xxxxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Kitchen-Sink Fallback Hotspot"
password: "xxxxxxxxxxxxxxxxxxxxxxx"
captive_portal:
# RGB LED strip using PWM control.
output:
- platform: esp8266_pwm
pin: D6
id: led_red
- platform: esp8266_pwm
pin: D8
id: led_green
- platform: esp8266_pwm
pin: D7
id: led_blue
light:
- platform: rgb
name: "Kitchen Sink Lights"
red: led_red
green: led_green
blue: led_blue
restore_mode: RESTORE_DEFAULT_ON
With Sensors Version
esphome:
name: kitchen-counter
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxxxxxxcxxx"
ota:
password: "xxxxxxxxxxxxxxxxxxxcxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Kitchen-Counter"
password: "xxxxxxxxxxxxxxxxxxxcxxx"
captive_portal:
i2c:
# used for the OLED display and BME280 sensor
sda: 4
scl: 15
# Temperature, humidity, and pressure
sensor:
- platform: bme280
id: kit_bme280
temperature:
name: "Kitchen Temperature"
id: temp
pressure:
name: "Kitchen Pressure"
id: press
humidity:
name: "Kitchen Humidity"
id: hum
address: 0x77
update_interval: 60s
# OLED display stuff
font:
# grabbed the fonts from Google Fonts and put them a fonts directory
# in yaml root directory
- file: "fonts/IBMPlexMono-Italic.ttf"
id: ibm_mono_ital_18
size: 18
- file: "fonts/IBMPlexMono-Regular.ttf"
id: ibm_mono_24
size: 24
display:
# display tmep, humidity, and pressure; replace with whatever you
# would like to display
- platform: ssd1306_i2c
model: "SSD1306 128x64"
reset_pin: 16
address: 0x3C
id: the_display
pages:
- id: pg_press
lambda: |-
it.print(0, 0, id(ibm_mono_ital_18), "Pressure");
it.printf(0, 18, id(ibm_mono_24), "%.1f hPa", id(press).state);
- id: pg_hum
lambda: |-
it.print(0, 0, id(ibm_mono_ital_18), "Humidity");
it.printf(0, 18, id(ibm_mono_24), "%.1f%s", id(hum).state, "\%");
- id: pg_temp
lambda: |-
it.print(0, 0, id(ibm_mono_ital_18), "Temperature");
it.printf(0, 18, id(ibm_mono_24), "%.1f °C", id(temp).state);
interval:
- interval: 5s
then:
- display.page.show_next: the_display
- component.update: the_display
# LED strip
output:
- platform: ledc
pin: 21
id: led_red
- platform: ledc
pin: 22
id: led_green
- platform: ledc
pin: 19
id: led_blue
light:
- platform: rgb
name: "Kitchen Counter Lights"
red: led_red
green: led_green
blue: led_blue
restore_mode: RESTORE_DEFAULT_ON
# motion detection
binary_sensor:
- platform: gpio
pin: 17
name: "Kitchen Motion"
device_class: motion