Rule trigger BETWEEN setpoints?

I have this rule that works flawlessly thanks to previous support from here. However, I’ve found an issue with how I am using it… basically, I want the light to get brighter as the LUX outside gets darker. I have the ‘working’ rule defined a handful of times, with a different brightness, the problem each, each time the LUX drops ALL my rules are triggering so the light sometimes get’s confused!

rule "Turn living room lights on when it starts to get dark (100)"
when
       Item Z_LUX_GF_Hallway changed
then
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        if ((Z_LUX_GF_Hallway.state as DecimalType) < 100 && Twilight_Lux.state == ON)
        {
        sendCommand(Hue_LivingRoom_MainLight, ON)
		sendCommand(Hue_LivingRoom_MainLightDim, 80)
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 100. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        }
end

What I really need is IF the value is BETWEEN two points, then trigger… Is this possible?

if ((Z_LUX_GF_Hallway.state as DecimalType) > 101 && (Z_LUX_GF_Hallway.state as DecimalType) < 150 && Twilight_Lux.state == ON)

Not as a trigger. Rule triggers do not provide that fine of a control. But if you wrap the logic of your rule in that exact if statement the behavior is the same as you are looking for.

So the rule body becomes:

if ((Z_LUX_GF_Hallway.state as DecimalType) > 101 && (Z_LUX_GF_Hallway.state as DecimalType) < 150 && Twilight_Lux.state == ON) {
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        if ((Z_LUX_GF_Hallway.state as DecimalType) < 100 && Twilight_Lux.state == ON)
        {
        sendCommand(Hue_LivingRoom_MainLight, ON)
		sendCommand(Hue_LivingRoom_MainLightDim, 80)
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 100. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        }
}
else {
    // ignore
}

However, something raises a flag in my mind. If the LUX dropping causes all your rules to trigger and those rules apparently interact with each other and “become confused”, that points to either merging the rules into one rule so you can better control these unwanted interactions, or adding locks to prevent more than one of these rules from running at the same time.

Which is appropriate largely depends on why you separated them in the first place.

I’ve found that unless the rules that are triggered by the same event are doing something completely different (e.g. one turns on a light while another resets the button to OFF) one gets much less error prone and easier to understand and follow rules by merging them into one, despite that one rule becoming more complicated.

Thanks again Rich… this is the full snippet. Take for example the Lux dropping below 50, all 3 rules trigger and occasionally the light will dim to 60% and then go to 100% in a second or two. It’s just weird on the eyes really.

rule "Turn living room lights on when it starts to get dark (150)"
when
       Item Z_LUX_GF_Hallway changed
then
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        if ((Z_LUX_GF_Hallway.state as DecimalType) < 150 && Twilight_Lux.state == ON)
        {
        sendCommand(Hue_LivingRoom_MainLight, ON)
		sendCommand(Hue_LivingRoom_MainLightDim, 60)
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 150. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        }
end

rule "Turn living room lights on when it starts to get dark (100)"
when
       Item Z_LUX_GF_Hallway changed
then
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        if ((Z_LUX_GF_Hallway.state as DecimalType) < 100 && Twilight_Lux.state == ON)
        {
        sendCommand(Hue_LivingRoom_MainLight, ON)
		sendCommand(Hue_LivingRoom_MainLightDim, 80)
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 100. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        }
end

rule "Turn living room lights on when it starts to get dark (50)"
when
       Item Z_LUX_GF_Hallway changed
then
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        if ((Z_LUX_GF_Hallway.state as DecimalType) < 50 && Twilight_Lux.state == ON)
        {
        sendCommand(Hue_LivingRoom_MainLight, ON)
		sendCommand(Hue_LivingRoom_MainLightDim, 100)
        logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 50. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
        }
end

If you test some value for say <100 it will also satisfy a test for <150

It does look like a case for rolling your rules into one using if-elseif-else structuring. (within the body of the rule)

Exactly…

I think I might cheat, and have the light get progressively brighter over say an hour or two AFTER the lux first drops below 150…

You can do exactly what you want, but you have to restructure to tell OH what you want.

Consider these pseudo rules -

Rule dim
when lux changed
If lux < 150 then blah

Rule darker
when lux changed
If lux < 100 then bleh

When lux changes to 99, BOTH rules fire. It is random pot luck which rule will complete last (due to multi threading), so you might end up with action blah or action bleh happening last.

When lux changes to 98, repeat, with another random result.

Consider instead

Rule consolidated
when lux changed
If lux < 100 then bleh
else if lux < 150 then blah
else …

Only one action is executed, the single result is entirely predictable

There is a switch–case programming technique available for the same ends.

Doing what you want will cope with thunderstorms and eclipses better than timers!

1 Like

Will see how this goes. Thanks.

rule "Turn living room lights on when it starts to get dark (elseif)" 
when 
    Item Z_LUX_GF_Hallway changed
then
	logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed, It's starting to get dark. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
	if ((Z_LUX_GF_Hallway.state as DecimalType) < 50 && Twilight_Lux.state == ON)
    {
	sendCommand(Hue_LivingRoom_MainLight, ON)
	sendCommand(Hue_LivingRoom_MainLightDim, 100)
	logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 50. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)					
	}    
	else if ((Z_LUX_GF_Hallway.state as DecimalType) < 100 && Twilight_Lux.state == ON)
    {
	sendCommand(Hue_LivingRoom_MainLight, ON)
	sendCommand(Hue_LivingRoom_MainLightDim, 80)
	logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 100. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)
	}
	else if ((Z_LUX_GF_Hallway.state as DecimalType) < 150 && Twilight_Lux.state == ON)
    {
	sendCommand(Hue_LivingRoom_MainLight, ON)
	sendCommand(Hue_LivingRoom_MainLightDim, 60)
	logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux < 150. Lux: "+Z_LUX_GF_Hallway.state+" - Main Light: "+Hue_LivingRoom_MainLight.state)					
	}   
end 

Failing that, I could create some switches I suppose.