[Deprecated] Design Pattern: Time Of Day

Sorry, I’ll rephrase, for each case you set curr = “something” can you set it so curr = “something” and curr2 = “something else” in the same case statement.

Yes. Like I said

case foo: {
    curr = "something"
    curr2 = "something else"
}

It’s just two lines of code.

Sorry, I misread the post on my phone screen.

case conditionA : {
  // the code in the curly brackets
  // is what gets executed
  // not the condition
 }
case conditionB || conditionC : {
  // the condition is similar to that in an if()
  // here the || qualifies as OR
}
case conditionX && conditionY : {
   // here the && acts as AND
}
case "EVENING" || "NIGHT" : {
   // DON'T FORGET THE COLON
}
2 Likes

Hi,

Just got round to implementing this…but I’m msiing something here… any help please?

switch now {
  	  case now.isAfter(morning_start)   && now.isBefore(day_start):       curr = "DAWN"       curr2 = "1"
  	  case now.isAfter(day_start)       && now.isBefore(afternoon_start): curr = "DAY"        curr2 = "2"
  	  case now.isAfter(afternoon_start) && now.isBefore(evening_start):   curr = "TWILIGHT"   curr2 = "3"
  	  case now.isAfter(evening_start)   && now.isBefore(night_start):     curr = "EVENING"    curr2 = "4"
          case now.isAfter(night_start):                                      curr = "NIGHT"      curr2 = "5"
  	  case now.isAfter(bed_start)       && now.isBefore(morning_start):   curr = "BED"        curr2 = "6"
      }

What I’m trying to do is set a var curr and a second var curr2 but the error I get is

Configuration model 'timeofday.rules' has errors, therefore ignoring it: [48,100]: no viable alternative at input '='
[48,102]: no viable alternative at input '"1"'
[49,6]: mismatched input 'case' expecting '}'
[49,72]: mismatched input ':' expecting 'end'

So I guess it doesn’t like 2 thens per case statement or do I need to have a & or similar between them / put them on separate lines?

…try it this way:

switch counter {
           case 0 :  {
                      daymin = day
                      daymax = day0
            }
           case 1 :  {
                      daymin = day0
                      daymax = day1
            }
           case 2 :  {
                      daymin = day1
                      daymax = day2
            }
           case 3 :  {
                      daymin = day2
                      daymax = day3
            }
           case 4 :  {
                      daymin = day3
                      daymax = day4
            }
           case 5 :  {
                      daymin = day4
                      daymax = day5
            }
    }

… use curly braces after the colon :wink:

1 Like

Thanks, feel a bit of a wally now, I’m blaming the excess of Christmas and some time off that my brain hasn’t kicked into gear yet…

Thanks for the help

One has to ask why you need two different representations of the same thing? Why can’t you just use curr or just use curr2?

It’s a question I’ve been asking myself too.

I’m doing a few rules where I want something to happen in more than one curr state, so in my ToD rule rather than say when ToD curr = Day or Evening or Night or Bed, I just wanted to say when ToD curr2 > 4.

Lazy, probably, but it just seemed easier to me.

OK, so why not be fully lazy and just use the number? There is nothing magical about using a String to represent the time of day. If the number works better for you, standardize on the number.

Yes, but the name is useful for just knowing what ToD it is to display rather than having to remember what ToD number 4 relates to.

Like I said…lazy :wink:

So create a map file and use the MAP transform in the label on your sitemap or in your logs (if you need it). Maintaining two items with the same information isn’t exactly lazy in my book. It’s just as much work and more work in the long run.

Yes, I did consider mapping it all but as it’s only an extra few lines I just let the rule do the work, plus it’s all there In one place should I ever add to the rule.

@rlkoshak,

Rich, I run into errors when using the above. I tried to find some info regarding the use of comma (,) inside a case statement but searching for case and , did not turn up much :grinning:

I get the following errors on the first case statement:

2019-12-31 08:24:23.728 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'time of day.rules' has errors, therefore ignoring it: [50,76]: no viable alternative at input '('
[50,88]: mismatched input '&&' expecting '=>'
[50,103]: no viable alternative at input '('
[50,118]: mismatched input ':' expecting '=>'

Maybe you have some hints?

kind regards,

Han

Scroll down to the Fall Through section.

What exactly is at line 50 column 76 in that file?

Hope you can see it in the picture, first case statement, just after the comma.

@rlkoshak,

found it, “case” was missing after the comma.

Hi,

I have tried to use the IS NOT case in the example rule. For some reason it is not working. Can anyone spot the mistake?

rule "BWM mit Tageszeit"
when Item RuleTest received update ON then
	 if(vTimeOfDay.state != "DAY") return;
      OU_Podest_Light.sendCommand(100)
      OU_FrontYard_Light.sendCommand(ON)

if	(OU_Vorgarten_Timer === null)
        {
	     OU_Vorgarten_Timer = createTimer(now.plusMinutes(3))
           [ | 
           
                { if (OU_Podest_Light.state instanceof DecimalType)
                  { percent = ((OU_Podest_Light.state as DecimalType)/5).intValue * 5 //round to 5
                    fade_Timer = createTimer(now.plusMillis(400)) [|
                    OU_Podest_Light.sendCommand(percent)
                        if (percent > dimmwert) {
                            percent = percent - 5
                            fade_Timer.reschedule(now.plusMillis(500))
                                               }
                    ]
                }
        }                      
            OU_FrontYard_Light.sendCommand(OFF)
            OU_Vorgarten_Timer = null ]
	    }
         else	{ OU_Vorgarten_Timer.reschedule(now.plusMinutes(3))
        }	
    
end

There is a near infinity contained in that statement. Not working how?

Does the .rules file parse successfully? Are there any errors in VSCode? Have you verified that RuleTest is receiving the update ON? Have you verified that vTimeOfDay is in fact not “DAY” or is in fact “DAY” depending on the use case you are going after?

Add logging to the top of the Rule to verify that the rule is triggering and what state vTimeOfDay actually is in.

Use vTimeOfDay.state.toString just to make sure you are comparing apples to apples.

Hi Rich,

thank you for your help. I’ve read so many helpful advise from you here. I really appreciate how much effort you put into this community.

I guess there are several problems in my script. Noob style try and error …

Where is it? I already realized that the dim value stays at 100 when it should actually go back to either 10 or 0 depending on the time of day. Is that the infinity statement you are referring to?

VS Code shows no errors. I tried the rule without the =! DAY statement and it worked more or less. Can you please tell me how to parse and start the logging? I found some commands for logging but I don’t get full results in my events.log. Concerning the “DAY” or not day question: The rule should run in the morning, evening, at night and bed time. Basically everytime when it is not day. The rule test switch will be replaced by a motion sensor switch once the rule is working.

EDIT: Now I managed to log vTimeOfDay. Result is “EVENING”

[INFO ] [eclipse.smarthome.model.script.Dimmwert] - EVENING

EDIT2: I simplified the rule and removed the fade down. It looks like the rule still does not get past the vTimeOfDay. Could it be because of the return;?

New rule:

rule "BWM Vordach mit Tageszeit"
when Item RuleTest received update ON then
      {

     if(vTimeOfDay.state != "DAY") logInfo (logDimm, vTimeOfDay.state.toString) return;
      OU_Podest_Light.sendCommand(100)
      OU_FrontYard_Light.sendCommand(ON)

if	(OU_Vorgarten_Timer === null)
        {
	     OU_Vorgarten_Timer = createTimer(now.plusMinutes(3))
           [ | OU_Podest_Light.sendCommand(dimmwert)
               OU_FrontYard_Light.sendCommand(OFF)
		        ]
          OU_Vorgarten_Timer = null      
	    }	
        else	{ OU_Vorgarten_Timer.reschedule(now.plusMinutes(3))
        }
      }      
    
end