Light Effect - Random On/Off

I thought this would be easy, but for the life of me I cannot come anywhere close. I want to set up several monochromatic lights each having a random on/off effect. I.e. they would fade on, stay on for some random seconds, fade off, stay off for some random seconds, repeat. Alternately, they could just fade to a low brightness, if “off” within an effect is an issue…

I get as far as having a light that does turn on/off from HA. I’ve toyed with versions of the effect below, which would be a fixed 3 second cycle, as the next step. The effect does nothing other than sometimes changing the state in HA (the physical light does nothing).

  - platform: monochromatic
    name: "Light1"
    id: light_1
    output: led_white_output_1    
    effects:
      - lambda:
          name: "Random On/Off"
          lambda: |-
            id(light_1).turn_on().set_brightness(1.0).set_transition_length(1000).perform();
            esphome::delay_microseconds_safe(3000000);
            id(light_1).turn_on().set_brightness(0.1).set_transition_length(1000).perform();
            esphome::delay_microseconds_safe(3000000);

What am I doing wrong?

can you create two helpers, one Random, and then a Timer that is based on the Random?

You can just create an helper as Random → Random Sensor → name it, give the minimum minutes, maximum minutes, set device class as duration, set unit of measurement to min.

Now you have an entity that updates between minimum and maximum randomly. Use that value at the time of kicking off the timer.

Thanks for the suggestion, but I really want to keep all the logic on the ESP32 chip. In the end, I’ll probably just expose a switch to HA to turn on/off the effect but let the randomization run by ESPHome, so that that traffic is kept to a minimum.

Which leads me to think…maybe I’ll just try a script in ESPHome and not bother with the effects configuration.

Ok, I think I’ve figured this out, at least, good enough for my purposes.

Things I think I learned (someone who knows better can feel free to correct, but since they don’t respond to start with, I doubt that’ll happen):

  1. I don’t think the lambda effect can turn the light off, as that will also turn off the effect. So, I went with the brightness option instead
  2. I think excluding the update_interval on the lambda means it was constantly getting executed, which means it was triggering too fast for the bulb to actually show the desired effect. So I changed my code so that the cycle based on the update_interval. This works.
  3. I couldn’t figure out any way to introduce true random into this. It appears the update_interval must be static. So, I’m just going to set a different update interval for each of my lights, which should appear random enough for my purpose.

Sample of my working code for 1 light:

light:
  - platform: monochromatic
    internal: true
    id: light_1
    output: led_white_output_1   
    effects:
      - lambda:
          name: OnOff    
          update_interval: 6s
          lambda: |-
            static float b = 1.0;
            auto call = id(light_1).turn_on();
            call.set_brightness(b);
            call.set_transition_length(3000);
            call.perform();
            if (b == 1.0)
              b = 0.1;
            else
              b = 1.0;

switch:
  - platform: template
    name: "Random Lights"
    id: lights_switch
    optimistic: true
    on_turn_on:
      - light.turn_on:
          id: light_1
          effect: OnOff
    on_turn_off: 
      - light.turn_off:
          id: light_1