ESPHome RGB Breathing Light effect

I´ve made my first own light effect for ESPHome, which just from almost off (to prevent showing a false-positive off state in HA) to full brightness and back to almost off and then cycles to the next color.

How-To: Simply add the code in effect.txt to your effects section of the light in your esphome configuration file of your node.

I know its not the most clean code, but i´m open for tipps and improvements

3 Likes

Sweet, there was a post about custom lighting effects on here, where they were looking to a list of extra ones.

How easy was it to work out this effect ?

@cooljimy84 Tbh, it wasnt that hard. Firstly i started with just breathing without a color cycle. After a few tries, it was breathing smoothly, then i had a few failed attemps to do the color cycle, but after adopting the style of the breathe, it worked flawlessly.
The example for a basic lambda effect from the esphome wiki was really helpful.
My usecase is to light up my RGB PC fan´s in style. Actually, HAss is a GUI for my RGB stuff for my gaming station (just look at that propretary stuff, espacially the “gaming” brands. once you got one brand, your´e stuck with them like forever, also im having fun building things), but im trying to add more uses for it like controlling the lights in my room remotely. A temperature sensor is already implemented, but i need to figure out, what i can automate/“do” with it, since im not most creative person around. Also im just living in a “small” room in a shared apartment.

Can you share a video?

1 Like

I will, once i completed the driver for my rgb pc fans, for which i planned this animation.

Trying to use this now,

Way too much space in the script. How can I add this to the yaml without going though, line by line and changing the spacing?

Also if I wanted only red, how could I do that?

Thanks :slight_smile:

Just went quick over the code, the spacing is needed i think.
For just red: Easy solution is set every #define Colorx to your prefered red value, like 1.0 , 0, 0, 1.0 beeing the max value. The most effiecent solution would be getting rid of the cases 2 to 12, removing the switch loop and removing the color loop. I would type that normally, but im about to go to bed.

Hey mate,

Thanks for that :slight_smile:

I must be doing it wrong then, I cant upload it :frowning:

If you get a sec to have a look, would appreciate it :slight_smile:

INFO Reading configuration /config/esphome/living_room_led_strip.yaml...
ERROR Error while reading config: Invalid YAML syntax:

mapping values are not allowed here
  in "/config/esphome/living_room_led_strip.yaml", line 44, column 17:
            - lambda:
                    ^

This is what I got;

I also ended up doing a kinda hybrid solution, removed all but two and then made the colours the same.

ota:

light:
  - platform: rgbw
    name: ${friendly_name}
    red: pwm_r
    green: pwm_g
    blue: pwm_b
    white: pwm_w
    
        - lambda:
           name: Breathing
           update_interval: 16s
           lambda: |-
            static int state = 0;
            static int color = 1;
            auto call = id(id).turn_on(); //the id of your light
            call.set_transition_length(15000);
            if (state == 0) 
            {
             call.set_brightness(1.0);
            }
             else if (state == 1)
            {
             call.set_brightness(0.01);
            }
             call.perform();
             state ++;
             if (state == 2){
             state = 0;
             }
        - lambda:
           name: RGB Breathing
           update_interval: 16s //Finetune to your liking with the transition lenght below
           lambda: |-
            #define Color1 0.8, 0.0, 0.4 //These are the colors defined, feel free to change or extend the list
            #define Color2 0.8, 0.0, 0.4 //if you extend the list, dont forget to add them in the switch loop below
            static int state = 0;
            static int color = 1;
            auto call = id(ID).turn_on(); //put the id for your light in here
            call.set_transition_length(15000);
            if (state == 0) 
            {
             call.set_brightness(0.01);
             
            }
             else if (state == 1)
            {
               switch(color)
               {
                 case 1: call.set_rgb(Color1);
                         break;
                 case 2: call.set_rgb(Color2);
                         break;
               }
              call.set_brightness(1.0);
            }
             
             state ++;
             if (state == 2){
             state = 0;
             }
             color++;
             if(color == 7)
             {
               color = 1;
             }
             call.perform();
             
             
    

output:
  - platform: esp8266_pwm
    pin: GPIO12
    frequency: 1000 Hz
    id: pwm_r

  - platform: esp8266_pwm
    pin: GPIO5
    frequency: 1000 Hz
    id: pwm_g

  - platform: esp8266_pwm
    pin: GPIO13
    frequency: 1000 Hz
    id: pwm_b

  - platform: esp8266_pwm
    pin: GPIO15
    frequency: 1000 Hz
    id: pwm_w

Hey mate,

Thanks for that :slight_smile:

I must be doing it wrong then, I cant upload it :frowning:

If you get a sec to have a look, would appreciate it :slight_smile:

I dont have the ID set right, But I have no idea where to put that in this context.

the lambda effects go in the effects list like this (taken from my pc node):

example
 - platform: rgb
   name: "Frontfans"
   id: "frontfan"
   red: outputTestRed
   green: outputTestGreen
   blue: outputTestBlue
   default_transition_length: 0.5s
   effects: 
        - lambda:
           name: RGB Breathing
           update_interval: 16s #Finetune to your liking with the transition lenght below
           lambda: |-
            #define Color1 1.0, 0.0, 0.0 //These are the colors defined, feel free to change or extend the list
            #define Color2 1.0, 0.5, 0.0 //if you extend the list, dont forget to add them in the switch loop below
            #define Color3 1.0, 1.0, 0.0 //and remember to adjust the reset counter at the bottom
            #define Color4 0.5, 1.0, 0.0
            #define Color5 0.0, 1.0, 0.0
            #define Color6 0.0, 1.0, 0.5
            #define Color7 0.0, 1.0, 1.0
            #define Color8 0.0, 0.5, 1.0
            #define Color9 0.0, 0.0, 1.0
            #define Color10 0.5, 0.0, 1.0
            #define Color11 0.5, 0.0, 1.0
            #define Color12 1.0, 0.0, 0.5
            static int state = 0;
            static int color = 1;
            auto call = id(frontfan).turn_on(); //put the id for your light in here
            call.set_transition_length(15000);
            if (state == 0) 
            {
             call.set_brightness(0.01);
             
            }
             else if (state == 1)
            {
               switch(color)
               {
                 case 1: call.set_rgb(Color1);
                         break;
                 case 2: call.set_rgb(Color2);
                         break;
                 case 3: call.set_rgb(Color3);
                         break;
                 case 4: call.set_rgb(Color4);
                         break;
                 case 5: call.set_rgb(Color5);
                         break;
                 case 6: call.set_rgb(Color6);
                         break;
                 case 7: call.set_rgb(Color7);
                         break;
                 case 8: call.set_rgb(Color8);
                         break;
                 case 9: call.set_rgb(Color9);
                         break;
                 case 10: call.set_rgb(Color10);
                          break;
                 case 11: call.set_rgb(Color11);
                          break;
                 case 12: call.set_rgb(Color12);
                          break;
               }
              call.set_brightness(1.0);
            }
             
             state ++;
             if (state == 2){
             state = 0;
             }
             color++;
             if(color == 7)
             {
               color = 1;
             }
             call.perform();

for just breathing red, you take this code:

Breathing red
effects: 
        - lambda:
           name: Breathing Red
           update_interval: 16s #Finetune to your liking with the transition lenght below
           lambda: |-
            #define Color1 1.0, 0.0, 0.0 //These are the colors defined, feel free to change or extend the list
                                         //if you extend the list, dont forget to add them in the switch loop below
                                        //and remember to adjust the reset counter at the bottom
            static int state = 0;
            static int color = 1;
            auto call = id(frontfan).turn_on(); //put the id for your light in here
            call.set_transition_length(15000);
            if (state == 0) 
            {
             call.set_brightness(0.01);
             
            }
             else if (state == 1)
            {
              call.set_rgb(Color1); 
              call.set_brightness(1.0);
            }
             
             state ++;
             if (state == 2){
             state = 0;
             }
             call.perform();
1 Like

Thanks so much for taking the time to write that up :slight_smile:

The thing I was missing was the id: got an answer to that on another post

need something like;

    name: ${friendly_name}
    id: livingroom_strip
    red: pwm_r
    green: pwm_g
    blue: pwm_b
    white: pwm_w
    effects:
       - lambda:

Then reference the id: in the script

Thanks again for that!!

This is great, thanks for sharing!! I’ve added it to a new RGBW strip controlled with an H801 and it works really nicely.

Im back trying to add a variation of this for some christmas light. But its stuck on green and wont go to red.

What do I have wrong here?

Thanks

       - lambda:
           name: Christmas
           update_interval: 16s #Finetune to your liking with the transition lenght below
           lambda: |-
            #define Color1 0.0, 1.0, 0.0 //These are the colors defined, feel free to change or extend the list
            #define Color2 1.0, 0.0, 0.0 //if you extend the list, dont forget to add them in the switch loop below
                                         //and remember to adjust the reset counter at the bottom

            static int state = 0;
            static int color = 1;
            auto call = id(printer_lamp).turn_on(); //put the id for your light in here
            call.set_white(0.0);
            call.set_transition_length(15000);
            if (state == 0) 
            {
             call.set_brightness(0.01);
             
             }
             else if (state == 1)
            {
               switch(color)
               {
                 case 1: call.set_rgb(Color1);
                         break;
                 case 2: call.set_rgb(Color2);
                         break;
               }
              call.set_brightness(1.0);
            }
             
            state ++;
            if (state == 2){
            state = 0;
            }
            color++;
            if(color == 2)
            {
              color = 1;
            }
            call.perform();

Sorry for late replay, but I think you have to reset color at 3, not 2.

Hey thanks for that.

I ended up getting it working with this

Might help someone

           name: Christmas
           update_interval: 16s #Finetune to your liking with the transition lenght below
           lambda: |-
            typedef struct { uint32_t transition_length; float brightness; float R,G,B; } stage_t;
            const stage_t Stages[] = {
            // Transition, Brightness, R, G, B
            { 15000, 0.01, 1.0, 0.0, 0.0 },
            { 15000, 1.0, 1.0, 0.0, 0.0 },
            { 15000, 0.01, 0.0, 1.0, 0.0 },
            { 15000, 1.0, 0.0, 1.0, 0.0 }
            };
            const int StageCount = sizeof(Stages)/sizeof(Stages[0]);
            static int stage = 0;
            auto call = id(printer_lamp).turn_on(); //put the id for your light in here
            call.set_transition_length(Stages[stage].transition_length);
            call.set_brightness(Stages[stage].brightness);
            call.set_rgb(Stages[stage].R, Stages[stage].G, Stages[stage].B);
            call.perform();
            if (++stage >= StageCount) stage = 0;
1 Like