Error when using CommandEventTrigger in Jython

Hi!

How can I use the trigger “CommandEventTrigger” in Jython?

I have a Item

String  PvOutputSourcePriority "Output Source Priority [%s]"

in Sitemap I use it like this:

Selection item=PvOutputSourcePriority label="Output Source Prio" mappings=["0"="Utility first","1"="Solar first","2"="SBU first"]

In Jthon following trigger is working:

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

But when I use the CommandEventTrigger like that:

def getEventTrigger(self):
        return [
            CommandEventTrigger("PvOutputSourcePriority")
        ]

I get this error:

2015-10-21 14:35:38.805 [ERROR] [o.o.c.j.i.e.s.ScriptManager ] - unknown exception
org.python.core.PyException: null
at org.python.core.Py.TypeError(Py.java:259) ~[jython.jar:na]
at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:209) ~[jython.jar:na]
at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java:262) ~[jython.jar:na]
at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:319) ~[jython.jar:na]
at org.python.core.PyReflectedConstructor.call(PyReflectedConstructor.java:177) ~[jython.jar:na]
at org.python.core.PyObject.call(PyObject.java:419) ~[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:223) ~[jython.jar:na]
at org.python.core.Deriveds.dispatch__init__(Deriveds.java:19) ~[jython.jar:na]
at org.python.core.PyObjectDerived.dispatch__init__(PyObjectDerived.java:1112) ~[jython.jar:na]
at org.python.core.PyType.type___call__(PyType.java:1713) ~[jython.jar:na]
at org.python.core.PyType.call(PyType.java:1696) ~[jython.jar:na]
at org.python.core.PyObject.call(PyObject.java:461) ~[jython.jar:na]
at org.python.core.PyObject.call(PyObject.java:465) ~[jython.jar:na]
at org.python.pycode.pyx14.getEventTrigger$5(:23) ~[na:na]
at org.python.pycode.pyx14.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$SetPvOutputSourcePriority$52.getEventTrigger(Unknown Source) ~[na:na]
at org.openhab.core.jsr223.internal.engine.RuleTriggerManager.addRule(RuleTriggerManager.java:254) ~[bundlefile:na]
at org.openhab.core.jsr223.internal.engine.RuleTriggerManager.addRuleModel(RuleTriggerManager.java:335) ~[bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptManager.loadScript(ScriptManager.java:103) [bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptManager.scriptsChanged(ScriptManager.java:185) [bundlefile:na]
at org.openhab.core.jsr223.internal.engine.scriptmanager.ScriptUpdateWatcher.run(ScriptUpdateWatcher.java:104) [bundlefile:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

What is going wrong?

kind regards
Martin

The Jython stack traces can be difficult to interpret, but the hint is there…

at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java:262) ~[jython.jar:na]

The CommandEventTrigger constructor requires both a name and a command. So something like should work better…

def getEventTrigger(self):
    return [
        CommandEventTrigger("PvOutputSourcePriority", StringType("HIGH"))
    ]

The trigger implementation doesn’t appear to support a wildcard command argument.

So, I must do that for every possible command?

get getEventTrigger(self):
    return [
    CommandEventTrigger("PvOutputSourcePriority", StringType("0")),
    CommandEventTrigger("PvOutputSourcePriority", StringType("1")),
    CommandEventTrigger("PvOutputSourcePriority", StringType("2"))
 ]

Thats not funny, because i have also other Items with up to 10 different strings! :frowning:

Yes, it does appear that way. I’m not sure why it was implemented like this. The ChangedEventTrigger supports unspecified states. I can submit a pull request for changing this trigger to be consistent.

In the meantime, it may not be as bad as it seems. Let’s say you had a variable with your commands…

COMMANDS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]

You could write your trigger function like this…

def getEventTrigger(self):
    return [CommandEventTrigger("PvOutputSourcePriority", StringType(c)) for c in COMMANDS]

or even…

def getEventTrigger(self):
    return [CommandEventTrigger("PvOutputSourcePriority", StringType(str(c))) for c in xrange(0,10)]

if the commands are always sequential integers. In this case no COMMANDS variable is needed.

I tried it. But nothing happens now.
No Error log or something like that:

return [
            CommandEventTrigger("PvOutputSourcePriority", StringType("0"))
        ]

I’ve done some more digging into the source code and found some strange things. It appears the actual command value is not provided to the trigger. So, it basically only supports wildcarding but the argument must be provided anyway and must be None. This seems like a bug, but I’m going to do some more exploration.

The following rule works for me…

class CommandRule(Rule):
  def getEventTrigger(self):
    return [ CommandEventTrigger("TestItem", None) ]

  def execute(self, event):
    oh.logInfo("Test", "Execute {}", str(event))

Any command I send to TestItem triggers the rule. This rule should continue to work even after the bugs are fixed (assuming the command value wildcard is still supported, which I’d expect).

The strange thing is, I tryed “None” already but it doesn’t work.

Now, it works. And with this “Bug” its in fact easier for me because of the enums… :sweat_smile:

Thanks for the help!