How do you use a variable in an if condition

Hey guys,

Ive got the following rule that I can’t figure out how to make the if condition work with a variable.

Any help would be amazing!

if	(VEnsuite_Main_Room_Lights == 1)
if	(VEnsuite_Main_Room_Lights ==0)

var Number Ensuite_Hue_Temp 
var Number Ensuite_Hue_Brightness 
var Number VEnsuite_Main_Room_Lights 
var Number Ensuite_Timeout_Minutes_Use
var Timer Ensuite_Lights_Timer = null

rule "Auto Ensuite Lights"

when
	Item Ensuite__Motion changed from OFF to ON
then
	logInfo("Auto Ensuite Lights", "Rule triggered")

if	(now.getHour <6) {
	logInfo("Auto Ensuite Lights", "Time is after 0600")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Night
 		Ensuite_Hue_Temp = 60
		Ensuite_Hue_Brightness = 20
		VEnsuite_Main_Room_Lights = 1
			}

if	(now.getHour <9) {
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 60
    	Ensuite_Hue_Brightness = 100
		VEnsuite_Main_Room_Lights = 1
			}

if	(now.getHour <22) {
	logInfo("Auto Ensuite Lights", "Time is after 2200")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 100
    	Ensuite_Hue_Brightness = 1
		VEnsuite_Main_Room_Lights = 0
			}

if	(now.getHour >6) {
	logInfo("Auto Ensuite Lights", "Time is after 2200 and before 7")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 100
    	Ensuite_Hue_Brightness = 1
		VEnsuite_Main_Room_Lights = 0
			}


if	((Ensuite_Lights_Timer !==null) && (Someones_Home.state == ON)) {
		logInfo("Auto Ensuite Lights", "Turning on lights and rescheduling timer")
       	Ensuite_Lights_Timer.reschedule(now.plusMinutes(Ensuite_Timeout_Minutes_Use ))
	if	(VEnsuite_Main_Room_Lights.state == 0)	{
	        Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
    }
	if	(VEnsuite_Main_Room_Lights.state == 1)	{
	     Ensuite__Main_Lights.sendCommand(ON)
         Ensuite_Left.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Right.sendCommand(Ensuite_Hue_Brightness)
    }
        	Ensuite_Right_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Middle_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Left_Temp.sendCommand(Ensuite_Hue_Temp)
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Entry_Timeout_Minutes_Use ), [|
        		])
if	((Ensuite_Lights_Timer === null) && (Someones_Home.state == ON)) {
		logInfo("Auto Ensuite Lights", "Turning on lights and setting timer")
	if	(VEnsuite_Main_Room_Lights == 0)	{
	        Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
    }
	if	(VEnsuite_Main_Room_Lights == 1)	{
	     Ensuite__Main_Lights.sendCommand(ON)
         Ensuite_Left.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Right.sendCommand(Ensuite_Hue_Brightness)
    }
        	Ensuite_Right_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Middle_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Left_Temp.sendCommand(Ensuite_Hue_Temp)
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Entry_Timeout_Minutes_Use ), [|
        		])
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Ensuite_Timeout_Minutes_Use ), [|
		logInfo("Auto Ensuite Lights", "Timer finished Turning Lights Off")
 	      	Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Left.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(OFF)
        	Ensuite_Right.sendCommand(OFF)
          		Ensuite_Lights_Timer = null
        		])
    		}}
end

These example conditions are correct. You already have some logging in this rule which is great for when the rule is working, but during development and debugging you can’t really have too much logging to track what’s going on. You are not seeing what you expect from the rule not because of these conditions, but several other problems with this rule.

Put some log statements after your initial list of if(now.getHour ...) conditions. You will find, I believe, that no matter what time it is your variables will always be:

Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
Ensuite_Hue_Temp = 100
Ensuite_Hue_Brightness = 1
VEnsuite_Main_Room_Lights = 0

Why? Your structure leaves each of those hour checks independent of the others. That means that every check always runs. So even if the hour is 4 and the first if statement sets your variable list to:

Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Night
Ensuite_Hue_Temp = 60
Ensuite_Hue_Brightness = 20
VEnsuite_Main_Room_Lights = 1

4 is also less than 22 and so the second to last statement will overwrite those values with its own.

There is no number that getHour can return that doesn’t satisfy either <22 or >6 and so one of those last two if statements will always be the final one to trigger and you will never have other values proceeding to the rest of the rule.

The solution here is to chain the if statements together so that the rule stops checking them as soon as it finds the first one that is true. This is what else and else if are for.

if (condition) {
    result code
} else {
    different result code
}

if (condition) {
    result code
} else if (different condition) {
    different result code
} else {
    code if none of the other conditions are true
}

When you add an else to your if statement the else code will only run if the initial condition was not satisfied. This gives you an easy way to handle binary results. “Under this one condition do X but in any other case do Y”.

Something like your complex rule, however, requires more than just a binary state and so you can use else if and supply other conditions that are only checked if all the previous conditions have not been satisfied. “Is this first condition true? No? OK, how about this second condition? Yes! Great then do X and don’t even bother checking the other possibilities.” With else if and else your <22 or >6 conditions won’t wind up overriding all the others because they won’t even be evaluated if one of the other conditions triggers first.

Once you have your structure clarified you are still going to require lots and lots of logging to find the remaining errors in the code. For example, VEnsuite_Main_Room_Lights is a number variable as you have declared it at the top of the rule file. However further down the rule you have VEnsuite_Main_Room_Lights.state. The .state is for items (which are objects that have lots of different information associated with them of which the state is just one option), it doesn’t mean anything for a number variable.

whoopsie tweaked the times in the rule so that it will work. because of the order of the times it is by design that they override variables :slight_smile: this is working confined by the logs.

Me adding the .state was trying to toubleshoot hahaha.

The other mistake that I made was having a bracket in the wrong place.

Here’s the completed rule incase anyone else might find it useful.

var Number Ensuite_Hue_Temp 
var Number Ensuite_Hue_Brightness 
var Number VEnsuite_Main_Room_Lights 
var Number Ensuite_Timeout_Minutes_Use
var Timer Ensuite_Lights_Timer = null

val int Ensuite_Timeout_Minutes_Night = 2
val int Ensuite_Timeout_Minutes_Day = 10



rule "Auto Ensuite Lights"

when
	Item Ensuite__Motion changed from OFF to ON
then
	logInfo("Auto Ensuite Lights", "Rule triggered")

if	(now.getHour <5) {
	logInfo("Auto Ensuite Lights", "Time is before 0500")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 100
    	Ensuite_Hue_Brightness = 1
		VEnsuite_Main_Room_Lights = 0
			}

if	(now.getHour >6) {
	logInfo("Auto Ensuite Lights", "Time is after 0600")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Night
 		Ensuite_Hue_Temp = 60
		Ensuite_Hue_Brightness = 20
		VEnsuite_Main_Room_Lights = 1
			}

if	(now.getHour >9) {
	logInfo("Auto Ensuite Lights", "Time is after 0900")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 60
    	Ensuite_Hue_Brightness = 100
		VEnsuite_Main_Room_Lights = 1
			}

if	(now.getHour >22) {
	logInfo("Auto Ensuite Lights", "Time is after 2200")
		Ensuite_Timeout_Minutes_Use = Ensuite_Timeout_Minutes_Day
    	Ensuite_Hue_Temp = 100
    	Ensuite_Hue_Brightness = 1
		VEnsuite_Main_Room_Lights = 0
			}


if	((Ensuite_Lights_Timer !==null) && (Someones_Home.state == ON)) {
		logInfo("Auto Ensuite Lights", "Turning on lights and rescheduling timer")
       	Ensuite_Lights_Timer.reschedule(now.plusMinutes(Ensuite_Timeout_Minutes_Use ))
	if	(VEnsuite_Main_Room_Lights == 0)	{
	        Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
    }
	if	(VEnsuite_Main_Room_Lights == 1)	{
	     Ensuite__Main_Lights.sendCommand(ON)
         Ensuite_Left.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Right.sendCommand(Ensuite_Hue_Brightness)
    }
        	Ensuite_Right_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Middle_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Left_Temp.sendCommand(Ensuite_Hue_Temp)
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Entry_Timeout_Minutes_Use ), [|
        		])
}

if	((Ensuite_Lights_Timer === null) && (Someones_Home.state == ON)) {
		logInfo("Auto Ensuite Lights", "Turning on lights and setting timer")
	if	(VEnsuite_Main_Room_Lights == 0)	{
	        Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
    }
	if	(VEnsuite_Main_Room_Lights == 1)	{
	     Ensuite__Main_Lights.sendCommand(ON)
         Ensuite_Left.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Middle.sendCommand(Ensuite_Hue_Brightness)
         Ensuite_Right.sendCommand(Ensuite_Hue_Brightness)
    }
        	Ensuite_Right_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Middle_Temp.sendCommand(Ensuite_Hue_Temp)
        	Ensuite_Left_Temp.sendCommand(Ensuite_Hue_Temp)
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Entry_Timeout_Minutes_Use ), [|
        		])
         	Ensuite_Lights_Timer = createTimer(now.plusMinutes(Ensuite_Timeout_Minutes_Use ), [|
		logInfo("Auto Ensuite Lights", "Timer finished Turning Lights Off")
 	      	Ensuite__Main_Lights.sendCommand(OFF)
        	Ensuite_Left.sendCommand(OFF)
        	Ensuite_Middle.sendCommand(OFF)
        	Ensuite_Right.sendCommand(OFF)
          		Ensuite_Lights_Timer = null
        		])
}
end

and the logs :slight_smile:

2021-05-21 14:57:45.632 [INFO ] [ore.model.script.Auto Ensuite Lights] - Rule triggered
2021-05-21 14:57:45.635 [INFO ] [ore.model.script.Auto Ensuite Lights] - Time is after 0600
2021-05-21 14:57:45.637 [INFO ] [ore.model.script.Auto Ensuite Lights] - Time is after 0900
2021-05-21 14:57:45.643 [INFO ] [ore.model.script.Auto Ensuite Lights] - Turning on lights and setting timer

I think you will find you still have a problem when the hour is 5 or 6 unless you employ <= and >=.