JRule - openHAB Rules using Java

I wouldn’t necessarily call these bad smells. If you don’t care about supporting UI users there is no need to support managed rules.

Post #87 indicates @Seaside may have found a way to support JSR223 which would enable UI support. But after scanning the the beta announcement posts above it doesn’t appear to have been implemented. As far as I know, JRule remains incompatible with UI rules (i.e. managed rules).

This also means it probably cannot be used in transformations.

I do believe it’s an automation addon now instead of a binding which is good and development continues.

@Seaside, one thing I noticed here was it was kind of hard to follow the releases/changes between releases because there are separate posts for each. The template for posts in this section of the marketplace does support a change log. It can be a lot easier for users to see that there is a new release and what’s in that release if the changelog is part of the top post. You can even see that from MainUI.

I think the template has changed a couple times since this was originally posted. The current template is:

> **Please remove this block and other instruction placeholders after reading these instructions**
>
> _:arrow_right: Your add-on must abide by the [Marketplace Rules](https://community.openhab.org/t/about-the-add-on-marketplace-category/123408#community-marketplace-contributing-rules-nov-2-2021-1), make sure to read them before submitting a new add-on._
>
> Remember to add the proper tags:
> - one tag denoting the type of the add-on is required: use one of _binding_, _automation_, _io_, _persistence_, _transformation_, _ui_
> - _published_ is necessary if you want users to see your entry in the UI. If you want to draft it before publishing, don't add the tag now and use the "Show Unpublished Entries" option in Settings > Community Marketplace to see it anyway in the UI until you're ready to add it.
> - self-assess the maturity level of your add-on with one of the _alpha_, _beta_, _stable_, _mature_ tags
> - you can package your add-on as a JAR or KAR file. In the former case, provide a direct link to the binary ending in .jar. In the latter case, provide a direct link to a binary ending in .kar, and add the _kar_ tag (mandatory). Don't name any Karaf feature "_openhab-something_", as the "_openhab_" prefix is reserved for the distribution features and have special behavior.

_[🖍 Add a brand logo here. The first image of the post will be promoted and put as an icon for the add-on when browsing in the UI. Change the alt name of the image to `logo` i.e.:
`![logo](url)`
otherwise it will be shown twice in the UI.]_

_[🖍 Replace with a general description. Everything above the first heading will be shown by default, the rest hidden and behind a "more" button - so remember to keep it short. You can add more heading to document the add-on in more detail if necessary.]_

## Changelog

_[🖍 Optional but recommended: Add a list of the changes you made for each version, as suggested below (remove example sections). The provided structure is for illustration only and can be changed freely.]_
### Version 0.2
- fixed: ...
- added: ...
### Version 0.1
- initial release

## Resources

_[🖍 Copy a ***direct and stable*** download link to a .jar or .kar file here, hosted by your preferred service - GitHub etc.]

_[🖍 MANDATORY: Copy a link to the source code (GitHub repository or other) - the marketplace rules mandate that the source of all Java-based add-ons be available]

And in fact, the way the add-on currently appears in MainUI is a little jumbled.

But over all, if you added and kept up to date a changelog section above the Resources it will allow users to see what’s changing without monitoring this thread or needing to scan through 140+ posts.

1 Like

I’ll try to adopt the correct template with the changeslogs, makes sense to do so.
For UI support @seime has added basic support in the UI, you can view the rules and and enable and disable them, but not edit or run them.

Yes it is an automation addon, that changed very early on, and a lot of new functionality has been added since then.
Transformations are not supported (yet).

Regards, S

Can they be called from another rule? I’d guess not but I’m not sure if the run button uses the same APIs as the runRule APIs. I’m not asking or pushing for anything, just curious. I don’t know how that whole thread works behind the scenes. I’m a little surprised that you can see the rules in the UI but not run them.

As long as the rules are not managed, you won’t ever be able to edit them in the UI though. That’s true for all the languages.

Not from any other “rule-system” no. I’m not sure either exactly how the “Run rule”-button works, but in order to trigger JRules there is a context object etc that needs to be populated, so it’s not that straight forward how they would be run from the UI (probably possible but not super simple to implement).

Regards, S

That could be a problem as manually triggered and when run from another rule there is no context Object (I assume that’s the event from the other languages?). I use this fact in some of my rule templates. To further complicate things, when one rule calls another, it can pass stuff to that called rule as part of the context so maybe that’s separate?

I know all about it from this side. I don’t know the plumbing though.

I Nashorn JS, which was pretty much just raw JSR223 API so it’s about as close to the openHAB Java APIs as it gets from a rule, event would get passed into the rule when it is triggered by an event (OH 4 made event be there for all event triggers, not just Item event triggers). But when a rule calls another rule, the stuff passed is available via this.context.

I’m kind of on the fence on this whole rules calling other rules thing. It has it’s place for sure (see Scenes for one) but it can be dangerous is some tries to use it in place of creating a proper library.

It’s all hard to follow sometimes.

Thanks!

By the way, for everyone here, there is a fully JSR223 java compliant automation bundle made by @weberjn. It is compatible with the openHAB rule system. But it has not the syntaxic sugar that JRule has (I don’t want to speak for @weberjn, but I think he plans to keep its automation “simple” ?). And it is not on the marketplace (yet ?). I’m planning to propose some aditionnal functionallities in the near future (beyond libraries and a “no boiler plate code” option, which is currently ready to be reviewed), if I can still keep it clear and simple.

I want to emphasize that the two automation bundles are not concurrent : they have their own advantages. I’m thinking that maybe we can make a comparison table in the near future, to put it in the open post of each thread ?

2 Likes

There exists also the SmartHome/J Javarule. As you said they all have their own advantages but I’m a bit sad having three distinct java automation bundles.

2 Likes

Version BETA19

Hi, first of all thank you very much for this binding. It’s working great for me so far.

However I stumbled upon an issue with a channel trigger. I declared a rule with trigger:

@JRuleWhenChannelTrigger(channel = "astro:sun:local:civilDawn#event")

But my rule does not get triggered. This is how channel trigger looks like as API Json:

{
      "linkedItems": [],
      "uid": "astro:sun:local:civilDawn#event",
      "id": "civilDawn#event",
      "channelTypeUID": "astro:rangeEvent",
      "kind": "TRIGGER",
      "label": "Range Event",
      "description": "Range event",
      "defaultTags": [],
      "properties": {},
      "configuration": {
        "offset": 0
      }
    }

Anything obvious I’m doing wrong?

I had already accidentally left out the “extends JRule” in the class definition without realizing it for a long time with the same effect as you mention @touitoui just as an idea

@drex Thanks, but unfortunately it must be something different. I can also see:

********   Loaded 1 channel triggers, change 0

in the logs, so the rule should be loaded. I wonder if there’s something wrong with my channel definition “astro:sun:local:civilDawn#event”. I have an UI Rule working, which is defined like this:

triggers:
  - id: "1"
    configuration:
      thingUID: astro:sun:local
      event: ""
      channelUID: astro:sun:local:civilDawn#event
    type: core.ChannelEventTrigger
conditions: []

My JRule annotation should be semantically equivalent, shouldn’t it?

Cannot tell for sure why it does not trigger, but why not use the typed channel names?

Here is a rule I have that I believe is triggered when the sun starts to set

import org.openhab.automation.jrule.generated.items.JRuleItems;
import org.openhab.automation.jrule.generated.things.astro_sun_home;
....

    @JRuleName("Autolight - turn on christmas lights")
    @JRuleWhenChannelTrigger(channel = astro_sun_home.set_event, event = "START")
    public void lightsOn() {
        JRuleItems.Socket_Switch.sendCommand(JRuleOnOffValue.ON);
    }

@seime Thanks for the hint, I’ll see tomorrow if that makes a difference.

It works using generated channel name! Still don’t know why the String version doesn’t, but, who cares :wink:

One of the reasons why I personally jumped on the JRule bandwagon (also as a contributor) was due to runtime rule errors due to misspelled item-, channels, and thing names. The more you can catch up front - the better it is IMHO.

All channels, things, actions and items are represented with types and constants in JRule, and I strongly recommend everyone to use them :slight_smile:

3 Likes

Hello everyone,

I wanted to have a look at JRule and installed it from the marketplace. I have the version Java Rules Engine v4.0.0.202312041914.

Unfortunately I already fail at the first example as soon as I use JRuleOnOffValue.

Only this works for me

package org.openhab.automation.jrule.rules.user;

import static org.openhab.automation.jrule.generated.items.JRuleItemNames.TestSwitch;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRuleWhenItemChange;
import org.openhab.automation.jrule.rules.JRule;

public class MySwitchRule extends JRule {
    @JRuleName("MySwitchRule")
    @JRuleWhenItemChange(item = TestSwitch)
    public void execChangedToRule() {
        logInfo("||||| --> Executing rule MyRule: changed to on");
    }
}

Herewith I get the following error

package org.openhab.automation.jrule.rules.user;

import static org.openhab.automation.jrule.generated.items.JRuleItemNames.TestSwitch;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRuleWhenItemChange;
import org.openhab.automation.jrule.rules.JRule;

public class MySwitchRule extends JRule {
    @JRuleName("MySwitchRule")
    @JRuleWhenItemChange(item = TestSwitch, to = JRuleOnOffValue.ON)
    public void execChangedToRule() {
        logInfo("||||| --> Executing rule MyRule: changed to on");
    }
}
2024-01-22 21:26:25.525 [ERROR] [rule.internal.compiler.JRuleCompiler] - [JRuleCompiler] Error on line 3 in file:///openhab/conf/automation/jrule/rules/org/openhab/automation/jrule/rules/user/MySwitchRule.java: cannot find symbol
  symbol:   class JRuleOnOffValue
  location: package org.openhab.automation.jrule.rules

and with this I get the following error

package org.openhab.automation.jrule.rules.user;

import static org.openhab.automation.jrule.rules.JRuleOnOffValue.ON;
import static org.openhab.automation.jrule.generated.items.JRuleItemNames.TestSwitch;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRuleWhenItemChange;
import org.openhab.automation.jrule.rules.JRule;

public class MySwitchRule extends JRule {
    @JRuleName("MySwitchRule")
    @JRuleWhenItemChange(item = TestSwitch, to = ON)
    public void execChangedToRule() {
        logInfo("||||| --> Executing rule MyRule: changed to on");
    }
}
2024-01-22 21:29:22.019 [ERROR] [rule.internal.compiler.JRuleCompiler] - [JRuleCompiler] Error on line 3 in file:///openhab/conf/automation/jrule/rules/org/openhab/automation/jrule/rules/user/MySwitchRule.java: cannot find symbol
  symbol:   class JRuleOnOffValue
  location: package org.openhab.automation.jrule.rules
2024-01-22 21:29:22.022 [ERROR] [rule.internal.compiler.JRuleCompiler] - [JRuleCompiler] Error on line 3 in file:///openhab/conf/automation/jrule/rules/org/openhab/automation/jrule/rules/user/MySwitchRule.java: static import only from classes and interfaces
2024-01-22 21:29:22.024 [ERROR] [rule.internal.compiler.JRuleCompiler] - [JRuleCompiler] Error on line 11 in file:///openhab/conf/automation/jrule/rules/org/openhab/automation/jrule/rules/user/MySwitchRule.java: cannot find symbol
  symbol:   variable ON
  location: class org.openhab.automation.jrule.rules.user.MySwitchRule

Comment that import, change the rule condition to: to = “ON”
Then try again.

Thanks, that’s how it works.

package org.openhab.automation.jrule.rules.user;

import static org.openhab.automation.jrule.generated.items.JRuleItemNames.TestSwitch;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRuleWhenItemChange;
import org.openhab.automation.jrule.rules.JRule;

public class MySwitchRule extends JRule {
    @JRuleName("MySwitchRule")
    @JRuleWhenItemChange(item = TestSwitch, to = "ON")
    public void execChangedToRule() {
        logInfo("||||| --> Executing rule MyRule: changed to on");
    }
}

@Seaside, I think there are two minor problems with the examples:

  1. The JRuleOnOffValue import is missing the .value.

import static org.openhab.automation.jrule.rules.value.JRuleOnOffValue.ON;

  1. The @JRuleWhenItemChange trigger expects a string for the ‘to’ and ‘from’ options, not a JRuleOnOffValue type.

There has been some refactorings so it could be related to that.
Please report a bug on github and we will try to fix it.