Port JSR223 bundle to openHAB 2

This is basically the only reason I have not moved to OH2.
Oh and the crappy thing generation through the UI.
I really hope there will be a textual thing definition approach again.

The PR ā€œscriptable automation #1783ā€ was merged in April. But I couldnā€™t find any documentation. Is it usable in OpenHab2 already? Iā€™m eager to finally migrate to OH2.

First installation instructions for very early adapters: :slight_smile:

Please use in nightly builds after 2017/05/30, because there was a problem with rules id definition before: https://github.com/eclipse/smarthome/pull/3534

1 Like

Nice, thanks for the link. Somehow I didnā€™t find it.

Later a complete documentation will be found here: http://docs.openhab.org/configuration/rules-ng.html

@lewie thank you for the link on the JSR223 integration. Not being fully into the underbelly of OH2, would you please clarify the section ā€œInstall in IDEā€ (especially the file path of the launch config) and section ā€œJythonā€ (especially what Main page of launch config is and where to put the jython jar)?

Thank you very much in advance!

Hello,

I was wondering - is there any plan when this makes its way to stable?

Hi,

Iā€™m using the openhab-2.2.0-snapshot docker image (from today, 9.7.17), but my example.js is not executed.
The misc-ruleengine shows as installed in PaperUI and my example.js (from the documentation) exists in conf/automation/jsr223, but it is not executed and I canā€™t find any log-entry concerning the jsr rule-engine in the logs.
Am I missing something?

Thanks,
Axel

@aruder77, when you get no log entries, misc-ruleengine seams not to be started.

At startup you MUST see this log entry [.internal.GenericScriptEngineFactory] - Activated scripting support for ECMAScript. It shows if misc-ruleengine is started and any *.js files are found.

For testing, do /etc/init.d/openhab stop at bash, then search for start.sh in openHAB folders and start openHAB with sh start.sh. (Now, after openHAB Logo, your prompt goes blue, and looks like openhab>)
Then you can do a openhab>list at openHAB console there you should see a block like:

ā€¦
185 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation API
186 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation commands
187 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Core
188 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Module Core
189 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Media Modules
190 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Module Script
191 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Script Globals
192 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Script RuleSupport
193 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Module Timer
194 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation GSON Parser
195 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation Providers
196 | Active | 80 | 0.9.0.201706270841 | Eclipse SmartHome Automation REST API
ā€¦

If yes, go to live log with openhab>log:tail (later left live console with ctrl-c). Open example.js in your editor and change anything (add a blank or so) and save back in conf/automation/jsr223. At that moment, when example.js is saved. In live console you should see entries like:

ā€¦
09:06:57.369 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script ā€˜example.jsā€™
09:06:57.408 [INFO ] [smarthome.event.RuleAddedEvent ] - Rule ā€˜rule_1ā€™ has been added.
09:06:57.409 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: INITIALIZING
09:06:57.412 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: IDLE
09:07:00.006 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: RUNNING
09:07:00.014 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: IDLE
Hello World from JavaScript
09:07:15.016 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: RUNNING
09:07:15.016 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: IDLE
Hello World from JavaScript
09:07:30.013 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: RUNNING
09:07:30.013 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: IDLE
ā€¦

I hope this can help. :slight_smile:

1 Like

Thanks a lot for your quick and detailed answer!
With your help I could track down the problem. I was actually mounting the automation scripts in the wrong location, so that they were not picked up. The example.js is now loaded, but there still seems to be a minor problem:
Error during evaluation of script ā€˜file:/openhab/conf/automation/jsr223/example.jsā€™: ReferenceError: ā€œSimpleRuleā€ is not defined in at line number 6

I will try a groovy/jython script and see how it goes.

Thanks again!

Can you provide some documentation what you have been doing so I can follow up?
This would be very helpful.

@Spaceman_Spiff and @aruder77, it is still an early rather experimental stage. Here we are currently collecting information for the later documentation. As a very early adapter there you can find links to examples too.

I hope you have so much fun as me! :thumbsup:

PS: You are of course welcome to help us improve the documentation!

I have an open PR with openhab-docs to document the language-independent aspects of the JSR223 support with additional documentation specific to Jython. Iā€™m not getting much feedback so any participation there is welcome and may speed up the process of publishing the material. After the PR is merged it will provide a place to add further details for Javascript and Groovy.

2 Likes

@lewie, @Spaceman_Spiff and @aruder77 and others. The OH2 JSR223 documentation is now available at:

http://docs.openhab.org/configuration/jsr223.html

Thanks to @ThomDietrich and @Benjy for the PR reviews.

3 Likes

Thanks a lot @steve1 and @lewie for the help and the documentation!
Unfortunately I still canā€™t get it to work up to now. I tried JS, jython and groovy, but apparently my presents arenā€™t loaded correctly.
With the examples from the documentation, I get the following log entries:
2017-07-16 18:14:39.031 [INFO ] [.internal.GenericScriptEngineFactory] - Activated scripting support for Groovy
2017-07-16 18:14:40.390 [INFO ] [.internal.GenericScriptEngineFactory] - Activated scripting support for ECMAScript
2017-07-16 18:14:40.397 [INFO ] [.internal.GenericScriptEngineFactory] - Activated scripting support for python
2017-07-16 18:15:05.614 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'example.groovyā€™
2017-07-16 18:15:09.623 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script ā€˜file:/openhab/conf/automation/jsr223/example.groovyā€™: javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: automationManager for cl
ass: Script1
2017-07-16 18:15:09.637 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'example.pyā€™
2017-07-16 18:15:41.494 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script ā€˜file:/openhab/conf/automation/jsr223/example.pyā€™: NameError: name ā€˜SimpleRuleā€™ is not defined in at line number 5
2017-07-16 18:15:41.504 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'exampleJs.jsā€™
2017-07-16 18:15:46.060 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script ā€˜file:/openhab/conf/automation/jsr223/exampleJs.jsā€™: ReferenceError: ā€œSimpleRuleā€ is not defined in at line number 6

Iā€™m using @lewieā€™s snapshot version with ESH snapshotsā€¦
Any hint?
Thanks!

Yesterday I installed the nightly build (#986) and started playing with the jsr223 script support. I ended up with doing nothing else than downloading the jython standalone jar and place it in runtime/lib/ext. After that Python scripts started to work. Unfortunately it doesnā€™t work after a restart of openHAB. The log looks like this:

2017-07-17 15:41:35.607 [INFO ] [.internal.GenericScriptEngineFactory] - Activated scripting support for python
2017-07-17 15:41:35.624 [INFO ] [.internal.GenericScriptEngineFactory] - Activated scripting support for ECMAScript
2017-07-17 15:42:21.265 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/opt/openhab/openhab-2.x/conf/automation/jsr223/sample_trigger.py': NameError: name 'SimpleRule' is not defined in <script> at line number 5

If I touch the file sample_trigger.py everything starts to work:

2017-07-18 07:49:20.575 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'sample_trigger.py'
2017-07-18 07:50:17.723 [INFO ] [clipse.smarthome.automation.examples] - JSR223 [Jython]: Alarm watchdog was updated!
2017-07-18 07:51:17.691 [INFO ] [clipse.smarthome.automation.examples] - JSR223 [Jython]: Alarm watchdog was updated!

Any ideas?

BTW. This feature looks absolutely awsome, Just what I have been waiting for :slight_smile:

Thanks!

By the way the script looks like this:

from org.slf4j import LoggerFactory
scriptExtension.importPreset("RuleSupport")
scriptExtension.importPreset("RuleSimple")

class myRule(SimpleRule):
    def __init__(self):
        self.triggers = [
             Trigger("MyTrigger", "core.ItemStateUpdateTrigger", 
                    Configuration({ "itemName": "Alarm_IsAlive"}))
        ]
        
    def execute(self, module, input):
	LoggerFactory.getLogger("org.eclipse.smarthome.automation.examples").info("JSR223 [Jython]: Alarm watchdog was updated!")
        #events.postUpdate("TestString2", "some data")


sRule = myRule()
#sRule.setTriggers([Trigger("aTimerTrigger", "timer.GenericCronTrigger", Configuration({"cronExpression": "0/15 * * * * ?"}))])

automationManager.addRule(sRule)

I have also tried to put the jython jar in runtime/lib/boot instead, but that doesnā€™t make any difference at all.

Hi,

I know very little of jython, only ā€œsomeā€ python (I write my py procedural :scream:)ā€¦so I have a couple of questions about this:

can I use external python libraries (3rd party) in these jython scripts? (like ā€œimport blablaā€) ?
How does scope work between scripts? if I create a ā€œglobalā€ variable, would it ā€œpersistā€ every time the script runs? is the scope shared between scripts, as in, would a globally defined variable be accessible between scripts?

Yes, you can either create your own Python modules that live outside of automation/jsr223 or use third-party libraries. Pure Python libraries will often work with Jython.

You can also use third-party Java libraries. For example, Iā€™ve been experimenting with integration of the Esper CEP (Complex Event Processing) engine.

Typically, the JSR223 scope is not changed by a script. When a script is reloaded it is completed recreated so no variables that live in that script ā€œmoduleā€ will survive. Also, script-level variables cannot be shared with other scripts. However, there are ways to share data between scripts and have the data survive script reloads. I do this by defining a module outside the automation\jsr223 directory (I use the Jython python.path JVM argument to specify this external library directory location).

Only scripts in the automation\jsr223 directory are reloaded automatically. Python modules outside that directory are imported/loaded the normal Python way.

When those external module are imported there is only one instance of the module shared among the scripts. If you define variables in that module they can be shared and their lifespan is not affected by script reloading (other than the first import which loads the module). Note that if you are changing the implementation of an external module, youā€™ll need to use reload(<module.name>) to explicitly reload it since that will not happen automatically. Again, only scripts are reloaded automatically.

Although I said a script doesnā€™t typically change the JSR223 scope, it is possible to do it. You can use Jython to create a custom ā€œpresetā€, similar to ā€œRuleSimpleā€, that will inject additional objects into the JSR223 scope. Those objects will typically have a lifespan not affected by script reloads.

2 Likes

Thatā€™s odd. It sounds like it is possibly a OSGI bundle load ordering issue or something like that. Iā€™m using a development environment for testing and Iā€™m also using a different technique to add the Jython library to the classpath and I donā€™t use the standalone JAR. So, lots of differences.

Maybe @smerschjo can comment, but one possibility is that the scripts are initially being loaded before the scope providers have run (which provides the ā€˜SimpleRuleā€™ class to the scope). I am a bit short on time right now (packing for a move) but at some point Iā€™ll install a snapshot build and try to reproduce your issue.

Also, which operating system are you using? Iā€™m running on an RPi3 (Linux) and I configured Jython in the /etc/default/openhab2 file.

EXTRA_JAVA_OPTS=-Xbootclasspath/a:/home/pi/jython2.7.0/jython.jar \
  -Dpython.home=/home/pi/jython2.7.0 \
  -Dpython.path=/etc/openhab2/lib/python