Getting Started: Rules - Introduction

This has now been merged into the main docs (should be available sometime in the next day or so after the next build). Thanks for all comments and edits! I’m closing this thread now. Please see Rules - Introduction | openHAB for the latest version. If you have questions open a new thread. If you have comments or suggestions please click the link at the bottom of the page to open an issue/PR./

I’m returning to the Getting Started Tutorial. This is a first draft before I submit it to the official docs to give people a chance to review and make changes. It’s a wiki so please edit as necessary and leave a comment.

Thanks.


Thus far we’ve connected OH to devices through Things, modeled the devices with Items, discussed persistence and how to build the display to control your home. But all of that amounts to home control, not automation. To create home automation we need to define behaviors. In openHAB behaviors are defined using rules. Almost anything you can think of can be done as long as you have a relevant event to kick it off and access to the data needed to decide what to do.

Event Driven

openHAB is an event driven system. What that means is an event happens and parts of openHAB that watch for that event can react. Persistence will see an Item change event and save that new state to the database. The UIs will watch for that same Item change event and update the UI widgets as necessary. And some rules will trigger when that Item change event occurs to create some behavior.

For example, the behavior we want is to turn on a light (represented by the Item Light) when motion is detected (represented by the Item Motion). To create this behavior we could create a rule that triggers on the event of the Motion Item receiving the command ON that sends the command ON to the Light Item.

This is a very simple example though. What if you want to keep the light on until 5 minutes after the last motion was detected, but only between the hours of 16:00 and 23:00 on weekdays or when no one is home? Rules can do that too.

Parts of a Rule

A rule consists of three parts.

Name MainUI Section Purpose
Trigger When List of the events that cause the rule to run.
Condition But Only If Conditions which must be true before the rule is allowed to run even when triggered
Action Then Actions to take when the rule runs.

Any single rule is not required to have all of these (although a rule without an action is not very sensible) and in many cases multiple instances may be required. A rule that should always run when triggered will have 0 conditions. A rule that should respond to several different types of events can have multiple different triggers. A rule that is only ever called by another rule or run manually can have 0 triggers.

Triggers

Rule triggers are always evaluated with an OR. If there are two triggers listed, read that as “if x occurs or if y occurs”. The following table is a list of the most common events that can be used to trigger a rule. Triggers of different types can be used on the same rule.

Event Category Purpose
was updated Item triggers the rule when an Item received an update, does not necessarily mean it changed state
was changed Item triggers the rule when an Item changed state after an update
received command Item triggers the rule when an Item is commanded; a command does not by itself imply that the Item received an update or changed
a member was updated Group triggers the rule when any member of the Group is updated
a member changed Group triggers the rule when any member of the Group changes state
a member received command Group triggers the rule when any member of the Group receives a command
a trigger channel fired Thing triggers the rule when a trigger type Channel on a Thing generates an event
status was updated Thing when a Thing’s status is updated, does not necessarily mean it changed
status changed Thing when a Thing’s status changed (e.g. went OFFLINE)
on a schedule Time uses a cron expression to generate a periodic trigger for the rule (e.g. every five minutes)
at a fixed time of day Time selects a specific time of day to trigger the rule
the system is being initialized System when openHAB is first starting up and reaches a given runlevel

In addition to these events which are configured on the rule, a rule can be called from another rule and a rule can be run manually.

Almost all of the time, an Item or a Time based trigger will be used by most users. System triggers are useful to do some sort of initialization step.

Conditions

Conditions are primarily a concept in UI rules though some rules languages support them in files too. These are a list of comparisons that each must evaluate to true for the actions to be run. For example, if a given rule should only run when no one is home, a condition can check the Item that represents the home/away state so it only runs when everyone is away. There are four categories of conditions.

Condition Type Purpose
Item Condition Item states tests to see if an Item’s state meets a comparison (e.g. == ON, <= 65 °F, etc.)
Time Condition Time a selection of the days of the week and a time period when the rule can run
Ephemeris Condition Ephemeris openHAB has a subsystem that tracks types of day (e.g. weekends, weekdays) and local holidays; this condition allows one to specify what types of days it’s allowed to run
Script Condition Script code whose last line evaluates to true of false.

When a rule is triggered from another rule, there is an option to allow or skip the called rule’s conditions. When run manually, the conditions are ignored.

Actions

If triggers define when the rule runs and conditions define what must be true for the rule to run, the actions define the rule’s behaviors. There are four categories of Actions.

Action Purpose
Item Action to command or update an Item
Other Rules to cause another rule to run
Audio and Voice to cause TTS or an audiofile to play on an audio sink
Script Action to execute some code written in a supported rule action

A Note on Rule Languages

There is a growing list of options of ways for users to create rules and many of them will have two flavors: UI and file based. This tutorial will not discuss file based rules. See the docs for the chosen language for details on how to write rules in files for that language.

openHAB comes with three languages by default (Rules DSL, ECMAScript 5.1, and Blockly) and has a number of add-ons to add more. For this tutorial we will be using Blockly and the JavaScript Scripting add-on. But most of the concepts presented can be applied to the other languages too.

What’s the Difference Between a Rule, Script, and Schedule?

This is a trick question because there is nothing very significantly different between the three. All are rules.

Type What’s Unique Purpose
Rule This is any unit of automation which can contain zero or more of triggers, actions and, conditions
Script rule consisting of a single Script Action and has the tag “Script”, there are no triggers so they must be run manually or called from another rule A great place to store examples when you figure something out and want to remember how you did it later. Can include reusable code called from other rules (though there are often better choices). Very useful for adhoc and pseudo-unit testing of your rules. Despite being a rule, Scripts do not appear in the Rules page of MainUI.
Schedule any rule with a time based trigger and the tag “Schedule” This page is a good place to see when your rules are scheduled to run. However, note that it only shows statically timed rules.

Important note on the term “Script”. Unfortunately this term is very overloaded in opneHAB. It has the following meanings depending on the context it’s used:

  • a UI rule consisting of a single Script Action with the tag “Script”

  • a special piece of Rules DSL code placed in the $OH_CONF/scripts folder that can be called from other rules using the callScript action (note that callScript cannot call UI Scripts)

  • a file consisting of code that is read and interpreted by a script engine, such as Bash or Python; usually called from a command line in OH using the executeCommandLine action or the Exec binding; these are not related to Rules DSL scripts and should not be placed in the $OH_CONF/scripts folder

  • in text based rules, a script is a file that creates one or more rules; as opposed to a module which is a library that might be used by a script or other modules.

Previous
[Next](Basic UI Rules

9 Likes

Anything from my side necessary to help you prepare things or do you just want to open a PR, when you are ready?

I plan on just opening a PR. This one is going to probably take me some time to complete and I’m really hoping to get some more community contributions, though I should know better by now.

I’m not really happy with the structure and order yet so it will edited pretty heavily as I go. I’m trying to limit it to four pages and have one “tips and tricks” page to conclude the tutorial.

Does it make sense to collapse the sections in the sidebar perhaps? It’s getting long and I worry it’s pushing down important stuff.

1 Like

Maybe we should delete wiki posts/topics here, that have been transferred to the docs in a consequent manner. Maybe this increases the traffic and interest in contributing at the main doc source.

I think we will have the same “problem” for blockly and i wanted to check, if we can bring some more depth in the sidebar for some special areas like rules and blocky (which are also rules in fact).
Especially for the complex topics it would make sense to split up the long articles in a more leightweight structure.

Also i am investigating in updating our website base system in the nearer future, because there are som e nic plugins available on newer versions, which also may help out with this.

1 Like

This is a really nice write-up, Rich. I was going to try and do some direct edits, but it’s really complete and there just wasn’t much that was missing for an intro. I do have a few stylistic comments that you can take or leave as you see fit.

This is actually a very powerful sentence. Instead of burying it towards the end of this subsection, I think it would read really well if it were the conclusion of the intro paragraph (i.e., after “In openHAB behaviors are defined using rules.”). That will hook readers a little more and lead into the Event Driven section even better.

I see where you’re going with this, but I think it’s a fairly confusing addition. You cover later that a rule with 0 triggers is a special case, a rule with 0 triggers is technically feasible, but really fundamentally malformed, and conditions aren’t even available in all rules formats (again, that comes further on). In addition, this idea get repeated in the What’s the Difference section where it makes more sense.
Would it just be sufficient to remove that line and tweak the following line a little?

The flow is first the rule is triggered to run, then the conditions, if any, are evaluated in sequence, and finally the actions are run, in sequence.

I’ve gone back and forth several times just while writing this comment on whether this is appropriate here. I don’t really have a better suggestion for a place for it (other than the glossary thread, perhaps), but it does feel out of place and tacked on. Also, this a page for real beginners and this seems like it might be somewhat intimidating for many of them and possibly likely to muddle valuable info they’ve gleaned from the rest of the page.

I realise this is a thread about documentation, but as we’re talking about beginners: it would make much more sense if this flow was actually reflected in the UI itself. Currently it’s trigger - action - condition instead of trigger - condition - action.

With the screenshots this would hopefully not be too confusing, but in the pursuit of perfection…!

I actually agree with the design choice as is. Presenting the rule builder in lexical order “When X then Y but only if Z” is more beginner friendly then presenting in programming order. Rich does a great job in this write up of starting to show beginners how to translate back and forth from the language they are accustomed to thinking in to the language of programming logic, but for a UI that is designed around the philosophy of welcoming users of every level staying in “thinking language” order is of utmost importance.

Sounds good.

I would argue here. A rule without a trigger is not malformed. It could be intended to only ever be triggered manually or called from another rule. Similarly a rule without conditions is not malformed, and in fact might be pretty common.

A rule without an action though is kind of pointless so that’s probably worth mention.

I actually came back to add the section about Rules, Scripts and Schedule after I wrote this section and moved on to the next page too. But my main takeaways for that particular sections are:

  • they are all rules
  • scripts are just a special case of rules
  • the term “script” is hopelessly overloaded, be careful of context when using it

I’m OK with rewording that section but I don’t want to wait until the end to talk about this topic because I think it’s important. the key takeaways from this section I want to be that:

  • you can have more than one trigger, action, or condition on any given rule
  • it’s OK to even have no triggers or conditions
  • it’s not really wrong to have no actions, but such a rule would be pointless.

Initially I had a fourth point (it’s OK to mix different types of Actions, such as an Item command, say TTS action, a Rules DSL Script and a JS Scripting Script) but decided that needs to wait for later, probably the tips and tricks page.

I’m not at all happy with that whole set of paragraphs though so welcome the feedback and any ideas or edits that might make it better.

The only reason I mention it here is because it causes so so much confusion on the forum. People try to use callScript to execute their shell script and become confused when it doesn’t work. Then others try to use callScript to execute one of the rules under Settings → Scripts in MainUI. So that whole section is an attempt to deal with that confusion.

It definitely feels out of place and perhaps a better place to put it will become apparent as the rest of the writing progresses. The only reason it’s where it is now is because that section says what a UI Script is and this part also says what a UI Script isn’t.

I don’t want to lose the content entirely though because it is a major source for confusion and problems for users. But agree, there might be a better place to put it. I just don’t know where yet.

I agree but it’s been in this order since the PaperUI Experimental Rules Engine days. I don’t know the reasoning. When you look at the YAML and the JSON you’ll see it actually in triggers, conditions, actions order.

I’ve gone back and forth on whether or not to file an issue on that. If you like, please do file one.

Except that the sentence I wrote explaining the order they are evaluated wouldn’t need to be there if the UI were in the order that they are evaluated. That’s why I keep going back and forth. In some ways it becomes more confusing to the users and in other ways it becomes less confusing.

I’m constantly amazed at the great leaps in assumptions people make when trying to use OH. It would not surprise me if many assume that the conditions are run last because they are last on the page, just like many try to use callScript to execute one of their rules in the Scripts section of MainUI. The docs don’t say that. They UI doesn’t imply that. But they both have “script” in the name so they assume that’s how it’s supposed to work.

1 Like

D’oh. I meant to type “a rule without an action is malformed”. We are in complete agreement here, I just didn’t do a very good job of proof reading my own post.

When I’m thinking about getting a beginner in something up to speed it’s not about using entirely natural or entirely logical language; it’s a matter of optimizing the two (alas, they rarely coincide exactly). I feel that “When X then Y but only if Z” still describes the logic of the evaluation order quite clearly, possibly even more clearly that “If X happens and Z then Y.” It also present the UI fields in the order that a beginner is most likely to both think about a new rule and develop a new rule (how many times is the condition on a new rule a secondary idea after the logical pitfalls of the original implementation have been discovered).

Now, I’ll admit that there is a bit of an English bias here (and my German is 25+ years out of date) so I can’t comment on whether this is a more natural order for all international new users. In that regard alone it may be better to default to the strictly procedural order.

I didn’t even complete the Pimsler basic German so I’ve got even less insight into that sort of thing.

I definitely see it from both sides which is why I’ve not file an issue myself.

But where I do see the confusion from a lot of users is trying to use the triggers as conditions, or trying to combine the triggers and the conditions. Part of me thinks maybe, if the user has to pass over the “But only if…” section to get to the actions they will be less likely to have that confusion. Though these docs might do the same so maybe it’s already all good.