How to combine AND and OR in an IF

Hey guys,

I have some doubts about the correct use of AND and OR in one IF part of a rule.

I want my rule to do something but only if some variables all are true and one variable can have two states. So typically combining && and II but it’s not working.

Here is the rule:

rule "Automatisches Badlicht Wochentags"
when
	Item OG_Ankleidezimmer_Licht changed to ON
then
	if (Daemmerung.state <= 250 && (Tagesart.state == "Wochentag" || Tagesart.state == "Homeoffice") && now.getHourOfDay >= 5 && now.getHourOfDay <= 8 && OG_Flur_Licht.state == OFF){
	sendCommand (OG_Bad_Licht, ON)
    sendCommand (OG_Bad_SpiegelLicht, ON)
    sendCommand (OG_Bad_Rolladen, UP)
	}
end

I guess putting the OR in brackets isn’t the right way to do?

By the way (so I dont have to create another topic :wink: ) is it possible to add an IF in an IF?
And multiple IFs in a rule aren’t possible because I have to use “else if” because if the first IF wasn’t true the rule wouldn’t even come to the second IF, right?

I personally find it hard (for my future self) to understand complex IF statements.

I recommend therefore this approach:

if (Daemmerung.state > 250 ){
  return;
}
if (Tagesart.state <> "Wochentag" && Tagesart.state <> "Homeoffice"){
return;
}
if (now.getHourOfDay < 5){
   return;
}
if ( now.getHourOfDay > 8 ){
return;
}

OF_Flur_Licht.state == OFF)
sendCommand (OG_Bad_Licht, ON)
sendCommand (OG_Bad_SpiegelLicht, ON)
sendCommand (OG_Bad_Rolladen, UP)

this way, you can also easily track (logInfo( ) ) which rule has a problem

1 Like

Thanks for your suggestion
To be honest I dont know what “return” does here.

I try to describe my understanding:
First if state is true
It “returns” the next if. Is the state of that also true next if will be returend. Correct?
If a one of them is not true the rule doesnt continue and so the wished result won’t happen.

What would happen if is would just write the different ifs without the “return”?

"returns; " leaves/exits the rule. so the sendCommands are only reached if all those returns are never reached. See the statement in detail, i Switched <= to > 250…

those are little “prerequisits” in the rule, they all must be false, only than, the action is triggered.

I see no (obvious) problem with the code. I would use some logInfo lines in order to show the states of the different items when the rule is running.

Yes, nested if statements ard possible.

Why should multiple if statement be not possible? The need of an elseif depends on what you want to check.

Without a return command the following if will, be prosecuted.
Look into the example of @papaPhiL, when reaching the return command the executing exit this rule, otherwise it would continue with the next if statement.

Philipp’s solution is the best one. Avoid long complicated conditionals like this as they are very hard to read and understand for others and for future you. Always remember that future you needs to be able to read and understand the code too. For further discussion on that approach see Design Pattern: How to Structure a Rule.

First, to answer some of your specific questions:

  • Yes you can have nested if statements:
if(Dammerung.state < 250){
  if(Tagestart.state == "Wochentag" || Tagersart.state == "Homeoffice") {
    // and so on
  }
}
  • Putting the or clause in the parentheses is exactly correct in this case. They work the same way as in math. The operations inside the parens are evaluated first which is what you want here.
  • But that’s what you want. As written everything in that conditional has to be true for the code in the if to execute. So if you are using nested ifs you only execute the code if all of the ifs evaluate to true. However, when using else if, the second if would only be reached if the first if was false.

I’m pretty sure you mean to use == and not <> here. The diamond operator is used to do stuff with generics, not equivalence comparisons. Also, it looks like the fourth to the last line had the first part of it cut off. It’s missing the if( and it;s missing the return.

In OH 3, the list of conditions would be placed in the “But only if” clause of the rule. All but the Tagesart conditions could be handled without actually writing the code for it through the UI. The Tagesart would be handled using a script conditional.

I think this every time I find an old Post-It note that has something like “jen 9” written on it. Is that my sister or coworker? Was I supposed to do something at 9am or 9pm? Does one of us owe the other $9? Has this already happened?

And yet, I still leave myself silly notes like this, and still don’t add descriptive comments to my items/rules to explain to Future Russ what Past Russ was thinking when he was Present Russ.

1 Like