[Deprecated] Design Pattern: Time Of Day

A lot of programming languages use indentation (tabs, not spaces) mostly for human readability, you’re right, the code works fine without. YAML uses them as functional parameters, I see that. But I’ve far more often hunted for errors because of that (yaml configuration files, for instance) than otherwise. With brackets, it’s a lot easier to see which parts of the code actually belong together, especially when that code stretches over many lines. But that’s just me. I guess with yaml you then have to count spaces :slight_smile:

And JSON, well, I love it for parsing JSON outputs, but not for much more.

Hi,
as i still struggle with my Openhab 3.0 Upgrade, one function needs a rewrite.
Currently i get a
“failed: ‘getHourOfDay’ is not a member of ‘java.time.ZonedDateTime’; line 16, column 19, length 18 in icloud”
What i am doing?
Something like that:

var Number hour = now.getHourOfDay()
        if (hour>=6 && hour<=9) {
                sendCommand(Hue_Nachtmodus_Sensor_SensorState,"0")
        }

So nothing special, just get the current hour and compare it to my timeframe.
This now fails.
Can anyone write me a quick and dirty example how to get the current hour in openhab3.0?
I have read through many threads, but i cannot imagine, that i have to perform such complex coding as mentioned just for getting the hour :confused:

Thanks !
Der_Gute

The full ZonedDateTime docs are at ZonedDateTime (Java SE 11 & JDK 11 )

Use getHour().

1 Like

Please @rlkoshak update the rule for OH3 :pray:

It is already. There is a JavaScript UI generated rule linked to in the original post. I’m probably going to remove the Rules DSL version as I do not intend to continue supporting it for Time of Day. I never liked how it had to be implemented in Rules DSL and am not inclined to keep maintaining it any longer. My time is better spent elsewhere, especially since there is a Python version for OH 2.5 and a JavaScript version for OH 3 that will let you implement Time of Day without ever needing to look at or edit the code, and they let you define a different set of times of day based on the type of day.

In short, there are far better and more capable implementations of Time of Day posted and described in the original post. Use those instead.

For DSL lovers, I adapted the DSL rule by @rlkoshak for OH3 (with help of this contribute).

val logName = "Time Of Day"

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(logName, "Calculating time of day...")

  val ZonedDateTime zdt = ZonedDateTime.now()
  val ZonedDateTime start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getOffset())

  // Calculate the times for the static tods and populate the associated Items
  // Update when changing static times
  // Jump to tomorrow and subtract to avoid problems at the change over to/from DST
  val morning_start = start_of_day.plusDays(1).minusHours(18)
  vMorning_Time.postUpdate(morning_start.toString) 

  val night_start = start_of_day.plusDays(1).minusHours(1)
  vNight_Time.postUpdate(night_start.toString)

  val bed_start = start_of_day
  vBed_Time.postUpdate(bed_start.toString)

  // Convert the Astro Items to Joda DateTime
  val day_start = (vSunrise_Time.state as DateTimeType).getZonedDateTime()
  val evening_start = (vSunset_Time.state as DateTimeType).getZonedDateTime()
  val afternoon_start = (vEvening_Time.state as DateTimeType).getZonedDateTime()

  // Calculate the current time of day
  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"
  }

  // Publish the current state
  logInfo(logName, "Calculated time of day is " + curr)
  vTimeOfDay.sendCommand(curr)
end

// Examples for use of vTimeOfDay
rule "Day time started"
when
  Item vTimeOfDay changed to "DAY" // does not work prior to OH 2.3 Release
then
  // do stuff when DAY starts
end
5 Likes

We already had a better implementation of the DSL rule than mine by Dan a while ago.
Post 572, I think.

I have just migrated to OH3 and most of my motion triggered rules have the vTimeOfDay in it. Thank you for making it work again.

1 Like

Is this still true in the Javascript version?
I can’t check it now because of time of the year, but based on viewing the code, I get the feeling that it won’t look anymore to the state (MORNING,DAY,EVENING etc), but just which comes first based on time. So in Summer if I set my MORNING to 07:00h and DAY to the sunrise (eg 06:13h), the sequence of events will be DAY, MORNING, EVENING etc.

Is this intentionally changed versus the old DSL rule?

I have to admit that I currently also rely on the DSL rule. The JS rule works fine, but every time I restart OH3 it messes up the ephemeris settings and that obviously kills the JS rule.

I don’t know that I’ve explicitly tested for it.

The JavaScript and Python versions do work differently by design so they might not work that way any more. Frankly, what I would do to handle this case is to adjust it in the Astro binding Thing where you can set a no-earlier than and no-later than properties to control when the times/events occur.

The Python and JavaScript versions of the rule are a complete rewrite and have almost nothing in common with the Rules DSL version.

Rules DSL JavaScript/Python
Rule triggers at each time of day transition Rule triggers once a day and sets timers for time of day transitions
Only works with Astro and cron times Supports any DateTime Item
Has a fixed set of times of day Supports a different set of times of day based on Ephemeris day type
Requires the rule code to be edited to change times of day Only requires creation and editing of Items to change times of day

In my opinion, the JavaScript/Python versions are significantly better and more flexible compared to the Rules DSL version and I’m inclined to deprecate the Rules DSL version entirely.

Have you filed an issue?

1 Like

Thx @rlkoshak for your answer. I understand now the difference and I’m also think that the JavaScript/Python versions are better, despite the “old feature” I miss. I’m going to test it with the Astro binding as you said.
Keep up the good work :+1:t2:

Long ago. No replies there nor a fix.
Does that happen to you, too, or is it just me?

It’s all volunteer effort. Filing an issue is no guarantee that the issue will be fixed. Someone must volunteer their time to fix it. And if it’s a problem that is difficult to reproduce, or the issue doesn’t have enough detail for the developer to reproduce, it may never get fixed.

Sometimes you can sweeten the pot by filing a bounty source on the issue. Sometimes a little bit of money will help convince someone to fix an issue or implement a feature request.

But at this point you’ve done your part and that’s about all you can to.

Sorry, that’s not what I meant.
I just wondered if your Ephemeris settings also get screwed up when you restart openhab.

Oh, no. I’ve not had any problems with Ephemeris. Though I’ve only defined weekdays/weekends and my location to get holidays.

1 Like

Strange. It’s the location that gets deleted every time, and that prevents the script from running.
Do you know if I can define that in a config file somewhere in OH3?

I’m sure there is but I’ve never looked into that. Probably ephemeris.cfg. You can set it and then look in /var/lib/openhab/config/org/openhab/ for the ephemeris.config file and see what the cfg file should include.

One thing though that is important is always select from the list, don’t type in a region. If there is no drop down (e.g. there is no city options for my region) don’t enter anything.

That’s the thing, after a restart the dropdown is empty.
I’ll have a look at the config file. Maybe that cures it.

No. You’re not alone. I see the same. Every time I restart openHAB I have to re-select the country …

Curious to hear the results…