-
Notifications
You must be signed in to change notification settings - Fork 779
scriptable automation #1783
scriptable automation #1783
Conversation
158d61c
to
1173ddd
Compare
1173ddd
to
410ce4e
Compare
Ok, here's some initial feedback/questions. First of all, you (again) did a tremendous job - I easily got it all working with Jython, although I have never used Jython before in my life :-) I must admit, that I do not yet fully understand the whole architecture. What would help me is, if your could briefly describe what the purpose of these bundles exactly is for you:
It feels that
Please also check the code again against the guidelines: I noticed specifically A.9 (considering #1568), B.4, B.6, C.1. I'll go deeper into the code, once we have agreed on the bundle structure - thanks! |
In general, I have divided the scripting functionality in multiple parts and made the scripts as modular as possible, by allowing them to only load the parts that they need.
This was meant as general basis to load script-engines using jsr223
These are types/classes/objects which are ALWAYS injected to the script engines scope and should therefore be kept small since by the introduction of the ScriptExtensions, the wanted type and object sets can be imported when required.
This is the script extension that allows to write rules using scripts. I moved it to an extension instead of importing them into the default scope by default to allow different extensions to coexist as well as to use the script engines without this support at all. It would for example not make much sense for the ScriptActionHandler, already introduced by you, to have these classes by default. It further allows that the Openhab2 or other implementations to offer slightly different interfaces or even a Openhab 1 compatibility layer without interference to other scripts as each script can load the extensions it requires. Therefore, scripts can coexist with other scripts depending on another set of implementations. This RuleSupport extension already consists of two presets: RuleSupport (always required if one wants to write rules) and SimpleRule (which tries to make writing rules easier).
This module allows the loading of scripts by bundle or from a filesystem directory. It is not named as parser as it really is not a parser but a loader ;) A parser would only "statically" parse a file and import it into a predefined structure etc. But in this context, the files are read, yes, but then passed on to the correct script engine and loaded into it. Therefore, I think the name parser does not fit here.
I wanted to divide the general jsr223 support (which is also used for simple ActionHandler triggering) from explicit rule writing support, therefore I moved those components to the newly introduced extension.
Same here: a script explicitly import the wanted set of types e.g. by
I agree, if the license is compatible with the the eclipse smarthome project, I can prepare a module for that
Ok, I will do that. But why do you still require at most JavaSE 7? It is not even supported by Oracle anymore. |
I will try to have a look as well before I leave on holidays, but certainly I will wait for this PR to be integrated in the repo before I start the refactoring of what I developed some time ago (see previous threads/discssions). My stuff is a bit outdated and I do not want to clutter things. |
What does "write" mean here exactly? And what is it concretely offering? It only consists out of internal classes, so it is no API for anybody. It only has one DS component called "loaderscriptscope" which from its name rather sounds application to module.script.loader.
I don't yet understand what those "presets" are and how they are used. Do you have a pointer for me?
Well, my point was that there already IS a loader for resources in bundles (from which you have duplicated a lot of code, which is in general not nice). This existing loader passes the content as-is to registered parsers, which is then supposed to spit out a set of rules. That's why I was wondering, if this existing infrastructure and API could be used here? After all, this is exactly their purpose.
What is the difference for "rule writing support"? Is it, that the whole chain of trigger/action/condition is executed within the script engine itself and thus the "normal" rule engine is not at all involved anymore? Does it have to be this way? Let me challenge you with some requirements to make it maybe a bit clearer, why I ask those questions:
For these reasons, I am trying to get your work into the existing framework as smoothly as possible - so that it isn't just some special optional feature, but that its power can be used in many different use cases.
Oh hell, so this is actually NOT about the automation component at all, but about a general integration of scripting code into the runtime? Then we should think of an even bigger refactoring to get some stuff out of the "automation" namespace.
Jython seems to have a pretty custom license, so I doubt that we will get that into ESH - but it should be fine to add such a bundle in OH2 then. Groovy instead is definitely fine in ESH, so we could have JS and Groovy support here and adding Jython in OH2.
Because especially on embedded hardware even Java 5 is still used by many people. Nonetheless, we plan to move to Java 8 soon, but as it will require to switch the whole build, it would be good if your code still compiles with Java 7 for now - as it is just two lines using String.join, that should be fairly simple :-) |
@kaikreuzer That is exactly my (to be refreshed) PR is doing, with the the Xtext script running as an Action, and the various .rules trigger being mapped to a (new) set of Triggers |
@kgoderis, right, looking forward to it :-) |
This is quite a chunk of code. I am not sure I have understood everything here, but here are some questions:
The rest I need to revisit later today |
the internal only relates to the OSGI model, it provides the functionality to the scripts which is not OSGI.
Yes, LoaderScriptExtension.java provides three different presets and they are used in the script like:
to load and instanciate the objects needed for this preset. This model is not currently possible with the default scope, as this does not allow to instantiate classes for a particular script. But using this feature, it is e.g. possible to unregister rules on script deletion/modification.
hm, yeah by refactoring the original code, this can be possible. But some needed features were missing at the time of writing in december and I did not want to rewrite the other parts as well at that time. But yes, this would be a task of a first refactoring. Specifically, context information to implement unloading behavior was missing if I remember correctly.
No that is not the case, there is the SimpleRule, which makes writing rules easier if you don't want to expose the action part as a separate action. In this case the Action is "hidden" by a unique id using the ScriptedAction. Nevertheless, as it can be seen in the example, it is possible to write actions that are normally registered to the automation engine and therefore are exposed as new action to the engine. This would allow the user to first write SimpleRules, refactor them accordingly where it fits, bundle them in a OSGI bundle and provide them as a jar archive.
No reason to swear ;) Yes, it allows scripting everything with the right extensions or with additional effort on the script side. And you are right, it really does not have to be in the automation namespace ;)
Actually, I would not like that separation as it would mean that jython degrades to a lower "supported" level. Yes, it is custom. But on the other side, comparable to a BSD license, just by reading it, and also stated on the wikipedia page where is states it is FSF compliant. I guess it would be fine to try getting the approval from eclipse.
No, it provides an import mechanism, where on the Java side, the classes can be instantiated based on the unique id of the script.
Because the current implementation did not fit nicely, after first general acceptance and refactoring, it can be exchanged quiet easily...
Why is a rule a decorated script? Even the .rule part should contain at least triggers and actions. But yes, in my opinion, it would make sense to generalize them.
Patches are welcome.
This is not necessary for scripts as rules implemented in the same file will share the same context. But isn't this just an implementation detail of your rule to automation wrapper?
good idea, why not? |
by decorated, I mean that from an Xtext point of view it is in essence a Script, with some DSL for triggers and so forth. |
mmm... would it not be more logical than to have a new class that extends ScriptScopeProvider, and that provides the class instantiation functionality? |
ScriptScopeProviders are meant to be always imported in the scripts, at least in the current state. This is the main fact, that I don't want here. |
@smerschjohann @kaikreuzer Would it make sense to commit the PR to a new dev branch so that we can prepare aux. PR's on it? |
I'm not in details in script engines and to be fair I don't understand fully this PR. For me the script handler has to support script conditions and script actions as it does at the moment. They gives possibility to write conditions base on the state of the system and to change the state of the system through the rule execution. |
actually, (some) script engines are not much more resource hungry than java itself, so that should not be the main issue here. I think the steps for rule creation are small enough to be directly integrated. So I think the benefit to have it directly in the scripts is higher than wrapping it by a limited "Converted"RuleProvider. Yes, you might even think about implementing an AI, the possibilities should not be limited by an unnecessary mapping. Nonetheless, as @kaikreuzer already said, it might be a good idea to look at the namespaces again to find the correct integration point for smarthome. |
I'll try to come back to you on this soon again as I definitely want to move this forward as well. Thanks for your patience meanwhile! |
Hi, what is the current state on the PR for JSR223 support? |
Well, I stopped working on it, since the feedback is low. This PR was working as is, but as the feedback, amongst other, suggested namespace changes, I waited for a full review as it can be quiet cumbersome to change only a single thing at a time. Especially, if the whole picture is not clear. Since I have a few free days now, I am hopefully able to migrate my current openhab1 setup to openhab2 now. With this done, I can offer a test build with that feature enabled, if you are willing to give feedback on the general functionality of this feature. |
This would be lovely. The Jython support is the only thing holding me back. |
I really have to apologize @smerschjohann and I am glad that you are still patiently waiting and didn't give up yet. I'll try to find 1-2 hours over christmas to go through my open questions again and summarize what I think should be refactored. Also note that there were quite some changes on the rule engine itself in the meantime, so this might also require some adaptions. |
Ok, I will try to recap what should be done from what I understand from the discussion:
Does this make sense to you, @smerschjohann? |
I have checked this. It is fine to use Jython as a works-with dependency, i.e. use it, if it is available on the users machine, but we would not be able to distribute the binary ourselves from Eclipse. Having this huge software IP cleared would be an immense effort and I doubt it is worth it. We could add such a module.script.jython bundle in the openhab-core repo, though. For the openHAB users, there would be no "lower supported level", it would be all the same as groovy. All other ESH-based solutions are also free to decide for some way to pre-install Jython, if this is of any interest to them. |
@petrklus Yes, this is the PR. I've just added a link to this PR in the openhab2-jython README.md. |
is there a way to access action services like mail or XMPP in scriptable automation? And for example how to access persistence extensions?
Thanks EDIT: |
Based on @steve-bate first Jython examples, realized a bit simple JavaScript Code. It is experimental, but it works nearly like in OH1 JSR223 binding. My first greatest concern is to migrate existing JS from OH1 to ESH automation with this JS tests. @smerschjohann, distinctions from JavaScript view:
From the user's point of view, it is great to work with new JSR223 on OH2, especially the access to much more classes as is possible in OH1. It goes far beyond the possibilities so far, it can be done many more prototyping things now. I'm looking forward to packable scripts. |
Yes, I think it is a must. I have a look in to it, I think I am able to do it this week. @lewie as you found a way already, I will not include that into the default namespace, neither as an extension. Might come in the future, but I think I shouldn't change any "minor" things right now. @lewie and @steve-bate thank you for providing these examples which even contain other ideas, I did not even think about ;) After I have made the last changes (hopefully this week), I would like to ask you two to test your scripts against the latest commit to verify that everything is still working or you can at least fix the incompatibilities that might arise due to the latest changes. I did not check it, but if I'm not mistaken, the jython examples are not working against the current head. StartupTrigger etc. are not directly related to this PR, so separate PRs should either go to ESH or openhab 2. |
@smerschjohann, of course, you're absolutely right, it's only trifles. Thanks Simon for your second great JSR223 work! |
@smerschjohann Good to hear that you'll continue working on this PR this week - we should be really close to a merge then!
This is absolutely right. |
@smerschjohann, I've been trying my scripts with the latest code. It seems like the code is working but some of my scripts are broken (as expected) because of naming changes. I'm working on fixing those, but I did see the following exception in the log and it seemed suspicious:
This happened when I removed the rule_decorators.py example script from the jsr223 directory. |
This PR adds the ability to script rules and all module types (trigger, conditions, actions). It does this by providing a thin layer ontop of the automation classes to by easier accessable from scripts. general features: - Adds ability to register ScriptEngines by OSGi - Adds special wrapper for Nashorn (directly scope classes to types) - Ability to load scripts from a directory - provide functionality to develop script extensions RuleSupport ScriptExtension: - allows scripting of module types. As different jsr223 implementations and in general programming languages have different support and convience it is possible to define thise module types in different ways (using classes and simple handlers) - provides ScriptedAction/ScriptedCondition/ScriptedTrigger which are script private (not meant to be used for compositing outside of the script) - ability to define custom module types. These are meant to be shared and used in other Rule compositions (like the Web-UI) - allows scripting of rules - rules are by default dependant on the script: if the script is deleted or modified, all created rules are removed - two types of rules are supported: - SimpleRule: create rules with a private action handler (SimpleAction) attached - ScriptedRule: no handler attached. Triggers, Conditions and actions have to be added by hand Signed-off-by: Simon Merschjohann <[email protected]>
b694140
to
26833d1
Compare
@steve-bate Sorry, I meant the changes including the changes I made this week. Could you check if this is still happening? The latest change relies on #3218 to have support for dynamic module handlers. @kaikreuzer I have changed the package of the FileWatcher and refactored that class a little bit as it had some conflicts with the latest head. I also added the ability to add custom handlers by updating the moduletypes accordingly. But due to some bugs in the head, I have opened another PR: #3218 Let's see if it can me merged now ;) |
Thanks @smerschjohann, sounds good! |
@smerschjohann I reset my automation-scriptable branch to yours. Unfortunately, I'm not getting a clean build (issues with missing AbstractWatchQueueReader and BundleProcessorVetoManager interface changes) but it seems to work well enough to do some testing. I still see the previously reported exception. It seems to be related to a SimpleRule/Rule object having a null UID. The Rule default constructor has a comment that the UID will be set by the engine. Apparently it's not being set in some scenarios. |
@kaikreuzer hm, I still have the dev branch, but yes those changes were not that big. Mainly the scriptloading, scope variables and a slitly changed SimpleTriggerHandler. @steve-bate actually I have those errors as well, but they don't come from any part of this code. Those problems seems to be in the current master. Nonetheless, they don't seem to influence this PR at all. |
I will have a look at that uid problem |
Ok, so as there was no further feedback resp. any veto, I have created CQ 13331 for this PR and am waiting for approval through the Eclipse IP team - once we have it, we will finally merge this PR! So @smerschjohann please refrain from any changes on this branch from now on, thanks! You and @steve-bate might want to start with the preparation of some good documentation of this new feature! |
Great news, everyone, the CQ has already been approved! |
FTR: #3330 |
Great achievement! I am eager to try it!! |
@smerschjohann WRT #3568 I have a question about the methods of a ScriptExtensionProvider. A provider could contain multiple presets. What about the Looking at a current implementation of |
This PR replaces #803, #806 and #813
It provides the ability to write Rules/ActionHandlers/Triggers directly from script files.
To accomplish this, this PR introduces:
A script loader that can load scripts from a directory and bundles
An import mechanism to allow bundles to provide script dependant classes for scripts. This means: scripts can import class instances via a default interface where the imported instances can have a reference to the scriptEngineId. This allows the unloading of Rules etc. if the script becomes unavailable. This extension mechanism is for example used to provide the following:
The RuleSupport and RuleSimple presets provide the ability for scripts to programmatically add and remove Rules and Modules to the ScriptEngine. By providing the ScriptedRuleProvider, these Rules will only be kept at runtime and will not be persisted on reboot except the Rule will be explicitly added by
addPermanent
. For an example script, see: distribution/smarthome/conf/scripts/test.py