[JSR223-Jython] Simplified rule definition (similar to Rules DSL) and universal decorator

jsr223
jython
decorator
Tags: #<Tag:0x00007f015227e8e0> #<Tag:0x00007f015227e610> #<Tag:0x00007f015227e3b8>

(Scott Karns) #41

Michael, The file you need is the proposed updated version of items.py. The file items.py is already part of your Jython installation. You should be able to replace the current version, maybe copy the original somewhere safe first, then copy the contents of the first code panel in my post above to automation/lib/python/items.py. On my system, an RPi3, I run Openhabian and the Jython files are all located under /etc/openhab2/automation/, which is actually a symlink to /usr/share/openhab2/automation. Your installation may be different, but you will have an automation directory into which you copied the Jython files and directories. I assume you are familiar with the post How to Setup Jython where @5iver described the process of installing Jython.


(Michael Cumming) #42

Hi Scott,

I am running OpenHABian as well. 2.4M5.

I would like to use the python request library - not related to the .items stuff above.

Mike


(Michael Cumming) #43

@5iver

This line generates an error in triggers.py, my guess is there needs to be a check that the inputList is not empty? Rule works when you specify to X.

 
@when ("Item GarageDoubleDoorIndicatorPressed_Value changed from 0")

2018-10-31 14:25:21.132 [ERROR] [omation.core.internal.RuleEngineImpl] - when: Exception [index out of range: 0]: [Traceback (most recent call last):

  File "/etc/openhab2/automation/lib/python/openhab/triggers.py", line 297, in when

    if inputList[0] == "to":

IndexError: index out of range: 0

(Scott Rushworth) #44

Please open an issue for this in GH. I’m a bit out of pocket ATM, but will take a look tonight/tomorrow.


(Michael Cumming) #45

done.


(Scott Rushworth) #46

done :slight_smile:

This should now be corrected. I refactored the trigger validation portion of the when decorator, and this corrected the issue and possible others! I’ve been building out a regression test for the decorators, and everything I have passed. There are a lot of combinations to test though, so I may have missed some.


(Michael Cumming) #47

@5iver Scott, question about trigger behaviour…

When using Member of to detect a change in a item of a group, should that trigger catch a group that is a member. ie I have a group that is a member of another group and currently that does not get triggered. I can behavior in the code of triggers.py is doing what it should but I always thought the rules DSL would trigger on that … correct me if I am wrong :slight_smile:

There is "descendent of " immediately below at line 177 but AFAIK this isn’t part of the rules DSL.

I opened an issue on github.

Mike


(Scott Rushworth) #48

My automation is very dependent on Member of triggering when child groups change values. I haven’t noticed any change in behavior, but I’ll specifically test it.

A group should trigger a Member of rule, if it is a child of the specified group.

I made up Descendent of, because it was functionality in the old item_triggered decorator. Groups are not considered with this trigger.


(Michael Cumming) #49

Actually groups do trigger with the descendent of and do not trigger with the member of…


(Scott Rushworth) #50

This appears to be working properly for me:

Items/Groups

Group:Switch:OR(ON,OFF)         gTest_Parent                 "Test Parent Group [%s]"           <none>      (gTest)
    Group:Switch:OR(ON,OFF)         gChild_1                 "Test Child Group 1 [%s]"          <none>      (gTest_Parent)
        Switch                          Test_Switch_1        "Test Switch 1 [%s]"               <switch>    (gChild_1)
        Switch                          Test_Switch_2        "Test Switch 2 [%s]"               <switch>    (gChild_1)
    Group:Switch:AND(ON,OFF)         gChild_2                "Test Child Group 2 [%s]"          <none>      (gTest_Parent)
        Switch                          Test_Switch_3        "Test Switch 3 [%s]"               <switch>    (gChild_2)

Rule

from openhab.rules import rule
from openhab.triggers import when

from org.slf4j import Logger, LoggerFactory
log = LoggerFactory.getLogger("org.eclipse.smarthome.model.script.Rules")

@rule("Regression Test: Test decorator Member of changed")
@when("Member of gTest_Parent changed")
def testDecoratorGroupMemberChangedRegression(event):
    log.debug("JSR223: Regression Test: Jython decorator: Member of gTest_Parent changed [{}]: [{}]".format(event.itemName, event.itemState))

@rule("Regression Test: Test decorator Descendent of changed")
@when("Descendent of gTest_Parent changed")
def testDecoratorGroupMemberChangedRegression(event):
    log.debug("JSR223: Regression Test: Jython decorator: Descendent of gTest_Parent changed [{}]: [{}]".format(event.itemName, event.itemState))

Logs

2018-11-02 22:23:22.821 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Member of gTest_Parent changed [gChild_1]: [OFF]
2018-11-02 22:23:22.822 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Descendent of gTest_Parent changed [Test_Switch_1]: [OFF]

2018-11-02 22:23:37.540 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Member of gTest_Parent changed [gChild_1]: [ON]
2018-11-02 22:23:37.541 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Descendent of gTest_Parent changed [Test_Switch_1]: [ON]

2018-11-02 22:25:33.326 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Descendent of gTest_Parent changed [Test_Switch_3]: [ON]
2018-11-02 22:25:33.333 [DEBUG] [org.eclipse.smarthome.model.script.Rules] - JSR223: Regression Test: Jython decorator: Member of gTest_Parent changed [gChild_2]: [ON]

(Michael Cumming) #51

Scott, how did you address the problems with the components and JythonItemProvider not loading correctly at startup? I have looked at using the reload function but no success.

I am starting to use the item.add you posted above. Works great but with a restart JythonItemProvider fails and I have to “edit it” and save to be able to load it

Mike


(Michael Cumming) #52

Of course I found the answer in the post immediately above :slight_smile:

from openhab.items import add
import openhab.items
reload(openhab.items)
from openhab.items import add

(Scott Karns) #53

Michael, glad you found the answer. I fought that issue myself until I recalled having read somewhere (I think it was the lucid README) about reload.


(Michael Cumming) #54

Scott, interesting problem that took me about an hour to sort out.

When doing string concatenation for item naming, item becomes type Unicode and not string. So the if statement False in items.py. Not sure this is desired or not…

if isinstance(item, str):

(Scott Karns) #55

I’ve noted that behavior in some other areas with Jython. I’m not quite sure what to do about it. It does seem to cause problems with join() expressions when one object is a str object and the other is Unicode.


(Michael Cumming) #56

Was really frustrating figuring that out… wondering if we should try and catch that in the add/remove methods?

Overall, the combination of Java and Python types requires a fair bit of understanding and troubleshooting.

But it still beats DSL anyday :slight_smile:


(Scott Karns) #57

Michael, I just did a little bit of research on Jython and unicode. From this link, it seems we can replace

isinstance(obj, str)

with:

isinstance(obj, basestring)

since basestring is the superclass of both str and unicode objects.

I agree, despite the Python and Java type issues, I prefer JSR223 Jython to DSL.


(Michael Cumming) #58

That looks like a nice solution. And I agree, Jython is far superior to DSL. One just has to remember that you need to think about variable types when working to/from Java.


(Michael Cumming) #59

@5iver

Scott, would like to restart a bundle from Jython. I have been digging through OH github but can’t find what I need - do you have any ideas?

I found the registry and the code below works but haven’t found how to reset a binding

Mike

BindingRegistryInfo = osgi.get_service("org.eclipse.smarthome.core.binding.BindingInfoRegistry")


bis = BindingRegistryInfo.getBindingInfos ()

log.info ('Binding info {}'.format(bis))

(Michael Cumming) #60

I found the documentation on a bundle - and this looks like what is needed to stop/start a bundle. @5iver or @scottk would either of you know where the registry is that we can get the bundle from?

https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FPlugin.html