smarthome icon indicating copy to clipboard operation
smarthome copied to clipboard

Easy Groovy Rules

Open torpex77 opened this issue 6 years ago • 12 comments

This issues covers the enhancement suggestion posted here on the discussion forums. Much of the content below is copied (with minor edits) from my initial post in that thread.

I want to make it easy to write rules in Groovy by creating a small set of base classes that add functionality found in the standard rules engine.

The base class contains methods for logging (logError, logWarn, logInfo, and logDebug), for interacting with bus (sendCommand and postUpdate), for interacting with the item registry (getItem, getItems), getting actions (getAction). There are some other convenience functions for things like creating triggers for different events.

In addition to the base classes, I have a small set of classes covering some of the common use cases for rules. For example, “do something when a contact opens”, “do something if a reading is outside a certain range”, “do something if a door has been open too long”, “do something when a door opens”, “do something when an item changes state”, etc. Generally, these classes have one or two methods with default implementations (logging only) that can be overridden to implement what the user wants to do. The event handler also traps and logs any exceptions thrown by those methods.

I implemented this for my own use in OpenHab1 and found it to work well.

I’m new to OSGi and the SmartHome framework, so this has been a lot of trial-and-error to get things working. I tried a lot of different things to get my external Groovy classes loaded and usable in JSR223 groovy scripts, and repeatedly failed. So for now I’ve added them directly to the RuleSupport bundle in the smarthome codebase. I’m not sure what the best or optimal approach should be, but at least this has allowed me to make progress on implementing what I want. I had to make some adjustments to my Java code such as passing and returning Object instead of types to allow the scripts to be a little more Groovy-like.

I've forked the smarthome repo, and ported my classes over from OH1. I haven't started using them in anger yet, but they pass my basic testing. My fork is at https://github.com/torpex77/smarthome

Usage examples can be found in the original thread mentioned above.

Anyway, please share your thoughts on this approach and how to proceed.

Thanks,

Doug

torpex77 avatar Jan 26 '18 00:01 torpex77

I should have added that my code is on the GroovyRuleHelperClasses branch of my fork. All my classes can be found here:

https://github.com/torpex77/smarthome/tree/GroovyRuleHelperClasses/bundles/automation/org.eclipse.smarthome.automation.module.script.rulesupport/src/main/java/org/eclipse/smarthome/automation/module/script/rulesupport/shared/simple/helper

Doug

torpex77 avatar Jan 26 '18 21:01 torpex77

@adimova As you are our automation professional, what do you think of?

maggu2810 avatar Feb 01 '18 05:02 maggu2810

@torpex77 My understanding so far was that the jsr223 support should be the ideal basis for writing rules in Groovy.

I tried a lot of different things to get my external Groovy classes loaded and usable in JSR223 groovy scripts, and repeatedly failed.

Did you try to discuss this with @smerschjohann & @lewie, who are the best experts wrt jsr233 integration?

kaikreuzer avatar Feb 01 '18 10:02 kaikreuzer

@kaikreuzer This is jsr223, just with some additional classes in smarthome automation rulesupport to handle common use cases.

It might be better to think of it like that - classes to handle common JSR223 uses cases like "do something with a switch changes" - as opposed to something purely for Groovy. I haven't tried them under Python or Javascript, but my assumption is they could be helpful there too.

Discussion started on the big "Port JSR223 bundle..." thread before I created a separate one (the "Easy Groovy Rules" referenced above). Not sure if @smerschjohann & @lewie chimed in on the first one or not. But I tried multiple suggestions from various people and/or sample rules in github - hours and hours and hours I've tried things with no luck. Lots of different approaches seem like they should work, but never do.

The closest I've come to including these externally is that I am able to compile my base classes outside of OH by adding the appropriate jar files to my classpath and build a jar file. Then add that to the ext directory for OH. I can even extend my base classes in a Groovy rule. But it completely screws up the rules engine - not only does my rule not work, any existing rules stop working. I turned logging up to debug, but there was no trace of any error or any indication what happened.

Doug

torpex77 avatar Feb 01 '18 17:02 torpex77

Based on the feedback so far, I think I need to go back and approach this from a different angle.

Instead of "Easy Groovy Rules" I need to rework the approach to be "JSR223 Rule Templates".

The goal would be to provide a set of classes that can be extended to easily implement some common rule use cases using JSR223 rules. The basic use cases would include “do something when a switch is thrown”, “do something when a contact/door opens”, “do something if a door has been open too long”, etc. There would also be a base class or two that would encapsulate some basic functionality like accessing the item registry, getting actions, and logging.

To use, extend the appropriate base class and override the default implementations for the event triggered methods. Here is a Groovy example:

def r = new OnOffRule('TestSwitch5') {
    def on(event) {
        logInfo('TestSwitch5 is now ON!');
        getAction('pushover').pushover('TestSwitch5 ON')
    }
}
automationManager.addRule(r)

I have not used Python or Javascript for rules, so I would have to work up some examples in those languages to make sure they could take advantage of it.

Sound OK? If so, I'll begin working to refactor and test my code to make sure it works with python and JS, get all of my documentation and examples into a single place, and refactor my code as necessary, and so forth. In this case, should this issue be closed and another opened, or just a pull request, or what?

If not, that's fine too. I'll still going to maintain my fork for my own use, but if I have created something that I can give back then so much better.

Thanks,

Doug

torpex77 avatar Feb 24 '18 19:02 torpex77

Based on the feedback so far

Which was hardly anything, sorry for that. I hope that doesn't lead to any frustration on your end... I‘d hope that people like @smerschjohann or @lewie could join in here as they are much deeper in the jsr223 & groovy stuff.

I need to rework the approach to be "JSR223 Rule Templates".

If this could be done in line with the templating approach of the rule engine, this would be cool - it would effectively mean that you could write the complex logic in groovy and then fill in the parameters in the Paper UI. I cannot really tell how and if that is feasible or what would need to be adapted in the rule engine architecture to make it possible.

I am currently still trying to tackle the huge refactoring of https://github.com/eclipse/smarthome/pull/4468 - once this is done, I could hopefully spend more time in helping to figure out a good approach for the templating and also help working on a "scripting API" (i.e. all the classes and services that we want/need to make available to scripts), which is currently not clearly defined either.

kaikreuzer avatar Mar 09 '18 11:03 kaikreuzer

@kaikreuzer

Well, looks like I picked an interesting time to start looking at this again, given the ESH -> OH change.

Anyway, I've updated my code (see link to repo above) to compile with the current master. I was hoping to talk about how close this is to ready enough for a pull request. I'd love to get it into the rules engine proper.

Is that still a viable option?

Doug

torpex77 avatar Jan 21 '19 23:01 torpex77

Hey @torpex77, nice to see that you are still around! You indeed chose an interesting timing ;-) - there is no sense in creating a PR against ESH, but the code is just in mid-air and will soon end up in openhab-core and once it is merged there, you are very welcome to create PRs against the rule engine there! You might want to start discussing your idea with @openhab-5iver as he's probably the most active maintainer for jsr223 related stuff now.

kaikreuzer avatar Jan 21 '19 23:01 kaikreuzer

Ok. Sounds good.

I've tried to be as non-invasive to the existing code base as possible. Actually, didn't change a bit of it - only the MANIFEST.MF and the karaf feature for the new dependencies. So It hopefully will carry over to the new structure fairly well.

Doug

torpex77 avatar Jan 21 '19 23:01 torpex77

Hello, Doug! I've only played with Jython and JS, and haven't done anything with Groovy yet, so I'll start looking at it. Would you need this if there was something like openhab2-jython for Groovy? I plan to add repos for JS and Groovy, so this may be a good time to for it!

In working with the Jython modules, I've thought about doing something similar... converting them to Java for use by other supported OH supported JSR223 languages. A large part of the Jython modules and JS libraries are to fill the gaps in functionality not yet provided by the automation API. I'm very interested to look through your code!

5iver avatar Jan 22 '19 02:01 5iver

Hello Scott,

I wanted to do an set of external libraries similar to openhab2-jython. I went down that road first. It would have been much easier. I couldn't figure out any way to include a set of base classes - Java or Groovy - into the standard OH without actually modifying the code base. The various class loader restrictions or OSGi blocked me with everything I tried. It was frustrating - I spent a lot of time on that before going this route.

So what I ended up with is what is described above - a set of base classes that a) add various utility and convenience methods and b) implement some common use cases. IMO it's less flexible that a scripting library, but it does the job.

The base class extends SimpleRule. The others extend it. I suspect they might be usable from the other JS223 languages, too, but I haven't tried that.

Doug

torpex77 avatar Jan 22 '19 03:01 torpex77

Sounds as if establishing a common scripting API/library for ALL jsr223 languages will definitely make sense - we should not end up with always different features for different languages.

Absolutely ok if you both add stuff to the core automation bundles - if OSGi is a beast, just ping me on issues and I'll try to figure out some advice ;-)

kaikreuzer avatar Jan 22 '19 10:01 kaikreuzer