Good Morning, Afternoon, and Evening

Hello -

I’m in the midst of building a status board for our utility room. This board, built using HABpanel pulls information from Calendars as well as status information on the state of our garage doors, entry gate, as well as a few others.

I’d like to put a banner across the top that reads out…Good Morning, It’s Saturday May 22, 2018 at 10:33am

I’m familiar with everything past the greeting…

What would I need to do, to print Good Morning, Good Afternoon, or Good Evening based on the time of day?

You should just write a little script - here’s an example for starters:-

Instead of using “MORNING”, use “Good Morning” for the state.

Alternatively you can use the sun angle channel from Astro and set the phrase based on ho high up the sun is instead of wall clock time.

The key using time will be along the lines of:

var time = "Good Night"
if(now.isAfter(now.plusDays(1).minusHours(24-6)) time = "Good Morning"
if(now.isAfter(now.plusDays(1).minusHours(24-11)) time = "Good Afternoon"
if(now.isAfter(now.plusDays(1).minusHours(24-18)) time = "Good Evening"

Why the plusDays minusHours 24-x? To handle daylight savings.

Then just trigger the rule to run at system started and at those times and you are good to go.

It’s just a simplified version of the ToD DP.

1 Like

That’s a much better answer! Very cool :slight_smile:

Sorry…my tinkering skills aren’t grasping this…

Am I to take the code above:

and add that to the rule you have posted on the DP - Time of Day?

Need some direction on getting things to click in place.

Thanks,

Squid

Take the code above and add it to what ever Rule you run to populate the Item that is displaying the banner across the top.

The code is a simplified implementation of the Time of Day Design Pattern.

Thanks for your continued assistance…

I created a rule with the above code and I was first prompted in the log that OH was looking for an additional ) before time

Configuration model 'daypart.rules' has errors, therefore ignoring it: [16,51]: missing ')' at 'time'
[17,51]: missing ')' at 'time'

so I changed the code to:

var time = "Good Night"
if(now.isAfter(now.plusDays(1).minusHours(24-6))) time = "Good Morning"
if(now.isAfter(now.plusDays(1).minusHours(24-11)) time = "Good Afternoon"
if(now.isAfter(now.plusDays(1).minusHours(24-18)) time = "Good Evening"

which now passes validation.

The one issue I am now having is that it’s telling me “Good Evening” at 3:15CST - my system clock is set correctly. Where might we be off?

Add some logging so we can see what the now.plusDays… is evaluating to.

logInfo("test", "Evening start is " + now.plusDays(1).minusHours(24-18).toString)

It should default to "Good Night". Then the first if will evaluate to true so time will get set to "Good Morning". Then the second if will evaluate to true so the time will get set to "Good Afternoon". Then the third if should evaluate to false and time will stay at "Good Afternoon". We need to figure out what is wrong with that third if, or whether the whole set of logic is bogus.

I just typed it in. I think it should work but clearly there is something wrong.

Here’s what I have in the log…

2018-09-14 23:00:00.002 [INFO ] [.smarthome.model.script.system.rules] - Calculating time of day...
2018-09-14 23:00:00.005 [INFO ] [.smarthome.model.script.system.rules] - Calculated daypart is Good Night
2018-09-14 23:56:15.583 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'daypart.rules'
2018-09-14 23:56:20.758 [INFO ] [.smarthome.model.script.system.rules] - Calculating time of day...
2018-09-14 23:56:20.761 [INFO ] [.eclipse.smarthome.model.script.test] - Evening start is 2018-09-15T17:56:20.761-05:00
2018-09-14 23:56:20.762 [INFO ] [.smarthome.model.script.system.rules] - Calculated daypart is Good Night

The time OH thinks it is when this rule ran is 23:00:00.002.

So either you were burning the midnight oil or there is a mandatory between what time it is and what time OH thinks it is.

Add now to one of those log statements so we can get the time zone adjusted time and we can compare the two.

I suspect either your OS doesn’t have the right time it time zone or OH doesn’t have the region settings set correctly.

Or I’m totally misinterpreting the logs.

So yes, I was up late when I implemented the logging you suggested.

This was in the log this morning…

2018-09-15 06:00:00.001 [INFO ] [.smarthome.model.script.system.rules] - Calculating time of day...
2018-09-15 06:00:00.004 [INFO ] [.eclipse.smarthome.model.script.test] - Evening start is 2018-09-16T00:00:00.003-05:00
2018-09-15 06:00:00.005 [INFO ] [.smarthome.model.script.system.rules] - Calculated daypart is Good Night
2018-09-15 06:30:00.001 [INFO ] [me.model.script.sunriseholiday.rules] - The SunRISE CRON rule has triggered ON
2018-09-15 07:08:00.001 [INFO ] [.smarthome.model.script.system.rules] - Calculating time of day...
2018-09-15 07:08:00.003 [INFO ] [.eclipse.smarthome.model.script.test] - Evening start is 2018-09-16T01:08:00.003-05:00
2018-09-15 07:08:00.004 [INFO ] [.smarthome.model.script.system.rules] - Calculated daypart is Good Night

I checked the timezone of the server as well as OH and both appear to set to the correct time zone.

image

image

Add a log state for now returns the following:

2018-09-15 12:05:25.731 [INFO ] [eclipse.smarthome.model.script.test1] - Now is 2018-09-15T12:05:25.731-05:00

I need to see what now is as well as now.minusDays… from the same run of the rule.

The evening start time looks wrong on this run though, unless you changes it to midnight.

2018-09-15 13:21:39.054 [INFO ] [eclipse.smarthome.model.script.test1] - Now is 2018-09-15T13:21:39.054-05:00
2018-09-15 13:21:39.055 [INFO ] [eclipse.smarthome.model.script.test2] - Now Minus Days 2018-09-14T13:21:39.055-05:00
2018-09-15 13:21:39.055 [INFO ] [.smarthome.model.script.system.rules] - Calculated daypart is Good Night

Show your full rule. The now.plusDays… is ensuring to now.

rule "Calculate time of day state" 
when
  System started or // run at system start in case the time changed when OH was offline
  Channel 'astro:sun:home:rise#event'    triggered START or
  Channel 'astro:sun:home:set#event'     triggered START or
  Channel 'astro:sun:minus90:set#event'  triggered START or
  Time cron "0 1 0 * * ? *" or // one minute after midnight so give Astro time to calculate the new day's times
  Time cron "0 0 6 * * ? *" or
  Time cron "0 0 23 * * ? *"
then

  logInfo("system.rules", "Calculating time of day...")

var time = "Good Night"
if(now.isAfter(now.plusDays(1).minusHours(24-6))) time = "Good Morning"
if(now.isAfter(now.plusDays(1).minusHours(24-11))) time = "Good Afternoon"
if(now.isAfter(now.plusDays(1).minusHours(24-18))) time = "Good Evening"

  logInfo("test", "Evening start is " + now.plusDays(1).minusHours(24-18).toString)
  logInfo("test1", "Now is " + now.toString)
  logInfo("test2", "Now Minus Days " + now.minusDays(1).toString)

  // Publish the current state
  logInfo("system.rules", "Calculated daypart is " + time)
  vTimeOfDay.sendCommand(time)
end

Doh, I forgot the withTimeAtStartOfDay. Also, you need to trigger the Rule at each of the transition times.

rule "Calculate time of day state"
when
    System started or
    Time cron "0 0 6 * * ? *" or
    Time cron "0 0 11 * * ? *" or
    Time cron "0 0 18 * * ? *" or
    Time cron "0 0 23 * * ? *"
then
    logInfo("system.rules", "Calculating time of day...")

    val morningStart = now.plusDays(1).withTimeAtStartOfDay.minusHours(18)   // 6 am
    val afternoonStart = now.plusDays(1).withTimeAtStartOfDay.minusHours(13) // 11 am
    val eveningStart = now.plusDays(1).withTimeAtStartOfDay.minusHours(6)    // 6 pm
    val nightStart = now.plusDays(1).withTimeAtStartOfDay.minusHours(1)      // 11 pm

    var time = ""
    if(now.isAfter(morningStart) time = "Good Morning"
    if(now.isAfter(afternoonStart) time = "Good Afternoon"
    if(now.isAfter(eveningStart) time = "Good Evening"
    if(now.isAfter(nightStart) time = "Good Night"
    
    logInfo("time", "Time calculations:\n moringStart = " + morningStart.toStart +"\n afternoonStart = " + afternoonStart +
                    "\n eveningStart = " + eveningStart + "\n nightStart = " + nightStart +"\n now = " + now +
                    "\n time = " + time)

    if(time != "") vTimeOfDay.sendCommand(time) else logWarn("time", "time did not get set!")
end

Thanks for your continued assistance…

Copied the new rule in and received the following error in the log:

2018-09-17 10:53:55.176 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'daypart.rules' has errors, therefore ignoring it: [17,34]: missing ')' at 'time'
[18,36]: missing ')' at 'time'
[19,34]: missing ')' at 'time'
[20,32]: missing ')' at 'time'

I added the “)” at the locations requested and then came across this in the logs…

2018-09-17 11:00:00.006 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Calculate time of day state': 'toStart' is not a member of 'org.joda.time.DateTime'; line 22, column 61, length 20

It’s hard to type code on a phone.

Get rid of the .toStart in the log statement. There is no such thing.

1 Like

Looks like that did the trick!

Thanks so much for your assistance on this.

Squid

1 Like

@rlkoshak

I peeked in this evening to check on the rule and saw this in the log…

2018-09-18 00:19:19.531 [INFO ] [.smarthome.model.script.system.rules] - Calculating time of day...
2018-09-18 00:19:19.533 [INFO ] [.eclipse.smarthome.model.script.time] - Time calculations:
 moringStart = 2018-09-18T06:00:00.000-05:00
 afternoonStart = 2018-09-18T12:00:00.000-05:00
 eveningStart = 2018-09-18T18:00:00.000-05:00
 nightStart = 2018-09-18T23:00:00.000-05:00
 now = 2018-09-18T00:19:19.533-05:00
 time = 
2018-09-18 00:19:19.534 [WARN ] [.eclipse.smarthome.model.script.time] - time did not get set!