[SOLVED] Multiple if conditions for triggering rules with time based

  • Platform information:
    • Hardware: RP3 +
    • OS: openhabian 2.4

Hello everyone, this is my first post on this forum, I hope my request is properly written.
Beginner on openhab, I try to create a rule that would allow me to activate some light scene based on the hours of detection of the presence of my phone via wifi and network binding.

For example if it is between 6 am and 7 am and phones are detect, activates the rule “atmosphere of the morning”,

If it is between 7am and 4pm activates the rule “evening atmosphere” etc …

I read this post which helped me partially, but I confess to being stuck:
https://community.openhab.org/t/execute-rule-during-certain-period-of-time/5440
Here are my items:

Group:Switch:OR(ON, OFF)                   Ambiance_Apero             "apero"                         (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_Matin             "Ambiance Lumiere du matin"     (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_cosy             "Ambiance cosy"                (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_TV                "Ambiance TV"                   (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_VP                "Ambiance VP"                   (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_Film_TV           "Ambiance film TV"              (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_Diner             "Ambiance diner"                (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_Pleine_lumiere    "Pleine lumiere"                (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_Soir              "Ambiance soir"                 (Ambiances_lumineuses)    [ "Switchable" ]
Group:Switch:OR(ON, OFF)                   Ambiance_feutree           "Ambiance faible"               (Ambiances_lumineuses)    [ "Switchable" ]

An example of one of my rule

rule "Ambiance rentree Matin"
when
Item G_Presence changed from OFF to ON
then
        var Number hour = now.getHourOfDay	
        if ((hour >= 4)  || (hour <= 8 )) {
      sendCommand(Ambiance_Matin, ON)
        }
        else if ((hour >= 8 )  || (hour <= 16 )) {
      sendCommand(Plafond_Entree_1, ON)
      sendCommand(Plafond_Entree_3, ON)
        }
        else if ((hour >= 16)  || (hour <= 21)) {
      sendCommand(Ambiance_Soir, ON)
        }
        else if ((hour >= 21)  || (hour <= 4)) {
      sendCommand(Ambiance_cosy, ON)
        } 
end
rule "Ambiance cosy"
when
      Item Ambiance_cosy received command ON  
then
        
        sendCommand(Niche_Droite, 10)
        sendCommand(Niche_Gauche, 10)
        sendCommand(Niche_Milieu,0)
        sendCommand(Lumieres_TV, 15)
        sendCommand(Plafond_Entree_2, 5)
        sendCommand(Plafond_Entree_1, 0)
        sendCommand(Plafond_Entree_3, 0)
        sendCommand(Plafond_Entree_4, 0)        
        sendCommand(Plafond_Salle_A_Manger_1, 15)
        sendCommand(Plafond_Salle_A_Manger_2, 0)
        sendCommand(Plafond_Salle_A_Manger_3, 15)
        sendCommand(ArcheDroite, 0)
        sendCommand(ArcheGauche, 0)
        sendCommand(ArcheMilieu, 15)
        sendCommand(Lumieres_Cuisine, 20)
        sendCommand(Lampe_Ambiance_Entree, 10)
        sendCommand(Lampe_Ambiance_Entree_ColorTemperature, 80)
      
postUpdate(Lumieres, ON)
postUpdate(Ambiance_Apero, OFF)
postUpdate(Ambiance_Diner, OFF)
postUpdate(Ambiance_Matin, OFF)
postUpdate(Ambiance_Film_TV, OFF)
postUpdate(Ambiance_TV, OFF)
postUpdate(Ambiance_Pleine_lumiere, OFF)
postUpdate(Ambiance_Soir, OFF)
postUpdate(Ambiance_cosy, ON)
postUpdate(Ambiance_VP, OFF)
postUpdate(Ambiance_feutree, OFF)

end

the result is that it’s always the “ambiance_matin” which is triggered.
What i’m doing wrong?
Thank you for your help.

Try this:

rule "Ambiance rentree Matin"
when
Item G_Presence changed from OFF to ON
then
        var Number hour = now.getHourOfDay	
        if ((hour >= 4)  && (hour <= 8 )) {
      sendCommand(Ambiance_Matin, ON)
        }
        else if ((hour >= 8 )  && (hour <= 16 )) {
      sendCommand(Plafond_Entree_1, ON)
      sendCommand(Plafond_Entree_3, ON)
        }
        else if ((hour >= 16)  && (hour <= 21)) {
      sendCommand(Ambiance_Soir, ON)
        }
        else if ((hour >= 21)  && (hour <= 4)) {
      sendCommand(Ambiance_cosy, ON)
        } 
end

You were using an OR gate instead of an AND gate, that is why your first if condition was most of the time true!

1 Like

it works perfectly

thx very much you make my day !

Here’s a link that I found to help with rules and understanding the logic that’s used. I’m not a programmer so I keep this bookmarked.:wink:
https://www.w3schools.com/js/js_comparisons.asp

Scroll down to Logical Operators.

Also, on the left side of the page you will see several other tutorials, the one just below Comparisons is JS Conditions, another good one for rules.

Hope you find this helpful.

1 Like

thx H102 a lot i bookmark too! very helpful!

Glad it helped.:grinning:

Good evening, I’m coming back to you, once again to solicit your expertise.
The solution made above worked fine until yesterday, then suddenly the variables no longer seemed to be recognized.
I did not see any changes in the logs.
I tried several combinations to be sure of the origin of the problem, and it turns out that by removing the var part

rule "Ambiance OFF TO ON"
when
Item G_Presence changed from OFF to ON
then
        var Number hour = now.getHourOfDay	
        if ((hour >= 4)  && (hour <= 8 )) {
      sendCommand(Ambiance_Matin, ON)
        }
        else if ....ETC....

… the rule runs correctly. i meen Item switch works, things works etc…!!! I’m going crazy

I really crossed all possible variables: like temporarily delete the rules files that can create conflicts, restart of course my raspberry and still nothing.

Do you have an explanation that would suddenly explain the fact that it does not work anymore? and also a solution.
It worked and suited me perfectly until then!

thanks in advance

okay i found my problem.

in my rule the passage of midnight posed problem, so i splited the sequence like this:

 then
     var Number hour = now.getHourOfDay	
        if ((hour >= 18)  && (hour < 0 ) || (hour >= 0)  && (hour < 4 )) {
     Do your stuff..//
        }
 end

everything seems to work until next time :smiley:

???

midnight =0

Sure, but you can’t test for hour less than zero. Hours don’t come in negative numbers. It certainly can’t be more than 18 and less than zero at the same time. Perhaps hour <= 23 ?

hour >= 0 is a bit redundant too. It’s always greater than or equal to zero.

if i understand your logic I should write the following rule in this way ? :

then
     var Number hour = now.getHourOfDay	
        if ((hour >= 18)  && (hour <= 23 ) || (hour > 0)  && (hour <= 4 )) {
     Do your stuff..//
        }
 end

do you confirm this:

I read that “hour <= 23” = 23:59
while hour <23 = 22:59

is it that well or have I misunderstood

Yep, that will work.

I am also trying to do a rule that switches on when 1) from a certain time onwards eg 7am, and 2) a wifi presence is detected. My phone wifi presence is determined by this item - OnePlus5 under Unifi binding. So it gives On or OFF.

This is my current rule that only fulfills 1)

rule "Flexion power to ON"
when	
	Time cron "0 0 7 ? *MON-SAT *"
then	
	mqttActions.publishMQTT("cmnd/sonoff-flexion/POWER", "On")
	sendTelegram("bot1", "Flexion Microscope is switched ON")
	logInfo("Info","Flexion power ON Rule fired")
end

How do I add condition 2) to the current rule such that it will still trigger the switch(if both conditions met) even if after 7am but not after 5pm?

I’m not sure to understand correctly your request, but if you want to trigger in your time slot when your phone is detected, you should try this rule

rule ""
when
    Time cron "0 0 7 ? *MON-SAT *"
then
    if(phoneitem.state == ON ) {
    Actions_here
}

Structure your rule so that it works from any trigger.
Then add the triggers that you want.
Psuedocode -

when
     turns 0700   or
     Wifi presence changed
then
    if (time between 0700 and 1700) AND (Wifi presence true)
    then   do Stuff

Thank you @yippicai and @rossko57 for your replies.
I am sorry if I was not clear. But I want to be able to trigger the switch BOTH the conditions of 1) time slot between 7am to 5pm, AND 2) presence is ON. Not either or.

Are either of your suggestions what I intend to be?

Yep, read it and see what it does. Mentally work through it with various conditions. Remember that if X then do stuff has the implication if not X then don’t do anything

Would this amended rule be correct?

rule "Flexion power to ON"
when	
	Time cron "0 0 7-17 ? *MON-SAT *" or
	Item OnePlus5 changed from Off to On
then
	if (OnePlus5 == ON) AND time between "0700 and 1700"	
	mqttActions.publishMQTT("cmnd/sonoff-flexion/POWER", "On")
	sendTelegram("bot1", "Flexion Microscope is switched ON")
	logInfo("Info","Flexion power ON Rule fired")
end

Well, as a work in progress :smiley:

Time cron “0 0 7-17 ? *MON-SAT *” or

You don’t need to fire the rule every hour to meet your requirement. It will fire every time presence changes, and if presence doesn’t change then you have no work to do.
You only need to fire once at the beginning of your time window, 0700, to assess whether presence is on or off at that time.

if (OnePlus5 == ON) AND time between “0700 and 1700”

Okay, my suggestion was in psuedo code, just made up language to show you the logic of how your rule should work.
For a real rule, you will need to use the proper syntax as shown in the documentation and thousands of examples in this forum.
The structure of an if(), for example:

if ( conditions) {
    // more code
}

Note the curly brackets { } defining the if-block.

if ( (condition one) && (condition two) ) { .....

Note the && symbol to denote logical AND in rules.

if (OnePlus5.state == ON) ...

Note the use of the .state method to get the state of an Item - as opposed to its label, name, etc.

time between "0700 and 1700"

Nah. :smiley:
One way is to get the current hour from the system now variable and do the comparison.
Part of the solution

Here’s an example looking for an hour of day range, like you want.

1 Like