[SOLVED] Multiple 'when' statements, (AND/OR)

Presumably, thats done like so;

# Configuration folders (must exist as a subdirectory of "configurations"; the value
# tells the number of seconds for the next scan of the directory for changes. A
# value of -1 deactivates the scan).
# A comma separated list can follow after the refresh value. This list defines a filter
# for valid file extensions for the models.
folder:items=10,items
folder:sitemaps=10,sitemap
folder:scripts=10,script
folder:persistence=10,persist
folder:rules=60,rules

Hmmm, progress?

22:25:21.897 [DEBUG] [m.r.internal.engine.RuleEngine:264  ] - Executing startup rule 'Get time period for right now'
22:25:21.933 [INFO ] [g.openhab.model.script.Started:53   ] - System started rule starting
22:25:22.397 [INFO ] [g.openhab.model.script.Started:53   ] - It is Twilight!

Looks like its working. You probably don’t need to make the polling period 60 seconds, 15 would probably be plenty.

1 Like

Seems to be working now, I’ve bounced it again this morning just to ensure it wasn’t persistence or something that caused it to work last night.

Thanks for sticking with my @rlkoshak, really appreciate it!

I am trying to setup something similar. I’m only trying to do it with a night & day switch, not the twilight and morning. I have the night and day switches setup and I can use them in rules. I am trying to get them to run at start-up. I am getting the following error message:
Error during the execution of startup rule ‘Get time period for right now’: Cannot cast org.openhab.core.types.UnDefType to org.openhab.core.library.types.DateTimeType
Here are my items and rule:

Switch   Day
Switch   Night   
Switch Sunrise_Event   {astro="planet=sun, type=rise, property=start, offset=30"}
Switch Sunset_Event    {astro="planet=sun, type=set, property=end, offset=-30"}
String Sunrise_Sunset  "Sunrise / Sunset [%s]"    <sun>
DateTime Sunrise_Time  "Sunrise [%1$tH:%1$tM]"    <sun>    {astro="planet=sun, type=rise, property=start"}   
DateTime Sunset_Time   "Sunset [%1$tH:%1$tM]"     <sun>    {astro="planet=sun, type=set, property=end"}

rule "Get time period for right now"
when
    System started
then
    val sunrise = new DateTime((Sunrise_Time.state as DateTimeType).calendar.timeInMillis)
    val sunset = new DateTime((Sunset_Time.state as DateTimeType).calendar.timeInMillis)
    if(now.isAfter(sunrise) && now.isBefore(sunset)) {
        Day.sendCommand(ON)
        Night.sendCommand(OFF)
    }
    else if(now.isAfter(sunset) && now.isBefore(sunrise)) {
        Day.sendCommand(OFF)
        Night.sendCommand(ON) 
    }
end

Do you have persistence installed and confgured to restoreOnStartup your Sunrise_Time and Sunset_Time Items? If not your startup rule is probably running before the Astro binding is recalculating the times for the current day.

Do I need persistence to run this rule? I ended up getting rid of the rrd4j persistence. I do have the myopenhab persist, but I’m thinking of uninstalling that too.

Yes. Otherwise your sunrise and sunset time items will be undefined at startup.

OK, I tried to setup db4o on my system. I copied the jar file to the right directory, edited db40 settings in my openhab.cfg and made it the default persistence and created the persist file. I am gettings this error message:

2016-01-19 06:13:00.035 [ERROR] [org.quartz.core.JobRunShell   ] - Job db4o.everyMinute threw an unhandled Exception:
java.lang.NullPointerException: null
        at org.openhab.core.persistence.internal.PersistItemsJob.hasStrategy(PersistItemsJob.java:73) ~[na:na]
        at org.openhab.core.persistence.internal.PersistItemsJob.execute(PersistItemsJob.java:52) ~[na:na]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-all-2.1.7.jar:na]
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-all-2.1.7.jar:na] 
2016-01-19 06:13:00.041 [ERROR] [org.quartz.core.ErrorLogger   ] - Job (db4o.everyMinute threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
        at org.quartz.core.JobRunShell.run(JobRunShell.java:224) ~[quartz-all-2.1.7.jar:na]
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-all-2.1.7.jar:na]
Caused by: java.lang.NullPointerException: null
        at org.openhab.core.persistence.internal.PersistItemsJob.hasStrategy(PersistItemsJob.java:73) ~[na:na]
        at org.openhab.core.persistence.internal.PersistItemsJob.execute(PersistItemsJob.java:52) ~[na:na]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-all-2.1.7.jar:na]
        ... 1 common frames omitted

Here is my persist file:

Strategies {
    everyMinute : "0 * * * * ?"
    everyHour 	: "0 0 * * * ?"
    everyDay	: "0 0 0 * * ?"
    default = everyChange
}
Items {
    // persist everything when the value is updated, just a default, and restore them from database on startup
    * : strategy = everyChange, restoreOnStartup

    // next we define specific strategies of everyHour for anything in the Temperature group, and and every minute       for Humidity
    Temperature* : strategy = everyHour
    Humidity* : strategy = everyMinute

    // alternatively you can add specific items here, such as
    //Bedroom_Humidity,JamesInOffice : strategy = everyMinute
        Sunrise_Time : strategy = everyminute, restoreOnStartup
        Sunset_Time : strategy = everyminute, restoreOnStartup
}

Here is my rules file for Sunrise/Sunset:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
import org.java.math.*

////////////////////////////////////////////////////////////////////////////
// Rule:    Initialize system on startup / rule update
// Purpose: Initialize the system
rule "Initialize system on startup / rule update"
when
    System started
then
    var DateTimeType sunrise = new DateTimeType(getAstroSunriseStart(now.toDate, 42.5803, 83.0303))
    var DateTimeType sunset = new DateTimeType(getAstroSunsetStart(now.toDate, 42.5803, 83.0303))
    Sunrise_Time.postUpdate(sunrise)
    Sunset_Time.postUpdate(sunset)
end

////////////////////////////////////////////////////////////////////////////
// Rule:    Sunrise/Sunset changed
// Purpose: Update Sunrise_Sunset string with the updated sunrise and sunset
//          times. The Sunrise_Sunset string is used to display both the
//          sunrise time and sunset time on a single line in the GUI
rule "Sunrise/Sunset changed"
when
    Item Sunrise_Time changed
    or Item Sunset_Time changed
then
    var DateTime sunrise = new DateTime((Sunrise_Time.state as DateTimeType).calendar.timeInMillis)
    var DateTime sunset = new DateTime((Sunset_Time.state as DateTimeType).calendar.timeInMillis)
    Sunrise_Sunset.postUpdate(String::format("%02d:%02d / %02d:%02d", sunrise.getHourOfDay(), s
sunrise.getMinuteOfHour(), sunset.getHourOfDay(), sunset.getMinuteOfHour()))
         end

    rule "Day"
    when
        Item Sunrise_Event received update
    then
    Night.sendCommand(OFF)
    Day.sendCommand(ON)
end

rule "Night"
when
    Item Sunset_Event received update
then
    Day.sendCommand(OFF)
    Night.sendCommand(ON)
end

rule "Get time period for right now"
when
    System started
then
    val sunrise = new DateTime((Sunrise_Time.state as DateTimeType).calendar.timeInMillis)
    val sunset = new DateTime((Sunset_Time.state as DateTimeType).calendar.timeInMillis)
    if(now.isAfter(sunrise) && now.isBefore(sunset)) {
        Day.sendCommand(ON)
        Night.sendCommand(OFF)
    }
    else if(now.isAfter(sunset) && now.isBefore(sunrise)) {
        Day.sendCommand(OFF)
        Night.sendCommand(ON) 
    }
end 

Can you see anything I’m doing wrong?

Do you indeed have a Temperature and Humidity group? That is the only thing I can think of that could be wrong. Also, since you are using db4o it is not that important to use the everyMinute strategy like you do with rrd4j and since by default everything gets saved every change and restoreOnStartup I would remove the lines for Sunrise_Time and Sunset_Time.

OK, I cleaned up the persist file. I didn’t have temperature and humidity group. I rebooted and didn’t see that long error message. I did see the “Error during the execution of startup rule ‘Get time period for right now’: Cannot cast org.openhab.core.types.UnDefType to org.openhab.core.library.types.DateTimeType”. I rebooted again and that error is not coming up anymore. So it looks like I’m error free. My sitemap comes up with the “Day” light on. There is one problem though. I have a line on my sitemap for “Sunrise/Sunset Time”. It should be showing something like this 7:56 / 17:28. I is showing 20:55 / 06:21. Do you see anything that could be messing that up?

Edit: I rebooted again to double check and that UnDefType error came up again.

Do you have multiple rules and items files? If yes it is possible that your rules file is loading and executing before all your .items files or persistence has finished loading. That would explain the intermittent appearance of the error. Change the polling times in your openhab.cfg so your rules get loaded last at startup. I use these values:

folder:items=20,items
folder:sitemaps=26,sitemap
folder:rules=30,rules
folder:scripts=24,script
folder:persistence=22,persist

Change your Sunrise_Sunset.postUpdate line to:

Sunrise_Sunset.postUpdate(String::format("%0$tr / %1$tr", sunrise, sunset)

When doing String::format, the “%x” part is a reference to which argument you are referencing and the $tr means the argument is a DateTime object and to format it as HH:MM am/pm. If you want the time in 24 hour format use $tR instead. The full documentation for format is here.

I entered the replacement line and Openhab designer had a problem with it. I needed to add a extra parentheses at the very end of it. I hope thats where it went.
After I entered in the replacement line my sun.rules did a refresh and I got the following error:
Error during the execution of rule ‘Sunrise/Sunset changed’: r != org.joda.time.DateTime
I

Yes, that is where it goes.

Oh wait… try the following:

Sunrise_Sunset.postUpdate(String::format("%0$tr / %1$tr", (Sunrise_Time.state as DateTimeType), (Sunset_Time.state as DateTimeType)))

When I enter that line, the two lines directly above it get errors. I think you have to use the words “sunrise” and “sunset” somewhere in the line. I noticed that I am using the words sunrise and sunset in two different rules. Can that cause some type of conflict. rule “Sunrise/Sunset changed” and rule “Get time period for right now”

Errors (i.e. red) or just a warning that they are not used anywhere (i.e. yellow). The warnings are not a problem. You can ignore them and once it works delete those two lines.

The line that you use to populate Sunrise_Sunset has to be the same in both places.

We don’t want to use sunrise and sunset because they are the wrong type to work with $tr.

But, are you using both the Astro binding and the Astro action? Others have reported that they are not compatible. You can only use one or the other.

I have both. I read somewhere I needed it to be able to run it at startup. Is that true?
They were warnings that they were not used anymore. I get this error message when I change the one line:
Error during the execution of rule ‘Sunrise/Sunset changed’: r != org.openhab.core.library.types.DateTimeType

I’m still getting those strange sunrise/sunset times on my sitemap. Here are the polling times I have:
folder:items=20,items
folder:sitemaps=26,sitemap
folder:rules=40,rules
folder:scripts=24,script
folder:persistence=22,persist

There are two separate errors. One is the UnDef error which the polling times addresses. The other is the times on the sitemap.

You should uninstall one or the other. I recommend unibstalling the action and just use the binding. I have know idea what “run it at startup means”.

Please post you items, rules, and sitemap as they are now again.

OK. I removed the astro action binding. I removed the 2 lines in the Rule “Sunrise/Sunset changed” and added your line. I also changed the Items DateTime Sunrise_Time and DateTime Sunset_Time. Do they look right? rebooted and there were no errors so far. The sunrise/sunset on the sitemap is still messed up, but all my rules based on sunrise and sunset still appear to be running on time. Here are the items, rules and sitemap. My Openhab version is now 1.8. I noticed some of my bindings are 1.7. Should they all be updated to 1.8 versions? db4o binding is 1.7, Astro is 1.8

Switch   Day
Switch   Night
Switch Sunrise_Event   {astro="planet=sun, type=rise, property=start, offset=30"} 
Switch Sunset_Event    {astro="planet=sun, type=set, property=end, offset=-30"}
String Sunrise_Sunset  "Sunrise / Sunset [%s]"    <sun>
DateTime Sunrise_Time  "Sunrise [%0$tr]"    <sun>    {astro="planet=sun, type=rise, property=start"}
DateTime Sunset_Time   "Sunset [%1$tr]"     <sun>    {astro="planet=sun, type=set, property=end"}


import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
import org.java.math.*

////////////////////////////////////////////////////////////////////////////
// Rule:    Initialize system on startup / rule update
// Purpose: Initialize the system
rule "Initialize system on startup / rule update"
when
    System started
then
    var DateTimeType sunrise = new DateTimeType(getAstroSunriseStart(now.toDate, 42.5803, 83.0303))
    var DateTimeType sunset = new DateTimeType(getAstroSunsetStart(now.toDate, 42.5803, 83.0303))
    Sunrise_Time.postUpdate(sunrise)
    Sunset_Time.postUpdate(sunset)
end

////////////////////////////////////////////////////////////////////////////
// Rule:    Sunrise/Sunset changed
// Purpose: Update Sunrise_Sunset string with the updated sunrise and sunset
//          times. The Sunrise_Sunset string is used to display both the
//          sunrise time and sunset time on a single line in the GUI
rule "Sunrise/Sunset changed"
when
    Item Sunrise_Time changed
    or Item Sunset_Time changed
then
    Sunrise_Sunset.postUpdate(String::format("%0$tr / %1$tr", (Sunrise_Time.state as DateTimeType),       
(Sunset_Time.state as DateTimeType)))
end

rule "Day"
when
    Item Sunrise_Event received update
then
    Night.sendCommand(OFF)
    Day.sendCommand(ON)
end

rule "Night"
when
Item Sunset_Event received update
then
    Day.sendCommand(OFF)
    Night.sendCommand(ON)
end

rule "Get time period for right now"
when
    System started
then
    val sunrise = new DateTime((Sunrise_Time.state as DateTimeType).calendar.timeInMillis)
    val sunset = new DateTime((Sunset_Time.state as DateTimeType).calendar.timeInMillis)
    if(now.isAfter(sunrise) && now.isBefore(sunset)) {
        Day.sendCommand(ON)
        Night.sendCommand(OFF)
    }
    else if(now.isAfter(sunset) && now.isBefore(sunrise)) {
        Day.sendCommand(OFF)
        Night.sendCommand(ON) 
    }
end 

Frame label="Date, Time and Weather" {
  Text item=Sunrise_Sunset
  Text item=Date icon="calendar"
  Text item=Temperature icon="temperature"
  Text item=Humidity icon="climate"
  Switch item=Night	
  Switch item=Day
  }
}

Follow up:
I noticed is that my db4o persistence directory is not filling up with item states like my rr4dj persistence use to do. I see the db4o persistence loading at bootup. I changed my Astro binding back to 1.7 to see if that would fix anything. It didn’t. Received this error message this morning(Thur, 1/21) : [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Sunrise/Sunset changed’: r != org.openhab.core.library.types.DateTimeType .