Share your Esphome light effects

So I have a whole bunch of devices running esphome, with just the standard light effects listed on the site.
Has anyone made any cool custom effects?
If so please share - it would be really nice to build up a thread of all the custom effects people have made, especially for this time of year when lots of people are using esphome devices for cool Christmas light setups :stuck_out_tongue_winking_eye:

I’ve looked at wled which has some lovely effects, but the board never seemed reliable running that.

I have the following 3 I’ve collected. Honestly though, I highly recommend taking a look at WLED again. It now has HA integration and it has more effects and customization (for lighting) than esphome ever will. I wish there were a way to marry the two but since microcontrollers are like $2, I don’t lose too much sleep over having some dedicated just to lighting.
I have been thinking about running two controllers next to each other and establishing a serial link between the two so I can maintain the automation at the edge that esphome enables with the lighting effects that WLED enables and it function even if HA or wifi are down. Haven’t messed with it yet though.

- addressable_lambda:
  name: "Christmas RedGreen (Static)"
  lambda: |-

    for (int i = 1; i <  it.size(); i+=2) {
    it[i] = light::ESPColor(255, 0, 18);
    }
    for (int i = 0; i <  it.size(); i+=2) {
    it[i] = light::ESPColor(0, 179, 44);
    }
  # from reddit user thedoctor___
  # https://www.reddit.com/r/homeassistant/comments/bua3u8/esphome_what_custom_addressable_lambda_effects/


- addressable_lambda:
  name: "Bluez"
  lambda: |-

    for (int i = 0; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(255, 255, 255);
    }

    for (int i = 1; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(255, 255, 255);
    }

    for (int i = 2; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(238, 0, 255);
    }

    for (int i = 3; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(238, 0, 255);
    }

    for (int i = 4; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(255, 157, 0);
    }

    for (int i = 5; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(255, 157, 0);
    }

    for (int i = 6; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(0, 28, 209);
    }

    for (int i = 7; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(0, 28, 209);
    }

    for (int i = 8; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(183, 255, 0);
    }

    for (int i = 9; i <  it.size(); i+=10) {
    it[i] = light::ESPColor(183, 255, 0);
    }
  # from reddit user thedoctor___
  # https://www.reddit.com/r/homeassistant/comments/bua3u8/esphome_what_custom_addressable_lambda_effects/

- addressable_lambda:
  name: "Fire"
  update_interval: 15ms
  lambda: |-
    int Cooling = 55;
    int Sparking = 110;
    static byte heat[188];
    int cooldown;

    // Step 1.  Cool down every cell a little
    for( int i = 0; i < it.size(); i++) {
      cooldown = random(0, ((Cooling * 10) / it.size()) + 2);

      if(cooldown>heat[i]) {
        heat[i]=0;
      } else {
        heat[i]=heat[i]-cooldown;
      }
    }

    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= it.size() - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
    }

    // Step 3.  Randomly ignite new 'sparks' near the bottom
    if( random(255) < Sparking ) {
      int y = random(7);
      heat[y] = heat[y] + random(160,255);
    }

    // Step 4.  Convert heat to LED colors
    for( int Pixel = 0; Pixel < it.size(); Pixel++) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((heat[Pixel]/255.0)*191);

      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 2; // scale up to 0..252

      // figure out which third of the spectrum we're in:
      //this is where you can reverse the effect by switching the commented out lines in all 3 places.
      if( t192 > 0x80) {                     // hottest
        //it[it.size() - Pixel - 1] = ESPColor(255, 255, heatramp);
        it[Pixel] = ESPColor(255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        //it[it.size() - Pixel - 1] = ESPColor(255, heatramp, 0);
        it[Pixel] = ESPColor(255, heatramp, 0);
      } else {                               // coolest
        //it[it.size() - Pixel - 1] = ESPColor(heatramp, 0, 0);
        it[Pixel] = ESPColor(heatramp, 0, 0);
      }
    }

-J

I wrote this quickly last night using @JayElDubya’s Red/Green as a base

      - addressable_lambda:
          name: "Static Rainbow"
          lambda: |-
           for (int i = 1; i < it.size(); i+=7) {
               it[i] = light::ESPColor(148, 0, 211);
            }
           for (int i = 0; i < it.size(); i+=7) {
               it[i] = light::ESPColor(75, 0, 130);
            }
           for (int i = 1; i < it.size(); i+=7) {
               it[i] = light::ESPColor(0, 0, 255);
            }
           for (int i = 0; i < it.size(); i+=7) {
               it[i] = light::ESPColor(0, 255, 0);
            }
           for (int i = 1; i < it.size(); i+=7) {
               it[i] = light::ESPColor(255, 255, 0);
            }
           for (int i = 0; i < it.size(); i+=7) {
               it[i] = light::ESPColor(255, 127, 0);
            }
           for (int i = 0; i < it.size(); i+=7) {
               it[i] = light::ESPColor(255, 0, 0);
            }

It just simply makes a static rainbow on my christmas tree. I use the Rainbow animation and the wife wanted one that didn’t move at all.

Just used a google for rainbow RGB to get the color values but they work well enough for me.

Thanks both, will be giving these a try out this evening :slight_smile:

Createt by @dashdrum and works great:

- addressable_lambda:
    name: Blue Scan
    update_interval: 25ms
    lambda:


      static int step = 0;
      static int direction = 1;

      if(initial_run){
        step = 0;
      }


      it[step] = ESPColor(0,0,255);
      if(step >0 && step < it.size()){
        it[step + (direction * -1)] = ESPColor::BLACK;
      }

      step = step + direction;

      if(step >= it.size() || step < 0){
        direction = direction * -1;
        step = step + (direction * 2);
      }

and this is mine:

      - addressable_lambda:
          name: snowflack
          update_interval: 43ms
          lambda:
    
            static int step = 0;
            
            static int startstepa = 0;
            static int startpositiona = 0;
            static int endpositiona = 0;
            static int directiona = 0;
            
            static int startstepb = 0;
            static int startpositionb = 0;
            static int endpositionb = 0;
            static int directionb = 0;
            
            
            if(initial_run){
              it.all() = ESPColor(0, 0, 0);
              step = 0;
              
              startstepa = 7;
              startpositiona = 79;
              endpositiona = 0;
              directiona = -1;
              
              startstepb = 55;
              startpositionb = 259;
              endpositionb = 180;
              directionb = -1;
            

            }

   
    
            if(step >= startstepa-3+(directiona*3) && step <= startstepa+(endpositiona-startpositiona)*directiona-3+(directiona*3)){
              it[startpositiona+((step-startstepa)*directiona)-3+(directiona*3)] = ESPColor(77, 54, 32);
            }
            if(step >= startstepa-3+(directiona*2) && step <= startstepa+(endpositiona-startpositiona)*directiona-3+(directiona*2)){
              it[startpositiona+((step-startstepa)*directiona)-3+(directiona*2)] = ESPColor(255, 181, 108);
            }
            if(step >= startstepa-3+(directiona*1) && step <= startstepa+(endpositiona-startpositiona)*directiona-3+(directiona*1)){
              it[startpositiona+((step-startstepa)*directiona)-3+(directiona*1)] = ESPColor(179, 127, 76);
            }
            if(step >= startstepa-3 && step <= startstepa+(endpositiona-startpositiona)*directiona-3){
              it[startpositiona+((step-startstepa)*directiona)-3] = ESPColor(77, 54, 32);
            }
            if(step >= startstepa-3-(directiona*1) && step <= startstepa+(endpositiona-startpositiona)*directiona-3-(directiona*1)){
              it[startpositiona+((step-startstepa)*directiona)-3-(directiona*1)] = ESPColor(51, 36, 22);
            }
            if(step >= startstepa-3-(directiona*2) && step <= startstepa+(endpositiona-startpositiona)*directiona-3-(directiona*2)){
              it[startpositiona+((step-startstepa)*directiona)-3-(directiona*2)] = ESPColor(26, 18, 11);
            }
            if(step >= startstepa-3-(directiona*3) && step <= startstepa+(endpositiona-startpositiona)*directiona-3-(directiona*3)){
              it[startpositiona+((step-startstepa)*directiona)-3-(directiona*3)] = ESPColor(0, 0, 0);
            }



            if(step >= startstepb-3+(directionb*3) && step <= startstepb+(endpositionb-startpositionb)*directionb-3+(directionb*3)){
              it[startpositionb+((step-startstepb)*directionb)-3+(directionb*3)] = ESPColor(77, 54, 32);
            }
            if(step >= startstepb-3+(directionb*2) && step <= startstepb+(endpositionb-startpositionb)*directionb-3+(directionb*2)){
              it[startpositionb+((step-startstepb)*directionb)-3+(directionb*2)] = ESPColor(255, 181, 108);
            }
            if(step >= startstepb-3+(directionb*1) && step <= startstepb+(endpositionb-startpositionb)*directionb-3+(directionb*1)){
              it[startpositionb+((step-startstepb)*directionb)-3+(directionb*1)] = ESPColor(179, 127, 76);
            }
            if(step >= startstepb-3 && step <= startstepb+(endpositionb-startpositionb)*directionb-3){
              it[startpositionb+((step-startstepb)*directionb)-3] = ESPColor(77, 54, 32);
            }
            if(step >= startstepb-3-(directionb*1) && step <= startstepb+(endpositionb-startpositionb)*directionb-3-(directionb*1)){
              it[startpositionb+((step-startstepb)*directionb)-3-(directionb*1)] = ESPColor(51, 36, 22);
            }
            if(step >= startstepb-3-(directionb*2) && step <= startstepb+(endpositionb-startpositionb)*directionb-3-(directionb*2)){
              it[startpositionb+((step-startstepb)*directionb)-3-(directionb*2)] = ESPColor(26, 18, 11);
            }
            if(step >= startstepb-3-(directionb*3) && step <= startstepb+(endpositionb-startpositionb)*directionb-3-(directionb*3)){
              it[startpositionb+((step-startstepb)*directionb)-3-(directionb*3)] = ESPColor(0, 0, 0);
            }


            step = step + 1;

            if(step >= 200 || step < 0){
              step = 0;
            }

You have to edit this section:

startstepa = 7; -> start time in the loop
startpositiona = 79; -> start position
endpositiona = 0; -> end position
directiona = -1; -> direction

just, if you like to scans/flake on the same time:
startstepb = 55;
startpositionb = 259;
endpositionb = 180;
directionb = -1;

if(step >= 200 || step < 0){ -> 200 = loop count
step = 0;
}

This is a simple one, but is a pleasing effect on an Xmas tree:

- addressable_lambda:
    name: Gold Glitter
    update_interval: 18ms
    lambda:
      static int state = 0;

      if (initial_run){
        state = 0;

        it.all() = ESPColor(218,165,32);

        ESP_LOGD("custom", "Gold Glitter");
      } else {

        it.all() = ESPColor(218,165,32);

        if(state==0){
          int i = rand() % it.size();
          it[i] = ESPColor::WHITE;
          state += 1;
        } else {
          state += 1;
          state = state % 10;
        }
      }