[Deprecated] Design Pattern: Time Of Day

Hello,
i have one Problem: DateTime is marked in my code and i get the Error Message:
"DateTime cannot be resolved…
Where do I need to define DayTime?

//–> Tagezeit
val logName = "Tageszeit"
rule "Kalkulieren der Tageszeit"
when
System started or
Time cron “0 0 5,22 * * ? *” or
Item SunriseTime received update ON or
Item SunsetTime received update ON or
Time cron "0 0 12 * * ? *"
then
Thread::sleep(50)

val morning = new DateTime(now.withTimeAtStartOfDay.plusHours(6).millis)

val sunrise = new DateTime((SunriseTime.state as DateTimeType).calendar.timeInMillis)
val afternoon = new DateTime(now.withTimeAtStartOfDay.plusHours(12).millis)
val evening = new DateTime((SunsetTime.state as DateTimeType).calendar.timeInMillis)
val night = new DateTime(now.withTimeAtStartOfDay.plusHours(23).millis)

var currPeriod = "ERROR"
if     (now.isAfter(morning)  && now.isBefore(sunrise))  currPeriod = "Morgen"
else if(now.isAfter(sunrise)  && now.isBefore(afternoon)) currPeriod = "Tag"
else if(now.isAfter(afternoon) && now.isBefore(evening))  currPeriod = "Nachmittag"
else if(now.isAfter(evening)  && now.isBefore(night))    currPeriod = "Abend"
else if(now.isAfter(night))                              currPeriod = "Nacht"

if(DayPhase.state.toString != currPeriod) {
logInfo(logName, “Aktuelle Tagesphase ist: " + currPeriod)
DayPhase.sendCommand(currPeriod)
sendMail(“Mailadress”,”[openHAB INFO] - Tageszeit wurde aktualisiert!","Die aktuelle Tageszeit ist: " + currPeriod)
}
end

What version of openHAB are you running?

If you are running openHAB 1.x you need to add

import org.joda.DateTime

at the top of your .rules file.

If you are running openHAB 2.x it should be imported automatically. However, you can try adding the import and see if that makes a difference.

I run Openhab2.
if i add “import org.joda.DateTime” i get the Error: "org.joda.DateTime cannot be resolved to a type"
I use the eclipse Smarthome desinger.

Edit:
Thanks, now its works :slight_smile:

it works for me this way:

import org.joda.DateTime

var DateTime dt = new DateTime()
(without “org.joda.”)

I more or less used the rule @rtvb suggested but my Eclipse SmartHome Designer and latest snapshot complain about the syntax, did the syntax for triggering channels change?

Note that depending on the Channel support the documentation should be updated:

ESHD 0.8.0 came out before Channel rule triggers were implemented. So it doesn’t recognize them and marks then as errors. It also fails to recognize non-core actions.

Yes but it also gives an error when saving, is that also expected.

What gives the error and what is the error? Does ESHD give the error or does OH give the error? If eshd, is there a pop-up or are you just seeing an error in the command prompt it was run from?

Does it still save the file?

Personally, I would not worry about exceptions or errors coming from ESHD unless you are also experiencing errors in OH. Designer is way behind and it doesn’t already anyone is actively working on it.

Real OH error, although not really clear:

2017-06-09 20:24:38.515 [DEBUG] [rg.quartz.core.QuartzSchedulerThread] - batch acquisition of 1 triggers
2017-06-09 20:24:38.527 [DEBUG] [rg.quartz.core.QuartzSchedulerThread] - batch acquisition of 1 triggers
2017-06-09 20:24:39.035 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 0 ms
2017-06-09 20:24:39.036 [DEBUG] [pse.xtext.util.OnChangeEvictingCache] - Clear 592 cache entries for resource time_of_day.rules after 6481 hits and 592 misses (quota: 91%)
2017-06-09 20:24:39.041 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'time_of_day.rules'
2017-06-09 20:24:39.042 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 0 ms
2017-06-09 20:24:39.045 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'time_of_day.rules' is either empty or cannot be parsed correctly!
2017-06-09 20:24:39.046 [DEBUG] [e.internal.engine.RuleTriggerManager] - Removed scheduled cron job 'time_of_day.rules#Calculate time of day state#0 0 6,23,0 * * ? *'
2017-06-09 20:24:39.046 [DEBUG] [rg.quartz.core.QuartzSchedulerThread] - batch acquisition of 1 triggers
2017-06-09 20:24:39.050 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 3 ms
2017-06-09 20:24:39.050 [DEBUG] [.linking.impl.AbstractCleaningLinker] - beforeModelLinked took: 0ms
2017-06-09 20:24:39.057 [DEBUG] [.linking.impl.AbstractCleaningLinker] - doLinkModel took: 7ms
2017-06-09 20:24:39.057 [DEBUG] [.linking.impl.AbstractCleaningLinker] - afterModelLinked took: 0ms
2017-06-09 20:24:39.072 [DEBUG] [pse.xtext.util.OnChangeEvictingCache] - Clear 423 cache entries for resource tmp_time_of_day.rules after 70 hits and 423 misses (quota: 14%)
2017-06-09 20:24:39.089 [DEBUG] [t.linking.impl.DefaultLinkingService] - before getLinkedObjects: node: 'long'
2017-06-09 20:24:39.095 [DEBUG] [t.linking.impl.DefaultLinkingService] - after getLinkedObjects: node: 'long' result: long
2017-06-09 20:24:39.099 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=162,c=32768,r=162],false)@COMMITTED
2017-06-09 20:24:39.099 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 162 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,945/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.099 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=162,l=162,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.099 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=169,c=32768,r=169],false)@COMMITTED
2017-06-09 20:24:39.100 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 169 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,1/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.100 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=169,l=169,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.101 [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing rule 'Total consumption update'
2017-06-09 20:24:39.102 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=171,c=32768,r=171],false)@COMMITTED
2017-06-09 20:24:39.102 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 171 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,2/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.102 [DEBUG] [t.linking.impl.DefaultLinkingService] - before getLinkedObjects: node: 'long'
2017-06-09 20:24:39.102 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=171,l=171,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.105 [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing rule 'Total consumption update'
2017-06-09 20:24:39.105 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=167,c=32768,r=167],false)@COMMITTED
2017-06-09 20:24:39.105 [DEBUG] [t.linking.impl.DefaultLinkingService] - after getLinkedObjects: node: 'long' result: long
2017-06-09 20:24:39.105 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 167 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,3/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.105 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=167,l=167,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.105 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=240,c=32768,r=240],false)@COMMITTED
2017-06-09 20:24:39.105 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 240 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,0/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.105 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=240,l=240,c=32768,r=0],false)@COMMITTED
,W,1/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.139 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=166,l=166,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.141 [DEBUG] [t.linking.impl.DefaultLinkingService] - before getLinkedObjects: node: 'DateTimeType'
2017-06-09 20:24:39.142 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=161,c=32768,r=161],false)@COMMITTED
2017-06-09 20:24:39.143 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 161 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,4/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.143 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=161,l=161,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.144 [DEBUG] [t.linking.impl.DefaultLinkingService] - after getLinkedObjects: node: 'DateTimeType' result: DateTimeType
2017-06-09 20:24:39.145 [DEBUG] [t.linking.impl.DefaultLinkingService] - before getLinkedObjects: node: 'long'
2017-06-09 20:24:39.149 [DEBUG] [t.linking.impl.DefaultLinkingService] - after getLinkedObjects: node: 'long' result: long
2017-06-09 20:24:39.154 [DEBUG] [t.linking.impl.DefaultLinkingService] - before getLinkedObjects: node: 'long'
2017-06-09 20:24:39.157 [DEBUG] [t.linking.impl.DefaultLinkingService] - after getLinkedObjects: node: 'long' result: long
2017-06-09 20:24:39.228 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=162,c=32768,r=162],false)@COMMITTED
2017-06-09 20:24:39.228 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 162 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,85/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.228 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=162,l=162,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.228 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: FLUSH (null,[p=0,l=162,c=32768,r=162],false)@COMMITTED
2017-06-09 20:24:39.228 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 162 SelectChannelEndPoint@6e00d91d{/192.168.1.191:52632<->5080,Open,in,out,-,W,0/30000,HttpConnection}{io=0,kio=0,kro=1}
2017-06-09 20:24:39.228 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@5e2c992a[PROCESSING][i=null,cb=Blocker@70c2df64{null}] generate: DONE (null,[p=162,l=162,c=32768,r=0],false)@COMMITTED
2017-06-09 20:24:39.231 [DEBUG] [pse.xtext.util.OnChangeEvictingCache] - Clear 592 cache entries for resource tmp_time_of_day.rules after 2544 hits and 592 misses (quota: 81%)
2017-06-09 20:24:39.232 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'time_of_day.rules'
2017-06-09 20:24:39.234 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 2 ms
2017-06-09 20:24:39.234 [DEBUG] [.linking.impl.AbstractCleaningLinker] - beforeModelLinked took: 0ms
2017-06-09 20:24:39.237 [DEBUG] [.linking.impl.AbstractCleaningLinker] - doLinkModel took: 3ms
2017-06-09 20:24:39.237 [DEBUG] [.linking.impl.AbstractCleaningLinker] - afterModelLinked took: 0ms
2017-06-09 20:24:39.248 [DEBUG] [pse.xtext.util.OnChangeEvictingCache] - Clear 423 cache entries for resource time_of_day.rules after 70 hits and 423 misses (quota: 14%)

This is everything on debug, the only hints imho are

2017-06-09 20:24:39.042 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 0 ms
2017-06-09 20:24:39.045 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'time_of_day.rules' is either empty or cannot be parsed correctly!

And the fact that rules do not seem to trigger although strange is the following:

2017-06-09 20:24:39.232 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'time_of_day.rules'
2017-06-09 20:24:39.234 [DEBUG] [er.antlr.AbstractInternalAntlrParser] - Parsing took: 2 ms
2017-06-09 20:24:39.234 [DEBUG] [.linking.impl.AbstractCleaningLinker] - beforeModelLinked took: 0ms
2017-06-09 20:24:39.237 [DEBUG] [.linking.impl.AbstractCleaningLinker] - doLinkModel took: 3ms
2017-06-09 20:24:39.237 [DEBUG] [.linking.impl.AbstractCleaningLinker] - afterModelLinked took: 0ms
2017-06-09 20:24:39.248 [DEBUG] [e.internal.engine.RuleTriggerManager] - Scheduled rule 'Calculate time of day state' with cron expression '0 0 6,23,0 * * ? *'

Maybe it reloads twice one when the editor emptied the file and another time after writing…

But my rule is still not triggered, I will try to add some debug statements later one.

Not sure what it going in here. I don’t really have much to offer.

Np, your rules ehm rule

But as far as you known the Channel syntax is correct that is the most important of it all :slight_smile:

Hi Rich,

Thanks for making such great tutorial.
When i try to use your code on OH2 i get this error in my log:

[ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'Calculate time of day state': org.eclipse.smarthome.core.library.types.DateTimeType

I tried the rules with:

import org.joda.DateTime

but that doesn’t work either, the error is still showing

In Eclipse SmartHome Designer, when i hover over ‘DateTimeType’ i see:

Note: This element has no attached Javadoc and the Javadoc could not be found in the attached source.

br,
Raymond

I wonder if the rule is trying to execute before the Items are fully initialized. Try adding a sleep at the top of the rule to see if that helps.

The problem isn’t with the data types. You do not need to import joda DateTime.

The warning in Designer can be ignored. It is just telling you the javadocs are not set up which is the case for ESHD 0.8.0.

I couldn’t add a sleep at the top of the file. Maybe i used the wrong syntax (i am new to all this :slight_smile:)
I did comment out ‘System started or’ like below:

val logName = "weather"
rule "Calculate time of day state"
when
  //System started or
  Channel 'astro:sun:local:rise#event' triggered START or
  Channel 'astro:sun:local:set#event' triggered START or
  Channel 'astro:sun:minus90:set#event' triggered START or
  Time cron "0 0 6,23,0 * * ? *" // there is currently a bug where only one cron is triggered per rule so I've combined all three into one
then
  Thread::sleep(1000) // make sure we are a tad past midnight to give Astro a chance to recalculate DateTimes for today

  val long morning_start = now.withTimeAtStartOfDay.plusHours(6).millis
  val long day_start = (vSunrise_Time.state as DateTimeType).calendar.timeInMillis
  val long afternoon_start = (vEvening_Time.state as DateTimeType).calendar.timeInMillis
  val long evening_start = (vSunset_Time.state as DateTimeType).calendar.timeInMillis
  val long night_start = now.withTimeAtStartOfDay.plusHours(23).millis
  val long bed_start = now.withTimeAtStartOfDay.millis

  var curr = "UNKNOWN"

  switch now {
        case now.isAfter(morning_start) && now.isBefore(day_start):       curr = "MORNING"
        case now.isAfter(day_start) && now.isBefore(afternoon_start):     curr = "DAY"
        case now.isAfter(afternoon_start) && now.isBefore(evening_start): curr = "AFTERNOON"
        case now.isAfter(evening_start) && now.isBefore(night_start):     curr = "EVENING"
        case now.isAfter(night_start):                                    curr = "NIGHT"
        case now.isAfter(bed_start) && now.isBefore(morning_start):       curr = "BED"
  }

  if(vTimeOfDay.state.toString != curr) {
    logInfo(logName, "Current time of day is now " + curr)
    vTimeOfDay.sendCommand(curr)
  }

end

Now my log doesn’t show the error anymore, strange isn’t it?
I hope you know what could cause this?
btw, what will be the consequences for commenting out what i did?

EDIT: OH2 uses

'astro:sun:local:set#event'

instead of:

'astro:sun:home:set#event'

br,
Raymond

Sadly my log still does show the error, not when i save the file in designer, but when the rule gets triggered.
Any help is much appreciated,
thanks

br
Raymond

Rich, i think i found whats wrong.
When i comment out my item with:

{ channel="astro:sun:minus90:set#start" }

The rule starts working and i get the following a message in my log, which indicates to me that everything is working:

2017-06-20 13:55:53.018 [INFO ] [lipse.smarthome.model.script.weather] - Current time of day is now DAY

There seems to be a syntax problem with ‘minus90’ but i don’t know how to write it properly, do you perhaps have any clue?
And is this working for you on OH2? because that seems strange to me :slight_smile:
I am on the OH2 snapshots

br
Raymond

Commenting out the System started trigger stops the error because it stops the rule from firing when the system restarts or the rules file loads. This breaks the rule as your TimeOfDay Item won’t have a value, potentially for hours.

My example is a complete example, including the Things. As you see in the op, I define two Things, one named astro:sun:home and one named astro:sun:minus90. The trigger channel must match the names of the Things you have defined. If you did autodiscovery rather than defining your own things like my example you must change the names in the rule trigger to match your Things.

Rich,
i am truly sorry, i assumed (and didn’t read carefully) that my auto detected things were sufficient.
I added the minus 90 thing and for the others i used the auto detected things and everything seems to work now.
Thanks for your patience :slight_smile:

One question i have, you seem to put a “v” infant of, for example: vSunset_Time and vTimeOfDay where on other places those “v”'s are missing, do these “v”'s have a purpose?

thanks,
br
Raymond

To tl;dr the posting sihui is its just a naming convention that I’ve evolved over time. Starts with a:

  • “v” indicates a value or a sensor
  • “a” indicates an actuator (i.e. something you can command)
  • “g” indicates a Group.

When I wrote the original pre-OH 2 version of the design pattern I had not yet adopted this naming convention. And even now I often try to remove them from my postings but I guess I was in a hurry this time and left them in.