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?
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.
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.
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.
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
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
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
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