JRule - openHAB Rules using Java

Sorry for replying so late to this. I can’t reproduce this, could you try and run the latest beta 6. You could also enable debug logging for jrule to give you more information

[15:03:56] openhab@stardust:~$ ssh -p 8101 openhab@127.0.0.1
Password authentication
Password: 

                           _   _     _     ____  
   ___   ___   ___   ___  | | | |   / \   | __ ) 
  / _ \ / _ \ / _ \ / _ \ | |_| |  / _ \  |  _ \ 
 | (_) | (_) |  __/| | | ||  _  | / ___ \ | |_) )
  \___/|  __/ \___/|_| |_||_| |_|/_/   \_\|____/ 
       |_|       3.3.0-SNAPSHOT - Build #2833

Use '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
To exit, use '<ctrl-d>' or 'logout'.

openhab> 
openhab>                                                                                                                                                                
openhab> log:set DEBUG org.openhab.automation.jrule   

Another thing you could try is to add the JRuleEvent to the method, not sure it will change anything but that is where you want value that triggered the rule (see example 3).
Make sure you clean out all folders for jrule, so you don’t have any old java or classes interfering. When updating all your items will be generated again, so try and start fresh and then add the rules (in java-files).

public class LinkindKeypadRule extends JRule {

    @JRuleName("LinkindKeypadRule")
    @JRuleWhen(item = _LinkindKeypad_Action_Transaction.ITEM, trigger = _LinkindKeypad_Action_Transaction.TRIGGER_CHANGED)	
    public void listenForKeypadAction(JRuleEvent event) {
        logInfo("Action: "+_LinkindKeypad_Action.getState()+", tx: "+event.getValue()+", code: "+_LinkindKeypad_Action_Code.getState());
    }
}

Added BETA7 build

BETA7

1 Like

Thank you very much for creating and sharing this! Just got it up and running without any issues.
Going to migrate all my messy Rules DSL scripts now.
Really happy to see this project growing.

1 Like

Have you already managed to look into that?
I’d also like to get an item from it’s name, like JRuleItem.forName("…").


Second question:
When using multiple “JRuleWhen” triggers, how to identify which item actually triggered the rule?

I tried with a group of multiple Number items but changing the value of one item won’t trigger the group.

Do you have an example where you want to use it? If you know the name of the item, you can do _MyItem.ITEM or similar.
If you want to send a command with itemname stored in a variable you can do JRuleSwitchItem.sendCommand(myitem, JRuleOnOffValue.ON)
The problem with JRuleItem.forName(…) would be: What type should be returned? The Generic JRuleItem does not have many methods. JRule relies on the generated items provided in the jar.
EDIT: Yes I could try and add it for the specific types, I promised to that, but it I forgot it.
So you could have JRuleSwitchItem.forName() and JRuleNumberItem.forName().

Take A look at example 3 in the documentation:

 @JRuleName("MyEventValueTest")
   @JRuleWhen(item = __MyTestSwitch2.ITEM, trigger = __MyTestSwitch2.TRIGGER_RECEIVED_COMMAND)
   public void myEventValueTest(JRuleEvent event) {
      logInfo("Got value from event: {}", event.getValue());
   }

An example is given here. The memberItemName is built at runtime.
There are various cases where an item name is not known at implementation-time but needs to be built at runtime. The Design Pattern: Associated Items explains the problem and solutions in python/rules DSL.

1 Like

I already use that method but I also need to know which item actually changed.

Example:
Item_1_Time
Item_2_Time

Now when one of those changes, I want to update:
Item_1_Time_Scaled
or
Item_2_Time_Scaled

I can’t do that without knowing which item changed. :smiley:

Look at example 15, or am I misunderstanding you?

When I use the group as a trigger, the rule won’t get triggered. That’s why I use one “JRuleWhen” for each item.
The group only contains NumberItems, I don’t know if that’s the issue.

I use the same approach (repeat the JRuleWhen for every item) for my window sensors since the group does not trigger the rule.
My guess is that it’s the same as described here.

Oh yes, that’s exactly the same “issue” I have.

Added BETA8 Build:

BETA8

2 Likes

BETA10

  • Optimized items by gerrieg https://github.com/seaside1/jrule/pull/33
  • Syntax change: event.getValue(), event.getValuesAsDouble() etc replaced with event.getState().getValue() and event.getState().getValueAsDouble()
  • Syntax change JRuleSwitchItem.sendCommand(myItem, ON) replaced with JRuleSwitchItem.forName(myItem).sendCommand(ON)
1 Like

I’ve got several Contact items which are sometimes out of reach. In this case, JRule throws an IllegalArgumentException when trying to access the state:

var ct = JRuleItemRegistry.get("GN_CT_DOOR", JRuleContactItem.class)
ct.getState();

This is the Exception:

2022-05-14 11:40:12.269 [ERROR] [on.jrule.internal.engine.JRuleEngine] - [UpdateDisplayHall] Error message: No enum constant org.openhab.core.library.types.OpenClosedType.NULL
2022-05-14 11:40:12.273 [ERROR] [on.jrule.internal.engine.JRuleEngine] - [UpdateDisplayHall] Error Stacktrace: java.lang.IllegalArgumentException: No enum constant org.openhab.core.library.types.OpenClosedType.NULL
	at java.base/java.lang.Enum.valueOf(Enum.java:240)
	at org.openhab.core.library.types.OpenClosedType.valueOf(OpenClosedType.java:1)
	at org.openhab.automation.jrule.internal.handler.JRuleEventHandler.getOpenClosedValueFromState(JRuleEventHandler.java:276)
	at org.openhab.automation.jrule.internal.handler.JRuleEventHandler.getOpenClosedValue(JRuleEventHandler.java:241)
	at org.openhab.automation.jrule.items.JRuleContactItem.getState(JRuleContactItem.java:37)
	at org.openhab.automation.jrule.rules.user.DisplayHallRule.lambda$updateDisplayHall$0(DisplayHallRule.java:90)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.openhab.automation.jrule.rules.user.DisplayHallRule.updateDisplayHall(DisplayHallRule.java:83)

It would be nicer to get UNDEF in this case.

trying to use transform leads to an Exception

final var dayInfo = transform("MAP(DayOfWeek_de.map):%s", dayOfWeek.name());

Result:

2022-05-14 13:01:08.253 [INFO ] [rule.internal.compiler.JRuleCompiler] - [JRuleCompiler] Error on line 54 in file:///etc/openhab/automation/jrule/rules/org/openhab/automation/jrule/rules/user/DateRule.java: cannot access org.openhab.core.transform.TransformationException
  class file for org.openhab.core.transform.TransformationException not found

I have created a fix for this. Have not tested it yet. Will build a new version soon.
See Fixed issued with undef item for state · seaside1/jrule@6827940 · GitHub

1 Like

This is fixed by seime: See: Wrap TransformationException in JRuleExecutionException by seime · Pull Request #39 · seaside1/jrule · GitHub

1 Like

This engine and the support/dedication it gets is awesome.

I’ve reimplemented my 250+ items/50+ rules openHAB 2.5 system with JRule on openHAB 3.2 within 6 hours. Some rules are really complex, but it was really easy to do a 1:1 migration from JSR223 groovy/jython and xtext rules.

Thanks to static typing, I could realize a long-postponed “rename items for more consistency” project without any problems.
Using IntelliJ and gradle instead of VSCode or the openHAB UI for editing really helps a lot.

For me, this is by far the best rule engine available in openHAB since openHAB 1.8.

5 Likes

It is fantastic to see that several people are contributing to the project. :+1:

3 Likes

Built a BETA11

BETA11

2 Likes