Hi Guys,
I have the following problem:
I have created a variable (var) across all rules. It will not be updated. Only once if I save the rules file. After that, the value stays that way.
What could be the problem?
Here is the code …
import org.joda.time.*
import org.openhab.core.library.types.*
var t__Dusk = (astro_Sonnenuntergang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli //<---this dosn't update. Keep the value all the time
rule "Rollläden herunterfahren"
when
Channel 'astro:sun:local:civilDusk#event' triggered END or
Time cron "0 30 21 * * ?" or
Time cron "0 0 21 * * ?"
then
if(now.getHourOfDay == 21 && now.getMinuteOfHour == 0)
{
//do something
}
else if(now.getHourOfDay == 21 && now.getMinuteOfHour == 30 )
{
//do something
}
else if(t__Dusk <= now().millis)
{
//do something
}
end
I guess that variables outside rules are only loaded once when the .rules file is loaded (it’s a constant). To solve this, you need to put the variable inside your rules (if you use it more than once) or use item.state instead. Note that if you decide to put the variable inside of your rule and you don’t let your code update the value, then you can use val instead of var.
import org.joda.time.*
import org.openhab.core.library.types.*
rule "Rollläden herunterfahren"
when
Channel 'astro:sun:local:civilDusk#event' triggered END or
Time cron "0 30 21 * * ?" or
Time cron "0 0 21 * * ?"
then
val t__Dusk = (astro_Sonnenuntergang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
if(now.getHourOfDay == 21 && now.getMinuteOfHour == 0)
{
//do something
}
else if(now.getHourOfDay == 21 && now.getMinuteOfHour == 30 )
{
//do something
}
else if(t__Dusk <= now().millis)
{
//do something
}
end
or
import org.joda.time.*
import org.openhab.core.library.types.*
rule "Rollläden herunterfahren"
when
Channel 'astro:sun:local:civilDusk#event' triggered END or
Time cron "0 30 21 * * ?" or
Time cron "0 0 21 * * ?"
then
if(now.getHourOfDay == 21 && now.getMinuteOfHour == 0)
{
//do something
}
else if(now.getHourOfDay == 21 && now.getMinuteOfHour == 30 )
{
//do something
}
else if((astro_Sonnenuntergang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli <= now().millis)
{
//do something
}
end
Just to provide a few observations and reiteration of what everyone else has said.
You are using OH 2. Those imports are not required and in fact should be removed.
As has been described, that line only gets evaluated when the .rules file loads. As astro_Sonnenuntergang changes, t__Dusk remains the same. Beyond that, putting this into a global variable doesn’t really buy you much at all beyond a few keystrokes. Why not replace
It’s not that much longer or harder to understand and it eliminates the need for the global variable.
Or, if you care about time periods like this in more than one Rule, consider using Design Pattern: Time Of Day. Then all of your Rules that care about the time can look like:
rule "Rollläden herunterfahren"
when
Item vTimeOfDay changed to DUSK or // starts at civil dusk
Item vTimeOfDay changed to EVENING or // starts at 21:00
Item vTimeOfDay change to NIGHT // starts at 21:30
then
switch(vTimeOfDay.state.toString) {
case "EVENING": {
// do something
}
case "NIGHT": {
// do something
}
case "DUSK": {
// do something
}
}
end
Then if you change when you want stuff to happen you only need to adjust it in one Rule instead of a bunch. And there is no need for the global variable. And you can even start to do even more interesting stuff.
Yes I would like to use it in several rules.
I have solved it now …
var Number st__vorDusk = 0
var Number st__nachDawn = 0
var Number t__Dusk = 0
rule "Update Variable"
when
Time cron "0 0 0 * * ?"
then
st__nachDawn = now.isAfter((astro_Sonnenaufgang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
st__vorDusk = now.isBefore((astro_Sonnenuntergang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
t__Dusk = (astro_Sonnenuntergang.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
end
That won’t work because astro doesn’t recalculate the new times until at least 30 seconds after midnight. Your variables will be set to the previous day’s times.
And yet you ignored the alternative and many would consider better approaches to do instead of global variables?
You do realize that once again, that will only get evaluated at the time of your midnight rule run? (“now” wil be midnight plus a tiny bit) And the variable will stay as it is until the next midnight.