OH2 AstroBinding in Rule

I want to use the DateTime of the astro binding to calculate stuff with it.
How do i get this information?
Some like this:
import import org.joda.time.*
var DateTime dtDawnStart = new DateTime(channel=“astro:sun:home:civilDawn#start”)

Using OH2.0.0b5
An item with this definition works:
DateTime dtDawnStart “Sonnenaufgang [%1$tH:%1$tM]” { channel=“astro:sun:home:civilDawn#start” }

I need this for init calculations before all Channels bind to the items.

Thank you for your help.

You should be able to reference your item in the rule.

(dtDawnStart.state as DateTimeType)

And, for example, if you want to format it for display, you could do something like this.

import java.text.SimpleDateFormat

...

    var SimpleDateFormat df = new SimpleDateFormat( "MM/dd/YYYY hh:mm a" )
    var String validAt = df.format( (dtDawnStart.state as DateTimeType).calendar.timeInMillis )

Hi Mark,

thanks for your help.
i already have a rule for calculating day/night based on items:

import org.joda.time.*
import org.openhab.core.library.types.*

rule "Init_Daylight"
when
	System started
then
	var DateTime dawnStart = new DateTime((dtDawnStart.state as DateTimeType).calendar.timeInMillis)
	var DateTime duskStart = new DateTime((dtDuskStart.state as DateTimeType).calendar.timeInMillis)
	
	if(now.isAfter(dawnStart) && now.isBefore(duskStart)){
		logInfo("initRule", "Es ist hell")
		nbDaylight.postUpdate(1)
	}else{
		logInfo("initRule", "Es ist dunkel")
		nbDaylight.postUpdate(0)
	}
end

But i gues: the system Trigger started runs directly after loading the models from file (.items, .sitemap, .rules, …) and before the channels get connected to the items.
That’s why i got an error with that rule:

Error during the execution of startup rule 'Init_Daylight': org.eclipse.smarthome.core.library.types.DateTimeType

The DateTimeType is not yet instantiatet. Further down, the log shows up the connection:

2017-01-26 09:38:23.824 [INFO ] [ding.astro.handler.AstroThingHandler] - Scheduled astro job-daily-sun at midnight for thing astro:sun:home
2017-01-26 09:38:24.263 [INFO ] [.astro.internal.job.AbstractDailyJob] - Scheduled astro event-jobs for thing astro:sun:home

Is there a way to get the channel start of group civilDawn of item sun of binding astro directly within a rule-then-block?

If I understand what you’re trying to do, you could use a timer to delay the execution of the statements in your then clause. Something like this:

var Timer timer = null

rule "Init_Daylight"
when
    System started
then
    if(timer == null) {
        timer = createTimer(now.plusSeconds(20)) [|
            logInfo("Init_Daylight", "Do Stuff")
            // Put your logic here
            timer = null   // reset the timer
        ]
    }
    else {
        logInfo("Init_Daylight", "Timer is already set.")
    }
end

Hi,

a good idea. This would be a warkaround, if it is really not possible to talk directly to the astro 2.0 binding. That would be my first goal.

For all others, banging their heads about that topic, here is another workaround, I found. It is mainly the snippet from above, where you get the astro infos from Items, which are connected to the astro channel. A soon, as they are connected, they will be writen. This change we will use as a Trigger.

import org.joda.time.*
import org.openhab.core.library.types.*

rule "Init_Daylight_by_DuskDawn"
when
	Item dtDawnStart changed OR
	Item dtDuskStart changed
then
	var DateTime globalDawnStart = new DateTime((dtDawnStart.state as DateTimeType).calendar.timeInMillis)
	var DateTime globalDuskStart = new DateTime((dtDuskStart.state as DateTimeType).calendar.timeInMillis)
	if(globalDuskStart != null && globalDawnStart != null){
		if(now.isAfter(globalDawnStart.plusMinutes(15)) && now.isBefore(globalDuskStart.plusMinutes(15))){
			logInfo("initRuleDuskDawn", "Es ist hell")
			nbDaylight.postUpdate(1)
		}else{
			logInfo("initRuleDuskDawn", "Es ist dunkel")
			nbDaylight.postUpdate(0)
		}
	}else{
		logInfo("initRuleDuskDawn", "Dusk or Dawn not yet set")
	}
end

with the item definition:

DateTime dtDawnStart "Sonnenaufgang [%1$tH:%1$tM]"     { channel="astro:sun:home:civilDawn#start" } 
DateTime dtDuskStart "Sonnenuntergang [%1$tH:%1$tM]"  { channel="astro:sun:home:civilDusk#start" }

Number nbDaylight "Tageslicht [MAP(sunlight.map):%s]"

Does anybody know, if there is a way to directly speak to the astro 2.0 binding within a rule?

I’m a little confused. You have an openhab2 tag but your imports are only valid for OH 1.x. You no longer need to import org.joda.time.* and org.openhab.core.* no longer exists (they all moved to another package) and they are all imported by default now. I’m not positive but that could be the source of your problem.

Rules only have access to Items (with the one exception of event triggers which reference the event channel of a Thing). See my Time of Day Design Pattern for details.

I do exactly this sort of thing in Time of Day and I’m not seeing the same problem you are. The one difference might be I use restoreOnStartup on all my Items. So when the system is starting the Items are initialized to whatever they were when OH went down and my Astro populated times are populated even if the binding has yet to recalculate the current times. Perhaps that is why I did not see the same problem.

In OH 1 there used to be an Asto Action that would let you call into the binding and get the times. I don’t see it in OH 2. You could install the 1.9 Astro Binding and Action through the compatibility layer (NOT through PaperUI, I tested it awhile back, the action won’t work).

Personally I would just set up restoreOnStartup on these Items or add a Thread::sleep/Timer to put off calculating the values for a little bit.

Presumably you have another rule that repopulates nbDaylight based on the event triggers? Otherwise nbDaylight will only ever be what ever time is was when OH restarted/Astro recalculates the times, and not reflect the actual current time of day.

Again, I direct you to the Time of Day example for one way to implement what you are after.

Hi,

thanks for sharing your time on my problem!
I will try to answer step by step.
Yes, I using OH2.0.0b5. I really can throw away the DateTimeType import. But if i kick the joda import, I get an error.

Rule 'Init_Daylight': An error occured during the script execution: null

Your statement helps a lot. now I know, that i definetly can NOT access the binding directly from the rule. Thanks.

Rules only have access to Items (with the one exception of event triggers which reference the event channel of a Thing).

I will give the restore config a try. It is the next on my list anyways.

The rule we are talking about is of course only the initialization. There are two other rules to switch daylightmode like:

rule "Abenddaemmerung"
when
    Channel 'astro:sun:home:civilDusk#event' triggered START
then
    logInfo("ruleCivilDusk", "Dusk detected, triggering 15 min Timer")
    timer = createTimer(now.plusMinutes(15)) [|
                nbDaylight.postUpdate(0)
            ]
    timer = null
end