A praise for JSR223 with Jython (highly recommended)

@steve1. correct.
When I tried to get it running under MacOS, I indeed strugggled for sometime to change the start.sh because the Linux start.sh did not work.
Patching the start.bat in Windows exceeds my capabilities.

@martin_klimke: here is a working startup.bat. Just change the JYTHON_HOME accordingly.
It also references “configurations/scripts/lib” as a import/library folder where you can write library functions.

@echo off

:: set path to eclipse folder. If local folder, use '.'; otherwise, use c:\path\to\eclipse
set ECLIPSEHOME=server

:: set ports for HTTP(S) server
set HTTP_PORT=8080
set HTTPS_PORT=8443
set JYTHON_HOME=c:\Progs\jython2.7.0
 
:: get path to equinox jar inside ECLIPSEHOME folder
for /f "delims= tokens=1" %%c in ('dir /B /S /OD %ECLIPSEHOME%\plugins\org.eclipse.equinox.launcher_*.jar') do set EQUINOXJAR=%%c
 
:: start Eclipse w/ java
echo Launching the openHAB runtime...
set ARGS=-Dorg.osgi.framework.bundle.parent=ext -Dpython.home="%JYTHON_HOME%" -Dpython.path="configurations/scripts/lib" -Dosgi.clean=true -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Djetty.port=%HTTP_PORT% -Djetty.port.ssl=%HTTPS_PORT% -Djetty.home=. -Dlogback.configurationFile=configurations/logback.xml -Dfelix.fileinstall.dir=addons -Dfelix.fileinstall.filter=.*\\.jar -Djava.library.path=lib -Djava.security.auth.login.config=./etc/login.conf -Dorg.quartz.properties=./etc/quartz.properties -Dequinox.ds.block_timeout=240000 -Dequinox.scr.waitTimeOnBlock=60000 -Djava.awt.headless=true -Dfelix.fileinstall.active.level=4 -cp %JYTHON_HOME%\jython.jar;%EQUINOXJAR% org.eclipse.equinox.launcher.Main %* -console 
::echo %ARGS% 
java %ARGS%
1 Like

I have spent a frustrating hour trying to install this on a standard Ubuntu package installation. I have installed jython and added

#For Jython
JYTHON_HOME="/opt/jython"

OPENHAB_ARGS="-Dpython.home=${JYTHON_HOME}   -Dpython.path=${OPENHAB_CONFIGURATIONS_DIR}/scripts/lib -classpath ${JYTHON_HOME}/jython.jar"

to openhab.in.sh but it does not seem to be recognised

12:14:21.306 [DEBUG] [.r.internal.RuleModelActivator:42   ] - Registered 'rules' configuration parser
12:14:21.376 [DEBUG] [m.r.internal.engine.RuleEngine:77   ] - Started rule engine
12:14:24.775 [DEBUG] [j.internal.Jsr223CoreActivator:33   ] - Registered 'jsr223' scripting-engine
12:14:24.781 [DEBUG] [j.internal.engine.Jsr223Engine:96   ] - itemRegistry set
12:14:24.790 [DEBUG] [j.internal.engine.Jsr223Engine:68   ] - activate()
12:14:24.795 [INFO ] [o.o.c.j.i.e.s.ScriptManager   :58   ] - Available engines:
12:14:24.827 [INFO ] [o.o.c.j.i.e.s.ScriptManager   :60   ] - Oracle Nashorn
12:14:24.831 [INFO ] [o.c.j.i.e.scriptmanager.Script:84   ] - Loading Script test.py
12:14:24.839 [WARN ] [o.o.c.j.i.e.s.ScriptManager   :92   ] - No Engine found for File: test.py
12:14:24.849 [DEBUG] [j.internal.engine.Jsr223Engine:78   ] - Started jsr223 engine

What am I missing?

Edit:
I found the problem. The packages run a jar file and from man java

           When you use the -jar option, the specified JAR file is the source of all user classes, and
           other class path settings are ignored.

You learn something every day.

Edit2:
I learned something today as well. You can use the -Xbootclasspath in this situation. I changed /etc/default/openhab to include this line and now I can load python scripts

JAVA_ARGS="-Xbootclasspath/a:/opt/jython2.7.0/jython.jar -Dpython.home=/opt/jython2.7.0 -Dpython.path=configurations/scripts/lib"

@Spaceman_Spiff
worked like charm.
So easy to setup.

Thank you so much.

Just wondering if it is all that sensible to start migrating all my rules over to Jython, when it isn’t currently supported in OH v2.0. Do we know what the rules engine will be in v2.0?

Don’t want to have to do this migration twice!

A JSR223 extension is being developed for OH2…

1 Like

@steve1
Can you please comment the stability on the existing JSR233 solution based on your practical experience ?

It’s been very stable for me. When I started using openHAB I looked at the Xtext language and knew right away that I wanted to use JSR223. I know many programming languages already (like Python) and it didn’t make sense to invest time in learning an openHAB-specific language unless there were clear and significant benefits, which I didn’t see, From the postings I’ve seen in the forum it seems to me that JSR223 is less buggy and performs better than the Xtext rule framework. My personal opinion is that the JSR223-based rules should be the primary rule framework with the Xtext-based framework remaining to support legacy rule implementations.

3 Likes

@steve1.
This is great news. I also was never convinced about the Xtest DSL and always thought that this aspect was one of the weak aspects in openhab.
You encourged me to give it a try.

@steve1 + @martin_klimke :
I completely agree with you. With python being so starter-friendly it would make lots of sense using this as the primary (or at least default) rule language.
For me it is better in every aspect. Even the Error messages.

I am trying my first jython scripts and want stop the thread for 1.5 seconds. When using

time.sleep( 1.5)

I am receiving the following error messages.

2016-04-29 19:49:37.570 [ERROR] [.c.j.i.e.RuleExecutionRunnable] - Error while executing rule: org.python.proxies.builtin$Martin_kommt_nach_hause$107@1bdf00
org.python.core.PyException: null
at org.python.core.Py.NameError(Py.java:284) ~[jython.jar:na]
at org.python.core.PyFrame.getglobal(PyFrame.java:265) ~[jython.jar:na]
at org.python.pycode.pyx37.execute$11(:65) ~[na:na]
at org.python.pycode.pyx37.call_function() ~[na:na]
at org.python.core.PyTableCode.call(PyTableCode.java:167) ~[jython.jar:na]
at org.python.core.PyBaseCode.call(PyBaseCode.java:307) ~[jython.jar:na]
at org.python.core.PyBaseCode.call(PyBaseCode.java:198) ~[jython.jar:na]
at org.python.core.PyFunction.call(PyFunction.java:482) ~[jython.jar:na]
at org.python.core.PyMethod.instancemethod___call
(PyMethod.java:237) ~[jython.jar:na]
at org.python.core.PyMethod.call(PyMethod.java:228) ~[jython.jar:na]
at org.python.core.PyMethod.call(PyMethod.java:218) ~[jython.jar:na]
at org.python.core.PyMethod.call(PyMethod.java:213) ~[jython.jar:na]
at org.python.core.PyObject._jcallexc(PyObject.java:3626) ~[jython.jar:na]
at org.python.core.PyObject._jcall(PyObject.java:3658) ~[jython.jar:na]
at org.python.proxies.builtin$Martin_kommt_nach_hause$107.execute(Unknown Source) ~[na:na]
at org.openhab.core.jsr223.internal.engine.RuleExecutionRunnable.run(RuleExecutionRunnable.java:36) ~[na:na]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_73]

That is the code:
class Martin_kommt_nach_hause(Rule):

def getEventTrigger(self):
    return [
        ChangedEventTrigger("Presence_Martin")
    ]

def execute(self,event):
    oh.logInfo("Martin_kommt_nach_hause","hallo")
    item = event.item
    oh.logInfo("Event :", str(ItemRegistry.getItem("Presence_Martin").state))
    oh.logInfo("Event :", str(item.state))    
    if str( event.newState) == "OFF":
        oh.sendCommand("Command_2_speech", "Martin hat das Haus verlassen")
        oh.sendCommand("Home_big_vorkurzem", "OFF")

    if str( event.newState) == "ON":
        #oh.sendCommand("Martin_home_time", new DateTimeType())
        oh.sendCommand("Command_2_speech", "Martin kommt gleich")

    time.sleep( 1.5)

The previous message is somehow not displaying completely.
I have no idea why.

I can only guess, but are you importing the time module?

Thanks. That was the solution.
My first 4 rules are working now :smile:

Maybe if I could ask another question.
I always had the statement

postUpdate(Martin_home_time, new DateTimeType())

to store the moment something has happend.
How would this be translated in Jython?

And maybe a second question:
How am I canceling a timer?

In general I am struggling quite a bit with the lack of documentation and examples and also I did not find the source code of the jsr233 addon. The syntax to interact with the specific openhab classes therefore is not clear for me. For example, is it possible to create a trigger that triggers if a certain state is reached.
the equivalent to

when
Item Presence_Martin_big changed to OFF
then

Could you provide a link to the github of the source?
Maybe I will find some questions to my answers there.

@martin_klimke I’m going to create another topic where we can discuss JSR223 Jython usage.

1 Like

Thanks for answering my questions and taking your time.

Hello,

I use the JSR223 also. But with groovy. This is a really great feature.

The only problem I saw was when I had a old rules with jsr223 rule at the same time. Openhab had really weird behaviour. When I switch all my rule to jsr223 it fix the problem.

Now I would love to see application rule like the one in smartthings.

Joel

I have no problem mixing rules.
Currently half of my rules are in jython and half of them are still in the old engine.

But the best part is, that now I have always deterministic behavior.
In my sleeping room is a button which I don’t push that often.
Sometimes the light would go on almost immediately, sometimes after a couple of seconds.
The delay was long enough to keep me wondering if I pressed the button correctly.

I switched the rule to jython today. Really fast response on the first press.
No more wondering! This is so awesome!

1 Like

I have meanwhile converted about 10 rules.
The learning curve has been steap but after this I can benefit from the power of a well documented language overcoming of the weaknesses of the Openhab DSL.

Hope that this approach will be continued in openhab 2.
Jython is awesome and really great.
Everybody here should at least give it a try.

Thanks to everybody who contributed to this valuable enhancement.

1 Like

I had a lot of frustration with xtext based rules since openhab seems to pose its own limitations on top of the “documented” xtext. For example, lambdas might not be able to refer to other variables (e.g. functions/lambdas) – except in the rules directly. This really limited the usability of the language for me.

Decided eventually bite the bullet and start to use JSR223. I decided to go with the built-in javascript as that seems to be 1) well developed & maintained 2) commonly used language 3) bring minimal additional dependencies, 4) I have some doubts over Jython**.

In any case, I really enjoyed the extra power you get from the language. I can’t stress enough how much smaller and easier the rule code base becomes with the JSR language.

I would like to get feedback on the packaging of JSR. I’m running openhab on raspberry pi and the official debian packages. I found it a bit weird that (installed) files need to be modified in order to have JSR->Java imports to work (see wiki on -Dorg.osgi.framework.bundle.parent=ext flag). Shouldn’t this be part of the JSR deb installation process? What do you think?

**) Even though I’m really a python fan, not really fan of jython as it seems to develop very slowly (Python version has been behind the CPython a long time, 2.7.0 vs 2.7.10, not even mentioning ever-growing trend to move to python3) and frankly speaking I’m a bit concerned over the future development.