Usage of PersistenceService in scripts in JSR223 binding

Hi all,

I successfully implemented rules as scripts in Groovy, using the JSR223 binding. Good stuff!

I’m now trying to implement a rule (still using Groovy) requiring data from a (queryable) persistence service.

Any suggestions on how to tackle this best? Is reuse of the existing PersistenceExtensions an option?

Tnx in advance!

Cheers,
Kristof
(Repost from Google Groups topic)

1 Like

Hi @kristofdk ,

I just extended the Wiki: https://github.com/openhab/openhab/wiki/Jsr223-Script-Engine
Now there are more Details about PersistenceExtensions and pre imported Classes

I’m not a Groovy specialist, implemented Java-script part for this Bundle. So this is untested:

//PersistenceExtensions
peExample = pe.historicState( ir.getItem(“Wintergarten_Temperatur”), DateTime.now().minusDays(7))
self.logger.info(“Wintergarten_Temperatur last Week: {}”, peExample)

Cheers,
Lewie

2 Likes

As simple as that?! :smiley: Cool, tnx!

I’ll give it a try in the upcoming days!

It would be really great if you could provide description on how to install this binding under windows and macos

I am really stuck.

Hello @martin_klimke,

for using Javascript, you only have to copy from “distribution-X.X.X-addons.zip” copy “org.openhab.core.jsr223-X.X.X.jar” to [PATH TO YOUR OPENHAB]\addons.

I have extended wiki for JavaScript examples:

Best
Lewie

Hi Helmut,

It great to have another commonly used language to be used in rules.
Thanks for this.
Could also please add the start.bat for windows.

regards Martin

I’m giving this another go and still no luck so some help is much appreciated!

The Groovy example on https://github.com/openhab/openhab/wiki/Jsr223-Script-Engine references PersistenceExtensions as a script global. However, this global isn’t available, so I don’t see how this example can correctly work. (cf. org.openhab.core.jsr223.internal.engine.scriptmanager.Script#initializeSciptGlobals).

I’m getting closer by instantiating PersistenceExtensions myself in the rule, but here I’m facing the error below which is specific to Groovy I guess. Additionally, this requires extending the classpath in the startup script.

groovy.lang.MissingMethodException: No signature of method: org.openhab.core.persistence.extensions.PersistenceExtensions.changedSince() is applicable for argument types: (org.openhab.core.items.GroupItem, org.joda.time.DateTime, java.lang.String) values: [Trap (Type=GroupItem, Members=1, State=ON), 2015-10-27T18:07:09.019+01:00, …]
Possible solutions: changedSince(org.openhab.core.items.Item, org.joda.time.base.AbstractInstant, java.lang.String), changedSince(org.openhab.core.items.Item, org.joda.time.base.AbstractInstant)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58) ~[groovy-all-2.4.5.jar:2.4.5]
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49) ~[groovy-all-2.4.5.jar:2.4.5]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141) ~[groovy-all-2.4.5.jar:2.4.5]
at AutoOffRule.execute(Script1.groovy:34) ~[na:na]
at org.openhab.core.jsr223.internal.engine.RuleExecutionRunnable.run(RuleExecutionRunnable.java:36) ~[na:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_31]

Rewrote my rule with Javascript (on Nashorn). Finally bumped against a similar error:

java.lang.RuntimeException: java.lang.NoSuchMethodException: None of the fixed arity signatures [(org.openhab.core.items.Item, org.joda.time.base.AbstractInstant)] of method org.openhab.core.persistence.extensions.PersistenceExtensions.changedSince match the argument types [org.openhab.core.items.GroupItem, org.joda.time.DateTime]
at jdk.nashorn.javaadapters.java.util.function.Consumer.accept(Unknown Source) ~[na:na]
at java.util.ArrayList.forEach(ArrayList.java:1249) ~[na:1.8.0_31]
at jdk.nashorn.internal.scripts.Script$^eval_.L:13(:14) ~[na:na]
at org.openhab.core.jsr223.internal.shared.Rule$$NashornJavaAdapter.execute(Unknown Source) ~[na:na]
at org.openhab.core.jsr223.internal.engine.RuleExecutionRunnable.run(RuleExecutionRunnable.java:36) ~[na:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_31]

Posted problem on StackOverflow for assistance: http://stackoverflow.com/questions/33419924/exception-when-calling-overloaded-static-method-using-jsr223

Hello @kristofdk,

Sorry you had to wait too long!! :frowning:

This Javascript Script works out of the box!

'use strict';

//not needed: load("nashorn:mozilla_compat.js");
//not needed: importPackage(org.openhab.core.jsr223.internal.shared);
//not needed: importPackage(org.joda.time);
//not needed: importPackage(org.joda.time.base);


var autoOffRule = new Rule() {
    getEventTrigger: function() {
        return [
            new TimerTrigger("0/15 * * * * ?"),
        ];
    }, 
    execute: function(event) {
        oh.logDebug("execute"+__LINE__,"autoOffRule");
        for each(var item in ir.getItems()) {
            oh.logDebug("execute"+__LINE__,"autoOffRule"+ item);
            if (item.getState() == OnOffType.ON) {
                //var dateTime = DateTime.now().minusMinutes(5);
                var dateTime = DateTime.now().minusSeconds(5);
                print(" #### 1. item changedSince:" + pe.changedSince(item, dateTime));
                if (!(pe.changedSince(item, dateTime))) {
                    print(" #### 2. Auto-off for " + item.getName());
                }
            }else{
                print(" #### 3. Name for " + item.getName());
            }
        }
    }
};

function getRules() {
    return new RuleSet([ autoOffRule ]);
}

Rgds
Helmut

Tnx for your reply!

I’m getting following exception when loading the provided script on my instance (openHAB 1.7.1 on jdk1.8.0_65/Windows 7).

Any idea what might be the cause? On which openHAB, JVM/JDK, OS are you running? Can you provide your start.bat/start.sh?

2015-11-24 18:02:04.582 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Available engines:
2015-11-24 18:02:04.612 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Oracle Nashorn
2015-11-24 18:02:04.612 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Groovy Scripting Engine
2015-11-24 18:02:04.612 [INFO ] [o.c.j.i.e.scriptmanager.Script] - Loading Script AutoOff.js
2015-11-24 18:02:05.142 [ERROR] [o.o.c.j.i.e.s.ScriptManager ] - script exception
javax.script.ScriptException: TypeError: interface org.openhab.core.jsr223.internal.shared.Rule is not a function in at line number 9
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467) ~[nashorn.jar:na]
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451) ~[nashorn.jar:na]
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403) ~[nashorn.jar:na]
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399) ~[nashorn.jar:na]
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150) ~[nashorn.jar:na]
at javax.script.AbstractScriptEngine.eval(Unknown Source) ~[na:1.8.0_65]
at org.openhab.core.jsr223.internal.engine.scriptmanager.Script.loadScript(Script.java:79) ~[bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.Script.(Script.java:67) ~[bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptManager.loadScript(ScriptManager.java:86) [bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptManager.loadScripts(ScriptManager.java:79) [bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptManager.(ScriptManager.java:68) [bundlefile:na]
at org.openhab.core.jsr223.internal.engine.Jsr223Engine.activate(Jsr223Engine.java:71) [bundlefile:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_65]
at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:235) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:345) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.Resolver.buildNewlySatisfied(Resolver.java:473) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.Resolver.enableComponents(Resolver.java:217) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.SCRManager.performWork(SCRManager.java:816) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.SCRManager$QueuedJob.dispatch(SCRManager.java:783) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.ds.WorkThread.run(WorkThread.java:89) [org.eclipse.equinox.ds_1.4.1.v20120926-201320.jar:na]
at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:70) [org.eclipse.equinox.util_1.0.400.v20120917-192807.jar:na]
Caused by: jdk.nashorn.internal.runtime.ECMAException: TypeError: interface org.openhab.core.jsr223.internal.shared.Rule is not a function
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:95) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:71) ~[nashorn.jar:na]
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124) ~[nashorn.jar:na]
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154) ~[nashorn.jar:na]
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253) ~[nashorn.jar:na]
at jdk.nashorn.internal.scripts.Script$^eval_.:program(:9) ~[na:na]
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228) ~[nashorn.jar:na]
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393) ~[nashorn.jar:na]
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446) ~[nashorn.jar:na]
… 25 common frames omitted

Cheers,
Kristof

My next really late reply,

Requirements, using Nashorn-Engine for JavaScript

  • Use openHAB >= Version 1.8.0
  • For loading Java classes with Nashorn you need to start openHab with the for java 8 preferred class-loader. Therefore add the -Dorg.osgi.framework.bundle.parent=ext parameter to your start.sh or start.bat.

Added this to the Documentation too.

Rgds
Helmut

Unfortunately, my setup fulfills both requirements: running on jdk1.8.0_65 and having the system property in my startup script.

Would you mind sharing your openHAB instance for that I can try it on my computer? Alternatively, I could share my instance as well.

You wrote you are using openHAB 1.7.1
You need openHAB 1.8.0, it is not released.
But you can load a SNAPSHOT from here:
https://openhab.ci.cloudbees.com/job/openHAB/

@kristofdk, does it work now?