Last active
January 26, 2026 18:02
-
-
Save emorydunn/db410db8bf68c8a335f3362d69624aaa to your computer and use it in GitHub Desktop.
Sonoff L1 ESPHome Component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| esphome: | |
| name: led_strip_1 | |
| platform: ESP8266 | |
| board: esp8285 | |
| includes: | |
| - custom_components/sonoff_l1.h | |
| wifi: | |
| captive_portal: | |
| # Logging must be disabled in order for the ESP to comunicate with the Nuvotron | |
| # logger: | |
| # hardware_uart: UART0_SWAP | |
| # level: VERBOSE | |
| # Enable Home Assistant API | |
| api: | |
| ota: | |
| light: | |
| - platform: custom | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| App.register_component(light_out); | |
| return {light_out}; | |
| lights: | |
| - name: "LED Strip 1" | |
| effects: | |
| - lambda: | |
| name: Colorful Gradient (Smooth) | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeGradient(); | |
| - lambda: | |
| name: Colorful Breath (Fade) | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeBreath(); | |
| - lambda: | |
| name: RGB Gradient | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeRGBGradient(); | |
| - lambda: | |
| name: RGB Pulse (Strobe) | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeRGBPulse(); | |
| - lambda: | |
| name: RGB Breath | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeRGBBreath(); | |
| - lambda: | |
| name: RGB Strobe (Flash) | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeRGBStrobe(); | |
| - lambda: | |
| name: Sound Reactive | |
| lambda: |- | |
| auto light_out = new SonoffL1(); | |
| light_out->setModeSync(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "esphome.h" | |
| class SonoffL1 : public Component, public LightOutput { | |
| #define SONOFF_L1_MODE_COLORFUL 1 // [Color key] Colorful (static color) | |
| #define SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // [SMOOTH] Colorful Gradient | |
| #define SONOFF_L1_MODE_COLORFUL_BREATH 3 // [FADE] Colorful Breath | |
| #define SONOFF_L1_MODE_DIY_GRADIENT 4 // DIY Gradient (fade in and out) [Speed 1- 100, color] | |
| #define SONOFF_L1_MODE_DIY_PULSE 5 // DIY Pulse (faster fade in and out) [Speed 1- 100, color] | |
| #define SONOFF_L1_MODE_DIY_BREATH 6 // DIY Breath (toggle on/off) [Speed 1- 100, color] | |
| #define SONOFF_L1_MODE_DIY_STROBE 7 // DIY Strobe (faster toggle on/off) [Speed 1- 100, color] | |
| #define SONOFF_L1_MODE_RGB_GRADIENT 8 // RGB Gradient | |
| #define SONOFF_L1_MODE_RGB_PULSE 9 // [STROBE] RGB Pulse | |
| #define SONOFF_L1_MODE_RGB_BREATH 10 // RGB Breath | |
| #define SONOFF_L1_MODE_RGB_STROBE 11 // [FLASH] RGB strobe | |
| #define SONOFF_L1_MODE_SYNC_TO_MUSIC 12 // Sync to music [Speed 1- 100, sensitivity 1 - 10] | |
| public: | |
| int mode = SONOFF_L1_MODE_COLORFUL; | |
| void setup() override { | |
| // nothing to do here | |
| Serial.begin(19200); | |
| } | |
| LightTraits get_traits() override { | |
| // return the traits this light supports | |
| auto traits = LightTraits(); | |
| // Use Supported Color Modes for 2021.8 and later | |
| traits.set_supported_color_modes({light::ColorMode::RGB}); | |
| // Use Individual traits for earlier versions | |
| // traits.set_supports_brightness(true); | |
| // traits.set_supports_rgb(true); | |
| // traits.set_supports_rgb_white_value(false); | |
| // traits.set_supports_color_temperature(false); | |
| 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); | |
| // Convert to 0-255 | |
| int redValue, greenValue, blueValue; | |
| redValue = floor(red * 255); | |
| greenValue = floor(green * 255); | |
| blueValue = floor(blue * 255); | |
| bool ledState; | |
| state->current_values_as_binary(&ledState); | |
| float brightnessPercent; | |
| state->current_values_as_brightness(&brightnessPercent); | |
| // Convert to 0-100 | |
| int brightness = floor(brightnessPercent * 100); | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d"), | |
| millis(), millis()%1000, | |
| ledState ? "on" : "off", | |
| redValue, greenValue, blueValue, | |
| brightness, | |
| SONOFF_L1_MODE_COLORFUL); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_COLORFUL_GRADIENT | |
| void setModeGradient() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_COLORFUL_GRADIENT | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_COLORFUL_BREATH | |
| void setModeBreath() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_COLORFUL_BREATH | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_RGB_GRADIENT | |
| void setModeRGBGradient() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_RGB_GRADIENT | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_RGB_PULSE | |
| void setModeRGBPulse() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_RGB_PULSE | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_RGB_BREATH | |
| void setModeRGBBreath() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_RGB_BREATH | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_RGB_STROBE | |
| void setModeRGBStrobe() { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_RGB_STROBE | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| // SONOFF_L1_MODE_SYNC_TO_MUSIC | |
| void setModeSync(int sensitive = 10, int speed = 50) { | |
| char buffer[140]; | |
| snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"mode\":%d,\"sensitive\":%d,\"speed\":%d"), | |
| millis(), millis()%1000, | |
| SONOFF_L1_MODE_SYNC_TO_MUSIC, | |
| sensitive, | |
| speed | |
| ); | |
| Serial.print(buffer); | |
| Serial.write(0x1B); | |
| Serial.flush(); | |
| } | |
| }; |
Can you create an issue on my repo & provide your config?
Since this is kinda off-topic to this custom component…
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I can't get it to work. If I change the ID, it compiles, but it loses all the LED strip functionality. This is my YAML:
substitutions:
device_name: "led"
esphome:
name: ${device_name}
esp8266:
board: esp8285
restore_from_flash: true
uart:
tx_pin: GPIO1
rx_pin: GPIO3
baud_rate: 19200
external_components:
components: [ sonoff_l1 ]
api:
encryption:
key: "XXX"
ota:
password: "XXX"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "LED"
password: !secret ap_password
captive_portal:
logger:
baud_rate: 0
web_server:
port: 80
time:
id: homeassistant_time
light:
name: "Sonoff L1"
id: led_cocina # Este es el ID actual
icon: mdi:led-strip-variant
on_turn_off:
// Usamos el ID correcto: led_cocina
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->resetMode();
effects:
name: "Gradient (Fast)"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeGradientFast();
name: "Gradient (Slow)"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeGradientSlow();
name: "Cycle (Fast)"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeCycleFast();
name: "Cycle (Slow)"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeCycleSlow();
name: "Pulse"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModePulse();
name: "Strobe"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeStrobe();
name: "Sound Reactive"
lambda: |-
auto output = (esphome::sonoff_l1::SonoffL1*)id(led_cocina).get_output();
output->activateModeSoundReactive(5, 50);
preferences:
flash_write_interval: 5min