Global variables in rules

Hi everybody

I’m trying to have these variables in global so I can use them in rules. It’s not working.
var month = now.getMonthOfYear
var day = now.getDayOfMonth
var hour = now.getHourOfDay
var minute = now.getMinuteOfHour
var seconds = now.getSecondOfMinute
var String date = (day +"/" + month + " " + hour + “:” + minute + “:” + seconds)

If I put them in a rule, they work.
Do you have any idea for me…

Thanks
Jose

You don’t say what the problem is so I’ll guess the variables don’t get updated from day to day.

When you define them as a global they only get set when the rule file gets loaded. Since typically the rules files are not reloaded every day theses globals become stale.

They are up to date in the rule because they get set as the rule executes.

Hi

When the rule is executed and the variable date is used i get an message
that the variable is not defined. Can i have a way that for each rule that
i need to have that date formatted i dont need to write all those
lines…somekind of a function?

Thanks
Jose

Maybe you could try something like this:

import java.util.Date
import java.text.SimpleDateFormat

var SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM HH:mm:ss" )

rule "myRule"
when
        Item Change changed
then
        var String ts = sdf.format( new Date() )
        // do somthing with "ts"
end

Any time the rule triggers, the string “ts” is updated to the actual date with the specified format.

SimpleDateFormat objects aren’t Thread safe, so this will break in unusual ways once there is concurrency using it (eg. Any concurrent Rules firing, Timers etc)

Joda’s DateTimeFormat is thread safe.

Hi

How do i accomplish the same thing?

Thanks

import org.joda.time.*
import org.joda.time.format.*

var SimpleDateFormater sdf = SimpleDateFormat::forPattern( "dd/MM HH:mm:ss" )

rule "myRule"
when
        Item Change changed
then
        var String ts = sdf.print( now.calendar.time )
        // do somthing with "ts"
end

Not tested, so proceed with caution.

Hi

I tried the last configuration and there is the error that I get:

Variable ‘sdf’ on rule file ‘default.rules’ cannot be initialized with
value ‘forPattern()’: An error occured during the
script execution: The name ‘forPattern()’ cannot be
resolved to an item or type.

Thanks
Jose

Hmmmm. The joda API says it is there but I can’t get Designer to find these classes. I wonder if OH uses an older version and these classes are in a different package or don’t exist.

I’ll continue to look but I don’t have a solution right now.

Rich

That’s not 100% true. Parsing with SimpleDateFormat is not thread safe, however you can format safely in multithread environment.

General question: Is there documentation available what predefined variables are available in rules?

I can see that the sample rules use “now” but I didn’t see any mention of that or any other variables in the documentation.

If someone can point out the right source file to me, I’m happy to contribute a few words about it. (I didn’t find the right class defining “now” using the github search.)

1 Like

Unfortunately I don’t think it is all in one place.

  • now is described on the Persistence wiki page and examples of its use is all over the place
  • receivedCommand and previousState are described in the Rules wiki page
  • Access to all of your items and groups, enumerated states (ON, OFF, OPEN, CLOSED, etc), and all actions is described on the Scripts wiki page

If there are more implicit or predefined variables I don’t know about them.

It is pretty clear to most everyone that the documentation needs a lot of help. I know one of Kai’s highest priorities is a rewrite of the quick start guide on the main openhab page. Given the number of installation problems I see on this forum I would agree. However, I also think the wiki is in pretty dire straights as well.

I’m not sure if there is an issue for this already, or if it needs an issue, but I do think some sort of coordinated effort should be made to restructure and clarify the documentation. One approach I’ve been meditating on is taking The Java Tutorial format with different trails that teach different aspects of openHAB through examples.

You may want to read the source code of the SimpleDataFormat.format(). The call to calendar.setTime(date) is particularly amusing

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/text/SimpleDateFormat.java#873

But the JavaDoc disclosure also works:

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Indeed. I was aware of this disclosure, but for some reason I was pretty sure it regards parsing only. But definitely I was wrong.
Thank you for pointing out my mistake, lesson learned. :smile:

Last time I checked, they’re not wrapping all of JodaTime, and it’s not in the OSGi CLASSPATH (equiv). Instead, they’re bundling it with one of the system EAR files, and exposing “now”. Once you get a handle to that, you can do most things, but it means you can’t just import any JodaTime entity.

At least, that’s the way I remember it, but it’s been about 8 months since I read that code.

Anyhow, it’s why this works (with no imports declared at all):

val String PATTERN = "dd/MM HH:mm:ss"

rule "Test2-Dates"
when
    Time cron "0/10 * * * * ?"
then
    var String ts = now.toString(PATTERN)
    logInfo("test2-dates", ts)
end