Rule automatically turns on after switched off

Hello all!

I’ve been playing with a rule(s) to run a hue lightstrip thru a series of color changes during Christmas but can’t quite get it right…

After several iterations of For loops, nested IFs, single rule/split rule, I ended up with two rules shown below. The rule is actually much longer. The rest is the same as the ‘blue’ block, more color changes.

The problem is if I switch it off, sometimes it turns itself back on.

Items:

Color LT_Mirror “Mirror” (gLT) {hue=“11”}
Switch LT_Christmas “Christmas Mirror” (gLT)

Rules:

/* Christmas Mirror /
rule “Mirror On”
when
Item LT_Christmas received update ON
then
sendCommand(LT_Mirror, ON)
while(LT_Christmas.state == ON){
/
green */
var DecimalType hue = new DecimalType(120) // 0-360; 0=red, 120=green, 240=blue, 360=red(again)
var PercentType sat = new PercentType(100) // 0-100
var PercentType bright = new PercentType(50) // 0-100
var HSBType light = new HSBType(hue,sat,bright)
light = new HSBType(hue,sat,bright)
sendCommand(LT_Mirror, light)
Thread::sleep(5000)

    /* blue */
    hue = new DecimalType(240)
    sat = new PercentType(100)
    bright = new PercentType(80)
    light = new HSBType(hue,sat,bright)
    sendCommand(LT_Mirror, light)
    Thread::sleep(5000)   
}

end

rule “Mirror Off”
when
Item LT_Christmas received update OFF
then
sendCommand(LT_Mirror, OFF)
end

Any ideas greatly appreciated.

Thanks

Scot

After the “green sleep”, you should check LT_Christmas.state == ON again before setting the blue color since it may have been turned off during the sleep.

Haven’t quite wrapped my head around the order of events and why that worked, but it worked.

Thanks!

Maybe this will help (or not)… each column in the following text diagram is a sequence events executing concurrently in time. If the LT_Christmas switch is turned off after the while loop check and before either color transition, then the color transition will turn the light back on until the while loop evaluates the switch again. However, exiting the while loop will not turn off the light so it will stay stuck in the blue color (the last transition). I show the LT_Chrismas OFF event during the first sleep but it could happen any time before the second color transition.

"Mirror On" Rule                          "Mirror Off" Rule
=======================================   ========================
while LT_Christmas == ON
  Turn on LT_Mirror, set color to green
  5 second sleep starts
        <- - - - - - - - - - - - - - -    LT_Chrismas:OFF -> LT_Mirror, OFF
  5 second sleep end

  // Turns on LT_Mirror unconditionally
  Turn on LT_Mirror, set color to blue
  sleep 5 seconds

Thanks for your help and explanation.

I have a functioning light mirror doing what I want now!

After many variations I’ve settled on letting it run the color saturation up/down and change colors. And the color selection is chosen at random.

rule “Mirror”
when
Item LT_Christmas received update
then
// hue 0-360; 0=red, 120=green, 240=blue, 360=red(again)
var vSat = 100 // 0-100
var vBrt = 30 // 0-100
var vLimit = 100
var vIncrement = 1
var vTiming = 300
var random = 0
var low = 120
var high = 360
var DecimalType hue = new DecimalType(120)
var PercentType sat = new PercentType(vSat) // 0-100
var PercentType bright = new PercentType(vBrt) // 0-100
var HSBType light = new HSBType(hue,sat,bright)

if(LT_Christmas.state == ON){   
   sendCommand(LT_Mirror, ON)
   while(LT_Christmas.state == ON){
        random = (new java.util.Random).nextInt(high - low) + low
        while(vSat != 35){
            if (LT_Christmas.state == ON){
                hue = new DecimalType(random)
                sat = new PercentType(vSat)
                bright = new PercentType(vBrt)
                light = new HSBType(hue,sat,bright)
                sendCommand(LT_Mirror, light)
                Thread::sleep(vTiming)   
                vSat = vSat - vIncrement    
            } 
        } 
        random = (new java.util.Random).nextInt(high - low) + low
        while(vSat != vLimit){
            if (LT_Christmas.state == ON){
                hue = new DecimalType(random)
                sat = new PercentType(vSat)
                bright = new PercentType(vBrt)
                light = new HSBType(hue,sat,bright)
                sendCommand(LT_Mirror, light)
                Thread::sleep(vTiming)
                
                vSat = vSat + vIncrement    
            } 
        }
        
        vSat = vLimit
   } 
} else {
       sendCommand(LT_Mirror, OFF)
}

end