[SOLVED] Pulsing lights without Thread::sleep?

I do have sensors for the garage door and do pulse red light when the door opens, switching to blue when the door has reached final position. Pulsing also red when closing.
This is completely senseless but gives a real cool effect :sunglasses:

I learnt that “Thred::sleep” is not a good thing to do, especially when this exceeds one second. Therefore I want to optimize the code getting rid of “Thread::sleep”. This is more difficult than I thought. Right now the code is:

while(Ga_Garagentor_State.state == OPEN && Ga_Garagentor_Motion){
  // pulse red
  Ga_effect_co.sendCommand("0,100,100")
  Thread::sleep(1200)
  Ga_effect_co.sendCommand("0,100,10")
  Thread::sleep(1200)
} //while
//as soon as door is open, switch on blue light 
Ga_effect_co.sendCommand("250,100,100")

To my understanding, creating Timers within the while loop is not an option since this would just create a lot of timers and “while” becomes senseless.
I tried to work with expire timers but this seems to make the code quite complex 


Anything I missed or any other suggestions?
Thanks a lot

That here seems to have the answer:

@lipp_markus Thanks a lot for this ultra-fast hint.
Timer.reschedule was not on my radar 
will check.

while(Ga_Garagentor_State.state == OPEN && Ga_Garagentor_Motion){
  // pulse red
  Ga_effect_co.sendCommand("0,100,100")
  Thread::sleep(1200)
  Ga_effect_co.sendCommand("0,100,10")
  Thread::sleep(1200)
} //while
//as soon as door is open, switch on blue light 
Ga_effect_co.sendCommand("250,100,100")

Step 1:
Create while loop with timer:

var timer = null // global variable

timer = createTimer(now, [ |
    // pulse red
    Ga_effect_co.sendCommand("0,100,100")
    Thread::sleep(1200)
    Ga_effect_co.sendCommand("0,100,10")
    Thread::sleep(1200)
    if(!(Ga_Garagentor_State.state == OPEN && Ga_Garagentor_Motion))
        timer.reschedule(now.plusMillis(100))
    else timer = null
])

Step 2:
Use timers inside the loop:

var timer = null // global variable

timer = createTimer(now, [ |
    // pulse red
    createTimer(now, [ |
        Ga_effect_co.sendCommand("0,100,100")
    ])
    createTImer.now.plusMillis(1200), [ |
        Ga_effect_co.sendCommand("0,100,10")
    ])
    if(!(Ga_Garagentor_State.state == OPEN && Ga_Garagentor_Motion))
        timer.reschedule(now.plusMillis(2400))
    else timer = null
])

Are you using Hue bulbs?
You could just send the color and activate the alert channel with LSELECT.
This will let the bulb pulse in your desired color.

Or Fibaro FGRGBWM-441 actuators ? They have 5 builtin programs that you can trigger via param #72.

All, thanks a lot! Great support!

Yes, I am using Hue Light Strips and the alert channel works quite well. Even though it is a little bit faster and hence less “elegant” than the 1200ms delay, I give it a try since it is a build-in function.

I changed the

Ga_Garagentor_State.state == OPEN && Ga_Garagentor_Motion

condition and trigger the states with separate rules.

Summary: no Thread::sleep required! Fantastic!

1 Like