Strange behaviour in Rules UI using previous state of item

  • Platform information:
    • Hardware: RPi 4/4G
    • OS: openHABianPi 5.10.103-v7+
    • Java Runtime Environment: Zulu11.50+19-CA (build 11.0.12+7-LTS)
    • openHAB version: 3.3.0.M3

I thought I would be smart advising a newbee friend of my to use the openHAB rules GUI - that was until he came up with this…

He is reading the actual power consumption of their dishwasher into an item called Diskmaskinen_Electricmeterwatts. That obviously works as intended:

2022-08-08 17:28:50.958 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Diskmaskinen_Electricmeterwatts' changed from 0 to 0.532
2022-08-08 17:28:57.058 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Diskmaskinen_Electricmeterwatts' changed from 0.532 to 12.324
2022-08-08 17:29:00.659 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Diskmaskinen_Electricmeterwatts' changed from 12.324 to 3.954

He created a rule to catch when the dishwasher starts based on the fact that during idle, the dishwasher draws ~<0.7W and when it starts, the power goes to >10W during initiation of the wash cycle. He created a rule using the rules GUI as per below:

The WHEN-clause is defined as:

The problem is that the rule does not react at all to changes in the Diskmaskinen_Electricmeterwatts item. In the log, the item changes value as expected but the rule sits silent. It seems as the previousState/state clause is not behaving as I would expect.
(Yes, the item is defined as Number:Power and reports perfectly good readings)

On trying to figure out what was wrong, I naturally looked at the code of the rule and to my surprise it seems like the current state is treated as a string whereas the previousState is (correctly) interpreted as a number?!

I tried removing the previousState part in the GUI and the rule kicked in but was of course running the rule for every cange in power level.
Being a text-based-rules kind of guy I am out of clues as to what is wrong here - typically me, but… :wink:
PS: Sorry about the swedish gibberish in the rule but I take it you can decode it…

Just to avoid confusion:
I know there are a few state machine apps available for openHAB but when this rule is functioning, it will be calling a code I wrote to get the electricity spot prices in Sweden and advice the user if the prices are lower in the “near” future and possibly delay the start of the appliance until then.

As far as I know operator like “<” or “>” are not allowed in the State definitions.

For your goal: Just let the fields for the States empty, so the rule will trigger with every change.
You define your condition in the rule here:

1 Like

You are correct, Sebastian, it seems that even though the previousState value seems to be recognized as a number, it does not work. I’m not clear why the interpreter allows for values other than e.g. ON, OFF and so on but that is the case.
Unfortunately, using the “But only if” clause will not give access to previousState and hence the possibility of creating a rule that triggers on previousState together with (current)state is gone.
On skimming the documentation I can not find anything on numeric vs text states but I’m sure it is there somewhere.
I’ll mark your answer as Solution (even if it is more of an explanation to a somewhat odd behavior)
Thank you /bp

Both in this case are treated as Strings. I don’t know why only one has quotes but both are Strings. It will compare that String to the toString of the incoming state or command. And of course <3.0 isn’t a valid Item state for any Item except a String Item so if you have a Number Item, it’ll never match.

As @Tuny explained, you can’t do math or comparisons in the previous state and state (or any other) field in a rule trigger.

Because you may want to only trigger the rule when a Number Item changes to exactly 3, or a String changes to exactly Awesome Sauce or changes from OFF to NULL.

You’ll have to use the Script Condition and do the comparison there. You have access to newState and previousState (or equivalent for what ever language you are using) same as you do inside the Action of a rule. Blockly is a good choice for people who don’t know how to program. See the Getting Started Tutorial for how to write a Script Condition using Blockly.

Yes, that is kind of the thing that got me wondering: should an item that is a number (here Number:Power) be included in the list where the user selects what item to include in the trigger and be allowed to use numeric comparison? Absolutely if the item is a string - but a number?? I copied every step in his definition in the GUI and there were no warnings or error messages. I mean a string may have a value of e.g. “<3.0” but a number can not. No big deal, but…
So, I guess your advice is for him to use the GUI for simple rules but use Blockly to design the conditions? Seems fair enough as I don’t think he will end up as a Haskell developer any day soon.

Speaking of scripts: There must be loads of discussions among openHAB developers/users regarding Blockly vs ECMAScript vs Rule DSL. Is there any document where the developers of openHAB describe the future of rules/scripting in openHAB? Like a roadmap if you will. Any pointer would be great.

Thank you for all your efforts developing openHAB further!

I’m not sure what you are asking here. Should triggers on Number Items be allowed to use the previousState and state fields? Yes of course. There are times where a Number Item might be used with only a few discrete and well defined values. For example, maybe they are using a Number Item with a mapping on the sitemap for a three or more phase switch.

Should the UI do some sort of checking to prevent putting in a meaningless previousState and state for the various Item types? Perhaps but that’s going to be really complicated code to cover all the Item types, states, and commands. It’s not impossible but it’s going to be tedious and complicated which is probably why no one has volunteered to implement it. And implementing it could run the risk of breaking some use cases inadvertently.

Yes, at least for this case where the previous state is needed. I also recommend always looking to the marketplace for rule templates that may do what you need before coding things yourself. Why write code when you can just install it?

Probably not as much that you may think. Each has their own maintainer and group of developers and there isn’t a lot of overlap between them. I can give you Rich’s opinion only.

UI Code

  • UI Rules: I can’t imagine these going away at any point. Over time more interesting actions and conditions will be added making it able to support more complicated rules, but it will always be only for the most simple of use cases.

  • Blockly: A lot of work has recently been put into Blockly to make it complete when it comes to OH features. And even when/if the underlying language that the Blocks “compile” into loses support, it can be adjusted to use a different supported language. So Blockly is likely here to stay.

“Legacy” Languages

  • Rules DSL: will probably be pulled out of core and made a separately installable add-on at some point. It depends on the upstream Xtend project and when/if that ever stops being maintained, Rules DSL support will likely end in OH at some point.

  • Nashorn JavaScript (ECMAScript 5.1): This is using a JavaScript engine built into Java 11. However, Nashorn is no longer included in later versions of Java so it should be treated as deprecated. There is an add-on that is in the Marketplace that enables the continued use of Nashorn in later Java versions when OH moves to Java 17. But it’s a really old version of ECMAScript so should be treated as maintained for legacy support. To write rules efficiently, this requires a third party library that is installed via a git clone and copy of the files.

  • Jython: This provides Python 2.7 which is two years+ end of life. The upstream project’s support has way slowed down and there is no indication that a Python 3.x version will be forthcoming. It also depends on a separately installable helper library to write rules in it efficiently that is not a part of the openHAB project and requires cloning the repo and copying files around.

  • Groovy: This is and has always been a niche language with just a few people using and writing about it. But it’s been supported in OH forever and I see no reason that would ever change. I’m not sure if it works in UI Script Actions and Script Conditions.

New Languages in OH

  • JS Scripting (ECMAScript 2011): This is a much more recent version of ECMAScript. When Blockly needs to move off of Nashorn it will probably move here. This is the only rules language where the helper library is both a part of the OH project and included in the add-on so there are no extra steps to code efficiently. It also provides equal support in writing Script Actions and Script Conditions in the UI.

  • jRuby: Of the modern supported languages it is the second most mature. My only dings on it are the helper library must be separately installed and it is not a part of the openHAB project and they were late to support UI Script Actions and Script Conditions. But if you like Ruby it’s a great choice.

  • JRule: Lets you write rules in pure Java. Does not support UI Script Actions and Script Conditions at all.

Outside of OH Options

  • There is at least one other language supported in the third party SmarthomeJ Marketplace that supports writing Java rules even in the UI Script Actions and Script Conditions.

  • HABApp is a separate rules service written in Python 3 that interacts with OH through its REST API.

  • Node Red is a separate graphical rules service that also interacts with OH through its REST API.

All of these are equally supported. Some have more continued development (e.g. JS Scripting and jRuby) than others (Nashorn and Jython) but all are equally supported.

I personally would stay away from Nashorn, Jython, and Rules DSL if you are just getting started. If you are not a coder I’d recommend Blockly. If you have no other preexisting preference for any of the specifically supported languages I’d choose JS Scripting because it’s the best documented and lest work to get up and running. Otherwise, choose based on your favorite language.

My guts feeling says Rich’s opinions are always worth listening to :wink:
Thanks a lot for your answer; very valuable for me as it covers most aspects of the current state as well as what the prospects for future developments look like. For me, your overview result in two conclusions:

  • I can safely tell my friend to learn and use Blockly
  • Myself, I’d better start moving away from good ol’ Rules DSL to JS Scripting.

Great intel, thank you Rich!