Global little helpers

I created in DSL some little helpers to shorten several times repeated commands like groups.members.forEach[ if… sendCommmand(…)].

These are global variables like:

val groupState = [ GroupItem g, Object cmd | g?.members.forEach [ i | val strCmd = cmd.toString
        if (i.state.toString != strCmd) i.sendCommand(strCmd) ] ]

var rolloUp   = [ GenericItem item, Number cmd | if ((item.state as Number) > cmd) item.sendCommand(cmd)]
var rolloDown = [ GenericItem item, Number cmd | if ((item.state as Number) < cmd) item.sendCommand(cmd)]

So I can easily use them in rules like:

rule "..."
when
    ...
then
    groupState.apply(gShutters_sud, 0)
    rolloUp.apply(Shutter_OG_Schlafen, 20)
end.

Works smart and efficient. But I have to add the global vals to each .rules file, where I need them.

I am wondering, ig there is any possibility (or maybe will be in future time) to set this global for all .rules files or perhabs as public cache.

I’m afraid not. It’s one of the major limitations of Rules DSL. This is possible in all the other rules languages but not in Rules DSL.

You can get part of the way there using Rules DSL Scripts. These are file placed in the $OH_CONF/scripts folder with a .script extension. However, they have limitations. From the docs

Scripts are small pieces of Rules DSL code that can be called from Rules. However, Scripts have limitations. Scripts cannot accept arguments. Scripts cannot return a value. Any reference to a class that would normally need to be imported in a .rules file, the class needs to be referred to by its full package as imports are not supported.

So they are not really useful for this.

Personal libraries for common code like this is really great and it’s standard programming proactice. But Rules DSL is anything but standard and doesn’t support it.

I wonder if this is actually possible in rulesdsl (xtend), but done in a Java way. I haven’t tested this since I’m on the road at the moment, but in general:

Create a .rules file that contains a class like this:

package my.name.common

class Foo {
  def static test(blah blah) { blah blah }
}

Then in your normal rules

import my.name.common.Foo

// use Foo somehow here

Rules DSL doesn’t support creating classes even though Xtend does support that. I never knew why classes and real functions were unsupported in Rules DSL. Since they are supported by Xtend it seems like a deliberate choice on OH’s part to not support them.

Tbh, I expected answers like these. Nevertheless, thank you for the precise clarification.

I should mention that all of the other rules languages do support what you are trying to do. Even Blockly has some ability to create libraries, though there are a few limitations in Blockly. The three big ones, jRuby, JS Scripting, and Python even support using standard third party libraries should you have a use for them.

seems like I have to become a foreign language correspondence clerk :grinning_face:

I switched from DSL rules to Javascript rules a couple of month ago, it is soooo much easier :innocent:

Is there a good practice of or suport for doing this, e.g. a recommended CoPilot or something like that? Thx

Didn’t get your intention clearly. Do you mean the outsourced command (first post) or the transformation into another language?

DSL Rules is Xbase, not Xtend, and Xbase does not have class and def keywords. In detail:

DSL rules are written in a language called XBase. This language is descried in words at https://eclipse.dev/Xtext/documentation/305_xbase.html#xbase-language-ref-introduction. Its grammar is defined in the files xtext/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/Xtype.xtext at main · eclipse-xtext/xtext · GitHub and xtext/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/Xbase.xtext at main · eclipse-xtext/xtext · GitHub . As can be seen from these two files new, var, val are reserved words, while class and def are not. Moreover Xbase inherits from XType.

Xtend is a language described in words at Xtend - Documentation . Its grammar is defined in xtext/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/annotations/XbaseWithAnnotations.xtext at main · eclipse-xtext/xtext · GitHub and xtext/org.eclipse.xtend.core/src/org/eclipse/xtend/core/Xtend.xtext at main · eclipse-xtext/xtext · GitHub . As you can see, the grammar of Xtend defines override, def, class as reserved words. Moreover XBaseWithAnnotations inherits from XBase and Xtend inherits from XBaseWithAnnotatitons.

The only thing I am aware of, which is only described in words for Xtend, but is in fact also part of XBase are the Collection Literals - https://eclipse.dev/Xtext/xtend/documentation/203_xtend_expressions.html#collection-literals. These are available in openHAB version 5.1.

This whole misconception of DSL Rules being Xtend based comes from suboptimal documentation, which was corrected by Clarification: Rules DSL derives from XBase and is similar to Xtend by dilyanpalauzov · Pull Request #2623 · openhab/openhab-docs · GitHub.

Summary

Both DSL Rules and Xtend inherit from XBase. Xtend handles the class keyword, while DSL Rules and XBase do not handle the class keyword. DSL Rules do not inherit from (are not) Xtend.