Skip to content

Instantly share code, notes, and snippets.

@emorydunn
Last active April 11, 2024 12:23
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emorydunn/db410db8bf68c8a335f3362d69624aaa to your computer and use it in GitHub Desktop.
Save emorydunn/db410db8bf68c8a335f3362d69624aaa to your computer and use it in GitHub Desktop.
Sonoff L1 ESPHome Component
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();
#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();
}
};
@emorydunn
Copy link
Author

I finally got around to updating ESPHome and testing this out. Looks like @kancelott's change does the trick.

@eucciferri
Copy link

Thanks guys! It worked perfect for me too!

@geertmeersman
Copy link

Perfectly did the trick, thanks @kancelott and @sirronb !

@geertmeersman
Copy link

Hey guys, seems since the update I lost the color picker? Any idea why this happened?

@Kentrp
Copy link

Kentrp commented Mar 10, 2023

Hello! Does it work without server (HA) after compiling?

@emorydunn
Copy link
Author

@Kentrp It should, although I'm not sure how useful a device running ESPHome will be without Home Assistant.

@chatziko
Copy link

Hello, it seems that esphome 2023.7.0 broke this component for me. It looks like sending commands to the Nuvotron fails:

AT+UPDATE="sequence":"588226226","switch":"off","light_type":1,"colorR":0,"colorG":0,"colorB":0,"bright":100,"mode":1
[11:33:45][W][component:204]: Component light took a long time for an operation (0.22 s).
[11:33:45][W][component:205]: Components should block for at most 20-30ms.

Anyone else experiencing the same issue with 2023.7.0?

@mihsu81
Copy link

mihsu81 commented Jul 25, 2023

Hello, it seems that esphome 2023.7.0 broke this component for me. It looks like sending commands to the Nuvotron fails:

AT+UPDATE="sequence":"588226226","switch":"off","light_type":1,"colorR":0,"colorG":0,"colorB":0,"bright":100,"mode":1
[11:33:45][W][component:204]: Component light took a long time for an operation (0.22 s).
[11:33:45][W][component:205]: Components should block for at most 20-30ms.

Anyone else experiencing the same issue with 2023.7.0?

The same for me.

@chatziko
Copy link

Maybe esphome/issues#4717 is related? But I get the impression that other components show the "too a long time" warning but still work, while this one breaks.

A git bisect between 2023.6.5 and 2023.7 would be very useful to find the exact commit that breaks the component. Don't know whether I have the time to do it though.

@chatziko
Copy link

I found the issue, I had logger enabled for wifi logging, which up to now did not seem to be an issue, but maybe in the latest version logger tries to set the baud rate or something. I fixed it by setting baud_rate: 0 which disables serial logging.

logger:
  esp8266_store_log_strings_in_flash: false
  baud_rate: 0

With this change the controller actually became more responsive than before. Maybe with logger enabled the Nuvotron was being slowed down by debug messages sent to it?

Note also that the " took a long time for an operation" warning still appears, probably it takes too long to send the command over serial, but likely it's not an issue. In esphome/issues#4717 it is mentioned that components should use callbacks to avoid the warning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment