OpenHab rules in Java?

I’m looking for a pointer to implementing my OpenHab rules in Java.

I find the Xbase / Xtend based rule language pretty limiting, in particular when it comes to factoring out common behavior across rules. Also, I prefer having a compilation phase in turn-around workflow which tells me if something’s wrong (on a syntactical level, of course).

I absolutely wouldn’t mind building my own rules bundle and deploying it into the OpenHab runtime, whenever there’s a change.

Thoughts?

1 Like

Theoretically I think it should be possible. But for now only Rules DSL, JavaScript, Groovy, and Python (OH 2 only for now, hopefully OH 3 soon) are “officially” supported. I recently saw a thread for someone accessing their own Java classes in rules (it was a pretty big pain) but I’ve not seen anything posted about writing rules in Java to begin with, though it was briefly mentioned by a developer who is no longer active on the project a long time ago.

1 Like

@Spaceman_Spiff wrote HABApp to write rules in Python 3. It is a separate daemon that accesses OH through the.REST API. I imagine something similar could be written in Java.

You are not alone! Look into scripted automation, which is provided by the new rule engine and utilizes the Java Scripting API. You can use almost any JVM scripting language, and they can also use native or custom Java classes. Jython is by far the most used, but I have 2.5.x add-ons for Kotlin, jRuby and Groovy on the way, then I will be adding them for OH3 (there is already a Groovy add-on available in OH3). You wouldn’t get a compilation phase, but there are linters available for most scripting languages and you can immediately test your changes.

Back to what you were asking for :slightly_smiling_face:… you can also utilize the OH automation API (new rule engine) through your own automation bundle. IIRC, there are some examples in the OHC magic bundle.

This is a very compelling idea, especially because of debugging possibilities and using all the bundle lifecycle management tools of OSGI. OTOH, as there is lots of dynamic stuff anyway (eg most objects need to be retrieved dynamically via some text identifier) compiler checks can only go so far.

I saw that GraalVM (which is unusable for OH because it does not work on ARM 32-bit) would also allow debugging (https://www.graalvm.org/advanced-tools/) for scripting, but could not find something easily for OH scripting, apart from classic logging. Is there something available?

No, just logging and the tools available in the IDE that you use to write your scripts. Though, it would be possible to extend the OH VSC extension.

1 Like

I think of eventually generating Java source code with constants representing things and items to avoid having to textually reference them in rules code, so rules code has to compile against these constants.
I.e., if you change your things/items, you may break your rules which is intentional to get feedback at compile time.

Rules themselves are represented as static data structures (no Java annotation BS – have been burned by its limitations). This gives each rule a nice identifier, allowing rule actions to refer to other rules. Any kind of activity (condition or action) is provided as lambda.

Something like this:

class MyRules {
    final static Rule myRule = new Rule("rule name")
    .description("rule for home magic")     // more additional primitive attributes
    .when(item -> item.state == "whatever") // multitude of conditions / patterns which define the trigger
    .handler(() -> {                        // action
        handlingTheRule(); 
    }); 
}

All rules can be swept up via reflection.

I guess as a first step I should get my own bundle in place with my own handler receiving all these events which feed into the existing rules engine.

1 Like

Rule author workflow:

  • Modify the rules in Java source
  • Build with Maven
  • if successful, deploy new revision of bundle jar into OpenHab Karaf
    • what this does to inflight rules provided by earlier revisions of the same bundle, I have to understand (I found hot-deployment into Karaf containers painful)

Highly interesting for me as well. I never fully liked the scripting languages, and the , highlighting etc seems like a compromise compared with pure java on a good dev environment like intellij and eclipse. Possibility to write unittests using mock frameworks etc would be awesome.

I’m a Java developer and I’ve been dreaming of something like this myself ever since I’ve come across openHAB. OH is built on Java so it seems kind of strange that there is no “plug in” mechanism for Java based rules.

Bindings are being tossed in the /addons folder as .jar files and loaded on-the-fly. Why not have the same concept for Java based rules? As of now rules in general must already exist as Java classes inside the openHAB core. A lot of rule based framework stuff and abstractions must already be there to build upon.

Personally I could live without having "live " access to an Item registry. Item values must already be cast to some type within rules anyway. So why not just have a generic “blind” registry interface where you can get an item by name and specified type (e.g. NumberItem) hardcoded in the rule.

Pseudocode:

OHContext context = OHContext.getInstance();
OHItemRegistry registry = context.getItemRegistry();
NumberItem item = registry.getAsNumberItem("MyNumberItem");
...

Of course the rule would break if the item definition would change. But I personally could live with that because items (and their definitions) rarely change once they’ve been created. At least from my perspective. Besides, we’ve been living with that restriction for years in the early days when there was no proper “live” syntax checking etc. - not even a proper code editor in the beginning.

But apart from that Eclipse would provide general syntax checking, type safety, one could build one’s own set of utility classes, etc. etc… All in pure Java.

I also love @m2spring 's suggestion of having a builder. Imagine being able to use the builder pattern to build rules! In Java! With full type safety and in full Java context.

Does that make sense? Any thoughts?

Have you looked at the REST API? You can access much information using http.The easiest way to see it is to install the REST API documentation addon from the User Interface tab.

Or are you looking for a “deeper” API integration?

This is some what what I would want in terms of syntax.


@Rule(name="MyCoolSwitchTurnedOn")
@When(item="MyCoolSwitchItem" condtion="On")
public void handleMyCoolSwitchRuleOn(OHContext context, GenericItem item) {
       context.getItem("MySuperSwitch").sendCommand(ON);
}


@Rule(name="MyCoolSwitchTurnedOff")
@When(item="MyCoolSwitchItem" condtion="Off")
public void handleMyCoolSwitchRuleOff(OHContext context, GenericItem item) {
              context.getItem("MySuperSwitch").sendCommand(OFF);

}
1 Like

Hey @Bruce_Osborne! Correct me if I’m wrong, but this doesn‘t solve the core issue: Being able to write rules directly in Java, running Java code. I think the subject of this discussion is not creating rules via Java code. The point is being able to use Java code inside rules. Lambdas. Inheritance. Custom POJOs with custom utility code. Not having to import the Java(!) Time libraries in a different language, having to deal with all the cumbersome shananigans this entails. That sort of thing. (Just to be clear: Not arguing against JavaScript or Python here - these are very nice languages in their own right.)

1 Like

I love that! Not sure if annotation based configuration would be too limiting, though. But it is very compelling. :slightly_smiling_face::+1:

You can use Java, like the JVM scripting languages, to interact with the OH automation API. Start with the magic packages. And…

Thought I’d already posted about this somewhere…

I’m currently working on a binding for writing rules in java using annotations. I connect to the eventbus to do so. Problem is time but might have something ready in a couple of weeks.

4 Likes