Exception when executing JSR rule

Hi all

I’ve just set up the JSR addon but when I try to execute the rule I always got an exception:

2016-04-30 00:49:08.313 [INFO ] [o.c.j.i.e.scriptmanager.Script] - Loading Script testrule.py
2016-04-30 00:49:08.314 [INFO ] [o.c.j.i.e.scriptmanager.Script] - EngineName: jython
2016-04-30 00:49:08.330 [INFO ] [o.o.c.j.i.e.s.ScriptManager   ] - Engine found for File: testrule.py
2016-04-30 00:49:46.500 [ERROR] [.c.j.i.e.RuleExecutionRunnable] - Error while executing rule: org.python.proxies.__builtin__$TestRule$2@2538208f
org.python.core.PyException: null
    at org.python.core.Py.AttributeError(Py.java:205) ~[jython.jar:na]
    at org.python.core.PyObject.noAttributeError(PyObject.java:1013) ~[jython.jar:na]
    at org.python.core.PyObject.__getattr__(PyObject.java:1008) ~[jython.jar:na]
    at org.python.pycode._pyx2.execute$3(<script>:8) ~[na:na]
    at org.python.pycode._pyx2.call_function(<script>) ~[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__$TestRule$2.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_91]

My rule is quite simple so I don’t really know what the problem is:

class TestRule(Rule):
    def getEventTrigger(self):
        return [
            ChangedEventTrigger("JythonTest", None, None)
        ]

    def execute(self, event):
      item = ItemRegistry.getItem(self._device_name)

def getRules():
    return RuleSet([
        TestRule()
    ])

Can anyone give me a clue to solve this problem? Might this be a problem with the OH Classpath at startup?

Thanks & Regards
Dieter

Where is self._device_name initialized?

Hi Steve

Thank you for your quick reply.

You are right, it is definitly to late here :sleeping:

When I change the execute method according to the wiki it (nearly) works:

        def execute(self, event):
            oh.logDebug("TEST", "event received " + str(event))
            oh.logInfo("TEST", str(ItemRegistry.getItem("JythonTest")))
            action = oh.getActions()
            oh.logInfo("TEST", "available actions: " + str(action.keySet()))
            ping = oh.getAction("Ping")
            oh.logInfo("TEST", "internet reachable: " + ("yes" if ping.checkVitality("google.com", 80, 100) else "no"))

If I use the self.getName() call instead, I still got the same error. Do you have an idea for this as well (I would expect the getName() method to be defined somewhere in the class hierachie but I’m completly new to jython…

Regards
Dieter

What name are you trying to get with self.getName() or self._device_name?

Hi Steve

self.getName() should return the class/rule name I guess from the context. I just copied this code from the oh-jsr-wiki (https://github.com/openhab/openhab/wiki/Jsr223-Script-Engine) and there the original lines are

oh.logDebug(self.getName(), "event received " + str(event))

so it should be something like that. As for self._device_name came for your tutorial here (https://community.openhab.org/t/tutorial-beyond-xtext-supercharged-rules-using-jython/3417) and was probably only because it was already after midnight.

I’d just tried to get it run, I will try “real” scripts today.

Regards
Dieter

I understand now. There is no getName() method on the [Rule] (https://github.com/openhab/openhab/blob/1.8/bundles/core/org.openhab.core.jsr223/src/main/java/org/openhab/core/jsr223/internal/shared/Rule.java) interface. I’ve updated the wiki (reminder: anybody can edit the wiki). My guess is that some earlier version of the [Rule] (https://github.com/openhab/openhab/blob/1.8/bundles/core/org.openhab.core.jsr223/src/main/java/org/openhab/core/jsr223/internal/shared/Rule.java) interface had a getName method.

To get the name of a rule you can use standard Python techniques for getting the class name.

rule_name = type(self).__name__

So a getName function could be implemented in a rule class as

def getName(self):
    return type(self).__name__

If you wanted to reuse that functionality across rules, you could create your own rule base class.

class MyRule(Rule):
    def getName(self):
        return type(self).__name__

and then derive your rules from that class instead of directly from Rule.

class ExampleRule(MyRule):
  def getEventTrigger(self):
     oh.logInfo(self.getName(), "getEventTrigger called")
     return [ StartupTrigger() ]
  # add execute function, etc. ...

You probably know this already, but the first argument to the log functions can be any string. The value is used as the LogBack category name in the log file. It isn’t required to be the rule name although that’s a convenient string to use.

1 Like