Confused on what kind of rules / rules engine I should be using

Preamble: I’ve been using OH for a few years, got started back in OH2 and transitioned to 3 pretty quickly. I’ve also been a developer for decades. My OH runs on a rpi.

When I first started playing around with OH, it looked like there was currently a huge refactoring going on. Sitemaps were changing to pages (I think that’s correct?), rules and things and such were moving from individual text files to some new thing built in the web UI, etc. I made the decision to jump on the new bandwagon- why start using it the old way when the future is here? (Plus, let’s be honest, designing a rule in the web UI was easier to grok for a new user, and programmers are inherently lazy. Ones dabbling in home automation even more so.)

Now, my house isn’t super automated. But I’m trying to get fancier. And yesterday, I’m trying to build a state machine to control my HVAC system better than slew of cron-based individual rules that have accumulated over the years into a hairy mess. Long story short, I test it and it doesn’t work. I try to debug it, and it’s a pain from the web UI. So I search, and I see Rich say I should really be using vscode and an extension to write my rules. Sweet, I already have Code, so I install the extension and hook it up. But I only get my Things and Items… even mounting /etc under NFS to my desktop doesn’t help.

After further reading and digging, I guess all the rules I’ve written over the years are basically useless because not only are they stored in some json file somewhere, but they’re a whole different language that’s only used in the web UI, which feels like a dead end to me since it doesn’t look like anybody is using them.

So, I’m slightly aggravated because I thought I was future-proofing myself back when I decided to do things the “new” way. But it looks like I actually hamstrung myself and the “old” way doesn’t seem to be going away any time soon. Add in a slew of different languages you can use to make automatons, and the impending release of OH4 which possibly has its own changes to the above, and my head is spinning.

So I’m at a crossroads and I’m looking for advice. I was already halfway planning on redoing everything, so remaking my rules and stuff isn’t a big deal for me at this point. What I mostly want is something that’ll be well supported for years to come. Will OH4 bring additional changes to this? (I’ve been unable to find anything.) If the built-in rule language isn’t standard / the best, what is?

tl;dr: I’m a programmer looking to start fresh on my rules. What is the best, most supported, most future-proof way of creating them?

Thanks for the help, and sorry for the novel.

1 Like

What language(s)?

Not changing, sitemaps and MainUI (and HABPanel) live side-by-side. But MainUI is by far the most capable and most complete UI which is why it’s the default. It’s the only UI that serves as both an end user’s UI and an admin UI.

Again, not so much as moving from as being given emphasis. Even in OH 2.x it was possible to define Items, Things and even Rules in the UI (the now defunct PaperUI). But it was awkward and not very user friendly to do so, so much so that even in the official docs it was recommended to only use PaperUI to discover Things and use text files for everything else. In OH 3, with MainUI’s introduction, that advice changed to emphasize UI to create and manage everything supported. But the text based ways are still supported and available.

Are you aware of rule templates? I have published a time based state machine for solving use cases like these. Time Based State Machine [3.2.0;3.4.9]. Rule templates can be installed and a rule or rules instantiated from them. So all you’d have to do is configure the rule and Items as necessary. In this case, you’ll create a set of DateTimeItems with static datetimes or datetimes from some other source (e.g. Astro, iCal, etc.) and the rule will command a TimeOfDay Item with a String representing the current time of day state. You can use that String to drive the rest of your rules.

That’s probably a really old post. But the advice is still true if and only if you are writing your configs as text files and not managed (i.e. in the UI). And even then the code checking only supports Rules DSL so if you are using some other language, VS Code doesn’t buy you much.

This isn’t correct. More and more is moving towards managed configs (i.e. that stuff in the JSONDB) as the emphasized approach. But, like I said, you wouldn’t be using VSCode for managed rules anyway.

If you do want to use VSCode, then you need to stick to text based rules and not defining rules through the UI.

As for the formatting and language, it depends a lot on what you’ve done. A UI defined rule is defined and serialized as a JSON string. This “object” consists of zero or more triggers, zero or more conditions, and zero or more actions. There is an option to write conditions or actions as a Script. The Script can be written in any programming language you have the add-on installed to support (in OH 3.4 you get Rules DSL, Nashorn JavaScript, and Blockly by default; in OH 4 you only get Rules DSL by default and must install an add-on to get the other languages).

When writing a rule in a text file, the whole shebang is written in the language chosen.

But I can say that the vast majority of users these days are using UI rules over text based rules, if the activity on the forum are any indication.

Both ways will continue to be supported for the foreseeable future. Though even on OH 2.x some things were not supported in text based configs (e.g. you can configure device parameters for Zwave devices when using .things files) and support for file based configs for new stuff may not materialize (e.g. custom UI widgets for MainUI) or may not make any sense as text files (e.g. Blockly).

So either way, managed or file based, you are future proof.

Not really. Mostly just Nashorn JS has moved to an add-on instead of being there by default and Blockly now requires the GraalVM JS Scripting add-on and “compiles” to a more modern JavaScript than Nashorn JS. Rules wise, everything is pretty much the same, with some new stuff added but full support for all the old stuff remaining.

The “DSL” in Rules DSL stands for Domain Specific Language. It’s largely based on XTend (a relatively obscure language) with lots of customizations for openHAB. For a long time I’ve advocated users who are programmers to not use Rules DSL. Since the release of OH 3.0 I’ve advocated new users who are not programmers to use Blockly instead of Rules DSL.

Over time fewer users will continue to use Rules DSL as their rules language of choice. And it might be the case that something happens upstream in XTend which may make OH’s continued support untenable, but that’s true for all the OH languages.

I wouldn’t start with the Jython add-on today. It’s stuck on Python 2.7, upstream shows no indication that Python 3.x support is coming anytime soon (and even if it did I’m not sure there is anyone left on the OH side to adopt it). If Python’s your thing, look into HABApp.

Beyond that, choose what ever language is closes to what you know. Decide if you want to stick to file based or managed rules (I’ve moved to managed because it has some advantages, not the least of which is rule templates can only be written as managed rules). I think the Java and maybe Groovy add-ons do not support UI rules (I really know very little about Groovy so could be wrong on that).

The two most mature languages with good built in helper libraries (abstract the Java which openHAB uses to native language Classes, Objects, and ways the language work) are GraalVM JavaScript and jRuby.

You don’t have to choose just one. All of these add-ons can live side-by-side and you can write rules in all of them at the same time. So you can experiment to see what works best for you.

Speaking from a personal perspective, to get a data point of one, I started with Rules DSL in OH 1.5. In OH 2.3 (IIRC) I moved everything to Jython in text files. In OH 3.0 I moved everything first to Nashorn JS managed rules. I can’t remember when but I was able to influence the direction of the GraalVM JS Scripting to make it better support managed rules. Because of support for modern ECMAScript and a good helper library greatly improved the overall coding experience, I moved once again to that.

A lot of people are very happy with jRuby as well which was a little behind on the managed rules support but has since caught up.

And a lot of work has gone into Blockly to make it feature complete with all the other languages so the less technical users do not have to give up on language features and capabilities for the easier to use coding environment.

tl;dr: Pick what ever supported language floats your boat. Decide if you are happier using VSCode (text file based) or MainUI (managed) to write your rules. Experiment a bit. Nothing currently supported in OH 3 is planned on going away in the foreseeable future. The only risky one I see is Jython.

3 Likes

You name it. I have moved around a lot over the years. I started with C and ASM, and I’ve learned Python, Java, Rust, JS, Ruby, and a few various DSLs over the years. The problem with this is that while I can read and play around with many, I lack the expert knowledge in most.

I am (somewhat) aware of them, and I looked at your state machine. I ultimately chose to try my own hand at it because 1) I wanted to learn, and 2) it was hard to wrap my mind around the initial setup. Most likely because it is I that don’t know what I want yet, so it was difficult to read your documentation and think “oh yeah, that would be X in my case”. I somewhat expect your template to be phase 3 of my automation roll out. :smiley:

But maybe I should give it another chance now that I’ve written at least some code.

Thanks, this alleviates a lot of my stress.

I did look into that a tiny bit. It looks pretty crazy and has a bit of momentum. But it’s also an extraneous process that I’d need to worry about failing. Maybe I’m just old school. =)

Thank you so much. Not just for this incredibly thoughtful reply, but for everything else too. I’ve been lurking in the forums for awhile researching this stuff, and you’re one of the pillars. I’d like to take this opportunity to thank you for all you do.

Anyway, to cap things off, it sounds like sticking with managed rules will make the most sense for me. For one, things are moving in that direction, but mostly because I can see myself moving to something more robust like your state engine in the future. The only problem I have is it just feels like I’m back in the early 90s when I’m working in that UI. No intellisense. No debugging. No help of any kind. Nothing but an empty text file. Am I missing something? This can’t be how you developed your stuff.

And you have the author here so ask if anything is confusing or not clear.

That’s pretty much the main reason I don’t use it too. That and in order to keep up my chops to help on this forum I need to be using what most newish users will be using. And Rule Templates which, I’m sorry there are not more people writing.

HABApp is very capable, is well supported, and has a lot of users so no one would go wrong by using it.

There is some:

It’s more or less capable depending on the language you are using. It’s not super but for JS Scripting at least the entire helper library is in there in addition to what you’ve defined in that Script already.

I think Java rules support debugging. It might be possible in the other languages too. I never really hit a point where I’ve said “I wish I could attach a debugger to this!”. Rules should be relatively short and sweet, independent, and simple most of the time. A few debug logging statements is plenty for me so far. Most of my rules (that are not based on a template) look something like this:

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: Large_Garagedoor_Opener
    type: core.ItemCommandTrigger
  - id: "2"
    configuration:
      itemName: Small_Garagedoor_Opener
    type: core.ItemCommandTrigger
conditions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: items.getItem('vCerberos_Status').state !=  'ON' ||
        items.getItem('Cerberossensorreporter_Onlinestatus').state != 'ON';
    type: script.ScriptCondition
actions:
  - inputs: {}
    id: "4"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: >-
        var {alerting} = require('rlk_personal');

        alerting.sendAlert('Attempting to trigger a garage door but cerberos is not online!');
    type: script.ScriptAction

Note: that’s what you see on the “Code” tab and it’s a YAML presentation of the underlying JSON.

Notice the actual JS code here just a few lines of JS code. The rest is defining the triggers and rules proforma. The average lines of code for my non-templated Script Actions and Script Conditions is around 10, maybe less. A debugger would just get in the way for something so short.

But if you look at most of my rule templates (especially the ones I rewrote in GraalVM JS Scripting for OH 4) you’ll find they are way longer but also that easily half if not more of the code is checking the configuration so that it can produce meaningful errors for the end users. If I were writing these for myself, they’d be much simpler and much less informative with the error messages and they would easily be half the length and complexity.

There’s also the problem that stopping a rule in the debugger can have knock on effects as subsequent triggers of the rule queue up.

The help will be in the docs for the most part.

Specifically for JS Scripting you’d look at:

  • Rules | openHAB : parts of the rules and core concepts that apply no matter what rule language you use
  • Rules - Advanced | openHAB : really you should have gone through the whole Getting Started Tutorial if you haven’t already. Those users who have the most trouble with OH 3 are not new users, it’s OH 2.x users who neglected to review Getting Started
  • JavaScript Scripting - Automation | openHAB : reference guide for coding rules in GraalVM JS Scripting, the other automation add-ons will have similar reference guides or links to similar reference guides (note that except for Rules DSL, documenting the base language is outside the scope of the reference, if it’s generic JavaScript you’ll not find it documented there and need to look elsewhere like W3Schools or StackOverflow or something)
  • JSR223 Scripting | openHAB : documents all the core openHAB API stuff for rules; it’s yucky which is why there are helper libraries for most of the languages but my rule templates written for OH 3 were written with Nashorn JS without a helper library if you want to see what coding with the raw API looks like

If you wanted to code jRuby instead, you’d replace the third link with the link to the jRuby add-on docs.

These pages kind of build on each other. First you find the core concepts that make up a rule that apply no matter what language you are using. Then Getting Started gradually builds from the simplest of rules through Blockly until finally a Script Action and Condition example using JS Scripting. Then the JS Scripting add-on documents the add-on and the helper library that tells you how to interact with OH in that language. Finally, if there is something that the helper library doesn’t support, you can muck around with the raw OH API (and file an issue to get it added to the helper library).

Yes, with these docs that’s all I really needed. I have the logs on one screen, MainUI on another, and the docs open in a tab somewhere behind and away I go. I wrote the Debounce rule template in an afternoon. Time of Day State Machine took a couple afternoons. Threshold Alert I’m not sure I still have right, but it’s such a Swiss army knife of a rule that I’m not sure I’ve covered all the edge cases.

Most of the time, when I do run into a thorny trouble, it’s going to be something to do with timing between events/triggers or the like which would turn into a Heisenbug if I were to attache a debugger anyway.

4 Likes

That’s incredibly generous of you. I’ll take advantage of that…

OK, thanks for cluing me in on this. I wasn’t seeing any because of two reasons: 1) I didn’t have the fancy JS automation installed and was still using the old included one, and 2) I was trying to do it in the rule context, instead of the script context. I’m seeing what you’re seeing now, so I’ll need to play around for a bit.

OK, that was overly dramatic. What I meant was that there’s no help in the editor, which was just a blank canvas.

That… might have been me? Honestly it was so long ago I don’t remember. But I didn’t write many rules in OH2 so it might not have impacted me either way. Either way, I humbly admit I spoke out of turn when I falsely claimed there was “no help of any kind.” It was wrong of me and unkind to say something about OH which certainly has plenty of documentation and help for those that choose to search for it. Anyway, if I’m going to write bigger rules, I had be re-familiarize myself with the docs, and I thank you for giving me a shortcut with some links.

You have no idea how happy it makes me that this term is still in circulation amongst us.

If you have suggestions for what could be added to the editor to help we are more than open to pursuing it. We are not under the impression that everything is super easy to understand and use so if there’s anything we can do to improve things in the UI we should.

Blockly is a little more intuitive because you get the menu on the left with all the blocks you can use. But for text based scripts indeed, you end up with a blank screen.

Maybe pre-populate it with a comment and the URL to the reference docs for that language, or add that to the bottom bar?

1 Like

Looks like I have other problems to diagnose. Trying to install your fancy rules library I get npm errors. Hell, just typing npm gives me npm errors. Obviously I got issues. Urge to reinstall rising.

Anyway, let me answer your question.

I think that’s a good idea.

What would have helped me get started quicker would have been a link to the library docs. For the beginners a note that pressing ctrl-space brings up a context menu of options might be nice too.

Now, a slightly more difficult thing would be slightly more debugging options. Having a sidebar (or a terminal-like window at the bottom) to show console output or the like would be nice. I’m fully able to ssh into my OH instance and tail the logs, but many people wouldn’t be at first. And hell, I’d use that too because it’s faster. Bonus points if it only shows output from the rule you’re developing. I can see that being nice if you have lots going on in your logs.

1 Like

I probably can’t help with that. I had issues myself on a machine not to long ago with npm comparing about the OpenSSL version. I was trying to install Bitwardencli, ironically enough to make it easier to publish updates to my npm library. IIRC a purge of NodeJS and npm and a reinstall worked for me.

I’ll file an issue later today unless you want to make a go at it.

I’m not sure of the technical feasibility but it never hurts to ask.

openHABian comes with Frontal configured with openhab.log and events.log. That does those logs in the browser and I believe appears as a UI option in the overview page. Frontal is also really easy to set up yourself if not using openHABian.

The developer sidebar (alt-shift-d) in MainUI also has an option to show the live event stream and it’s filterable.

There has been some work to add frontal like capability to MainUI but I don’t know the status of that work. It will require changes to both core and the UI to introduce a new logs API endpoint.

By default each rule gets it’s own logger and frontal definitely supports filters and I’m sure what ever they built into OH will to.

More, you can also set the logger name yourself in the rule but by default it will use something like org.openhab.automation.<rule uid>.

Filtering on logger name it’s convenient. However, keeping up with the item events is equally important as that tells you what states they are in and changing to which is usually what triggers a rule in the first place. So looking at just the rule logs is rarely sufficient.

1 Like

Forget about OH rules engine and start using NodeRed. Disconnecting logic from hardware is the proven way to mitigate obsolescence. I use it for 7 years already and can still maintain all my rules easily, while upgrading OH.
Just keep a thin interface between the two (like MQTT for example) and you will be able to upgrade both independently or replace OpenHab with automation of your choice, while not needing to rewrite all the rules.

I may take a look some day, but that style of programming doesn’t really appeal to me. Also, I presume I’d have less options for support if I used NodeRed.

Well, it‘s not even a programming. But that is the point - you don‘t have to learn a programming language to create automation rules. I think home automation should be just like that.
For support you can go to their forum, and the good thing there - they have a community library, which allows you to reuse many patterns.

NodeRed is not part of openHAB, but there is Blockly as a graphical Rule solution.

You can setup a bunch of different software tools and get all of them updated, but that’s not the easy way (though it might be for someone).

KISS is a basic principle, and although openHAB is a highly complex piece of software, it won’t get simpler by adding NodeRed :slight_smile:

openHAB is meant as a generic gateway between hundreds of protocols and hardware interfaces, it’s not only about UI nor automation.

There is a PR at openHAB Core that adds the required API endpoint, but there has not been any recent activity: Add log SSE endpoint by ghys · Pull Request #3345 · openhab/openhab-core · GitHub

Can you please ping me on that UI issue once you created it?

Simple is always something very subjective and for many people other rule engines make creating rules simpler thus leading to a simpler overall system.
And while Blockly is a nice and easy start for beginners it’s of course no match for NodeRed (because it never meant to be one).

I would really love to have this implemented so I can process the openHAB error messages in HABApp without having to read the physical log files. Imho the only thing that’s missing is to specify a log level filter which will be applied to all messages.
@J-N-K Do you see this as something that would / could be supported by websockets, too?

Better late than never.

There is a LogReader binding which might work for this in the mean time.

Actually I’m using OpenHAB only as generic Gateway between hundreds of protocols and interfaces and here it’s power. But I have absolutely no single rule or automation there. They are all in Node-Red and only there. So I still think it’s simple, cause I haven’t added any single peace of additional complexity to OH.

And that’s ok.
But that’s because you already have Node Red.

Please don’t write

That’s a No-Go.
I won’t advise you not to use Node Red although it adds complexity (two pieces of software instead of one)