Time span for if conditions in rules (nowTime and Astro channels)

Hi fellow openHAB community,

actually I use for some of my rules if conditions e.g. like that:

if(now >= now.with(LocalTime.of(9, 30)) && now < now.with(LocalTime.of(22, 50))) {

Now, I would like to define a time based if condition between MIDNIGHT and the given time Sunrise start time out of Astro binding. So basically and simple thought, re-use the value of an already existing item:


DateTime Sunset_Start   "Sonnenuntergang [%1$tH:%1$tM]"                      {channel="astro:sun:local:set#start"}
if(now >= now.with(LocalTime.MIDNIGHT) && now < now.with(Sunset_Start)) {

Could somebody give a kickstart here? Is the time format same between Java getTime and the channels e.g. Astro binding?

Thanks in advance for any answer :slight_smile:

My gear: openHABian with openHAB 4.0.3.

If you are not already familiar with programming I recommend giving Blocky a try. It’s much more obvious how to code stuff like this and harder to make the sort of mistake you are making here.

Sunset_Start is an Item. An Item has all sorts of properties like it’s name, tags, names of the Groups it belongs to, etc. It is not a ZonedDateTime and it cannot be use as such. However, it does carry a state and that state does carry a ZonedDateTime.

Assuming that the >= and < work as expected

if(now >= now.with(LocalTime.MIDNIGHT) && now < (Sunset_Start.state as DateTimeType).zonedDateTime)

In Blockly it would look like

We are only testing the times so it doesn’t matter what the date part is set to.

In JS Scripting there are a lot of utilities to make working with date times much easier.

if(now.isBetweenDateTimes(time.toZDT("00:00"), time.toZDT(items.Sunset_Start)))

jRuby has similar helpers to make dealing with date times easier.

1 Like

@rlkoshak Thanks for you helpful and comprehensive answer.

Sure, I am not full time coder and just code occasional on my openHAB. So, on every occasion its a restart and yes, keeping existing already found solutions resp. snippets.

Here just haven’t found a hint, how to handover Item value into time span, will not ask a second time for that info :slight_smile:

So, yes, I guessed I have to use the channel value covered by an Item and cannot use the channel directly in my if condition time span …

Well, as said, anyone else might might tend stay on already working solutions, but I think I could use something like that, reading ZonedDateTime documentation.

if(now.isAfter(LocalTime.MIDNIGHT) && now.isBefore(Sunset_Start.state as DateTimeType).zonedDateTime)

But its not 100% the same, rather “>” and “<” … no idea how to use “isEqual” or “isAfter” in one term here …

Another great reason to consider using Blockly.

If you don’t understand the code you can’t maintain the code. Blockly is very easy to understand.

The term “channel” and “item” have a specific meaning in OH. Given those meanings this sentence doesn’t really make sense.

Things represent devices in OH. In the case of Astro, it’s like a device. Things have Channels. Channels represent a value or a way to control a device. Channels are Linked to Items.

Everything else in OH mostly works with Items.

In your original attempt, you were attempting to use the Item. But an Item isn’t a DateTime. You can’t just pass an Item to now and expect it to work. You need to get at the Item’s state and even then you need to convert that sate to a ZonedDateTime.

now is already a ZonedDateTime.

Does that matter? All you are missing is one nanosecond by not using >= as opposed to isAfter. If now is midnight plus one nanosecond, isAfter will return true. The chances that you will run this if statement when it is exactly midnight is vanishingly small.

And the only reason I said assuming that the > works is it has been a very long time since I’ve used Rules DSL and I’m pretty sure that didn’t work at some point. Maybe it works now. Maybe it always worked. Maybe it’s not throwing errors but also not doing what you think it is.

Gave it a quick look, honestly would it take me more time to learn that, compared to polishing my scripting values.

Regarding your guessing about my capabilites, I am not new in coding, started almost 30 years ago as Cobol programmer, but long time out of that business. Since back then I needed to write many shell, various flavors and complexity, Perl & Python scripts for my customer projects … it is just not my main business. So could be, I need to re-learn/-refresh e.g. Perl again the next months, as my last business case for that has been back in 2016 …

No, I was not attempting to, I didn’t even try that line on my gear. I wrote it just that way, knowing it is wrong, basically as a sketch to explain what I am looking for. The hint how to handover the Item value into my time span if condition. Thanks again for your great support here :+1:t2:

The line with “>=” and “<” and your valuable input seems to work, reality test needs to follow:

if(now >= now.with(LocalTime.MIDNIGHT) && now < (Sunset_Start.state as DateTimeType).zonedDateTime) {

I gave the other notation also a try:

if(now.isAfter(now.with(LocalTime.MIDNIGHT)) && now.isBefore(Sunset_Start.state as DateTimeType).zonedDateTime) {

But with that forces an error:

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'shellytime-6' failed: An error occurred during the script execution: Could not invoke method: java.time.chrono.ChronoZonedDateTime.isBefore(java.time.chrono.ChronoZonedDateTime) on instance:

If you don’t know how your current scripts work, it probably would not take more time. The biggest advantage is it’s basically impossible to make a syntax error.

Case in point…

You have missmatched parens.

now.isBefore((Sunset_Start.state as DateTimeType).zonedDateTime) {

You need to scope the cast to DateTimeType to get at zonedDateTime and you want to pass that to isBefore.

1 Like

You might want to try jruby.

if Time.now.between?(LocalTime::MIDNIGHT, Sunset_Start.state)
1 Like

Well, that is the fun at all for me, it is mesmerizing like puzzling Sudoku … I need to deliver perfection all day long in a tight corset of rules and responsibilities in my business. No need in my private environment, everything is just nice to have, no must at all … :slight_smile:

Thanks for your great support, both notations work great, have tested and finalize last night … :+1:

Btw. all the effort just for one light on a specific location, adopting daily routine added some dynamic … as said all is just nice to have, better having than needing … :sweat_smile:

Thanks for the hint, maybe I give a try one day :+1: