@KjetilA Thank you for your answer - although it does not sound very promising. Are global functions a feature which is planned for the future, or maybe already has a milestone? I am sure many people would like to see this as, at least for me, my problem does not look very special.
If I cannot use a global function, can I use something which I create at the top of the rules file maybe? Like a semi-global function which I can use for all rules inside one rules file?
The solution you suggested will work, yes, but does not sound very practical to me. Then I would stick to my over and over same definitions for the notifications and if I need to change something it will remain a cut-n-paste orgy.
You may use scripts as some kind of global functions. But have to find a convention for yourself to use Items as parameters because you can not delegate script parameters to callScript(“filenameOfMyScript”)
This is one of the driving requirements behind the creation of the Experimental Rules Engine. Kai’s vision is we would have ready made off the shelf rules that users can download and install from the IoT Marketplace. No more copy and paste from examples in the forum.
So, in addition to lambdas and what might be coming in the future, a great way to handle cross-cutting code like this is Design Pattern: Separation of Behaviors. This is particularly handy for notifications as it lets you add additional logic around alerts more easily (e.g. use a different mechanism at night than during the day).
@opus The big difference here is for me that putting all rules into one file creates a big pile of sh*t and looks like programming back in 1990 and also would not show the intention of the openHAB idea behind this - in my eyes. Also I imagine that putting everything into one file creates more problems, e.g. when putting a typo into one of these rules which causes all rules to fail at once as the updated file might not be loaded into openHAB anymore.
I think what opus was intending is not that you put ALL rules into a single file. If you organize your files by function, you will be very unlikely to need to access any lambdas from some other file. And if you do have a cross-cutting concern like alerting or the like, you can use the Separation of Behaviors to call those.
Well, the problem is that I e.g. want to make notifications from many different functions - so there we have the problem. I understood opus not like you. In my understanding he suggests putting everything into one big file and use lambdas then.
As usual, my answer was not as precise as the one from @rlkoshak.
The quick anser was to put everything into one file, the more elaborate(as said by @rlkoshak) is to seperate by function, by that the rules needing a specific lambda could be in a seperated file.
Since you do forsee the need for such a lambda in (nearly) all your rules you could find yourself in the single file situation.
@rlkoshak I completely agree with your thoughts about ‘programming in the 1990s’.
I have some complex rules, resulting if .rules files close to 64kB, thus it’s a bit of a nightmare to debug. It also takes very long after saving the file before it’s compiled and it starts executing.
So I tried to put a bunch of the lambda functions in a .script file.
However, you cannot call includeScript(“name_wo_ext”) outside a rule (thus global within the .rules file.
So my next try: include the .script in the rule. Yes, no error. However, I cannot call the lambda functions. It seems they only exist in the context of the .script file. Nasty!
Apparently there are no ways to trick the system.
At least, I couldn’t find them.
But you never know…
What I haven’t tried (since so far it always resulted in errors within the .rules files), is to define a class. I mean: is that somehow possible? In that case we might be able to simply use an include a.b.c at the top of the .rules file and call the methods.
Unfortunately I haven’t found any examples, so whether this is or isn’t possible… who knows.
In the meantime I’m a bit fed up with the limitations of xtend, so I’m doing more and more in PHP. For me this could end up in using openHAB as just the bus and the drivers for the hardware and doing all the automation logic in PHP.
Or if you want something easier to use configure NodeRed as your Rule engine.
Or, as illustrated in the DP I linked to above, there are techniques and best practices one can use to avoid duplicated code in Rules DSL that don’t involve lambdas. Based on experience, you can probably reduce your lines of code by 60-80% using those techniques.
Thank for the feedback.
I wasn’t aware that classes aren’t possible; that saves me some time in fruitless attempts.
I haven’t explored the JSR223 route yet.
On the other hand I have my UI in apache/php anyway (it’s an alternative remote control UI, as well as a configuration UI for my automation rules – program once, configure many), so it’s not such a big step to do even more in php.
The reason why my rules are rather large, is because the OH rules are basically interpreting my configuration. Thus I don’t mind to use the OH REST API even more than I do now.
There’s another reason why I like php: it’s very well documented.
In my experience Xtend is a real struggle; never happened for such an elongated period for any other languages / libraries I’ve used over many years.
Anyway, I’m keeping an open mind – and I don’t mind completely redesign at a point in the future if some new promising route becomes available.
I know this is an old thread, but I stumbled upon this a few days ago via google. Since there isn’t an easy way to do global variables / functions in the default rule engine, I decided to code myself a tool to allow this.
I know the general advice to get reusable code is to use “virtual” items with a rule attached to them, but that gets messy quick in my opinion.