This Wiki topic’s goal is to serve as a working document, in order to provide an up-to-date tutorial for OH3 aimed at new users and novices. Everyone is welcome and encouraged to edit it, when we’re satisfied it will make its way to the official docs. You may reply for the specific purpose of improving the article are allowed, but please, this is NOT a support thread: if you’re stuck while reading this and are simply seeking support please open another thread. Thanks!
To this point we have connected Things to devices, modeled our Things, build the start of a UI to control the devices. But how does one cause something to happen in response to events in openHAB? For example, turn on the porch light when I return home or turn on an exhaust fan when the humidity rises above a threshold? This is what rules are for.
Event driven
One important concept about rules is they are event driven. An event occurs and any rule that gets triggered by that will run. A single rule can run based on more than one event but it will only be triggered on the event. You cannot trigger a rule based on two events (e.g. Item Foo changed to OFF and Item Bar > 23) because no two events actually occur at exactly the same time.
Two Approaches
There are two primary approaches for writing rules.
Text based
Text based rules are written with text editors and saved in openHAB’s conf folder. Regardless of the language chosen (more below) the code files must:
- define rules and their triggers
- define the code to run when the triggers happen
Text based rule files are loaded when openHAB starts up and when the files are changed.
Pros:
- more natural approach for developers who already know how to code
- easier to share data between separate rules
Cons:
- slightly slower to be parsed and loaded
- lacks a “but only if” clause so any conditions have to be included as part of the body of the rule
UI Created
UI created rules are created through MainUI. Much of the proforma required for the creation of the rule and it’s triggers are handled for you. UI Created rules also includes an additional “but only if” clause. This is a place where the rule can be prevented from running unless certain state conditions are met (e.g. it’s between 12:00 and 17:00 time).
Pros:
- Simple rules do not even require code at all.
- Blockly is an option for writing the code in a graphical style.
Cons:
- Sharing variables between rules is not as simple.
- Clicking around the browser is not as efficient for some users as writing text, though the Code tab helps to address some of that.
This tutorial will only present UI created rules.
Languages
As of this writing, there are five supported programming languages to choose from for writing rules. the following table presents their pros and cons.
Language | Pros | Cons |
---|---|---|
Blockly | Graphical, renders to JavaScript | Slow to develop, hard to change, large rules become unruly |
Rules DSL | Comes out-of-the-box, has the most examples on the forum | Does not support all features of OH or normal programming languages such as classes, functions, access to Item metadata, etc. |
Jython | Second most number of examples, most mature helper libraries | Stuck on Python 2.7 for now, requires a separate addon |
JavaScript | Comes out-of-box | Stuck on Nashorn which is ECMAScript 5.1, awkward method for importing libraries that make most third party libraries unusable |
Groovy | Has the least number of examples (fewest number of users?), requires a separate addon |
As you can see, there are significant limitations for all of the language choices. If you are totally new to programming, Blockly would be a good choice. This tutorial will present JavaScript as the example, but the concepts presented will work with any of the languages. You can use more than one language at the same time should you choose.
Anatomy of a Rule
Each rule has three main sections:
Section | Also Called | Purpose |
---|---|---|
When | Triggers | Defined the events that will cause the rule to run |
But only if | Conditions | Defined the conditions that must be true for the rule to run, even when the triggering event occur |
Then | Actions | Defines what to do when the rule runs |
When
Rule triggers are always events. When the defined event occurs, the execution is passed off to the But only if to see if the rule is allowed to run. The types of event that can trigger a rule include:
- Item events: received command, changed state, received update
- Thing events: a Thing status changes or updates, events on a special type of Channel called an “event trigger”
- Member of Group events: when a member of a Group receives one of the Item events
- Time events: cron defined times, fixed times of day
- System events: e.g. when openHAB first starts
But only if
The conditions are very similar to the rule triggers except they operate on state. The sorts of states that can be used include:
- Item states including ==, !=, <, >, <=, >= comparisons
- A range of time over the course of the day (e.g. between 12:00 and 17:00)
- A certain type of day as defined by Ephemeris
- A script evaluates to true
The script condition is particularly powerful as you can create quite complicated comparisons and even add error correction to the script if necessary (e.g. if a String Item only has a few valid states set the Item back to it’s previous state if it changes to an invalid state). One particularly useful comparison is to test whether the Item is changed from NULL or UNDEF and not run the rule if it did.
event.oldState.class == UnDefType.class
Then
This is the part of the rule where you define the stuff that should occur when the trigger occurred and the conditions are met. The sorts of things you can do as actions include:
- enable or disable other rules
- run another rule
- send a command to an Item
- execute a given script
NOTE: As of this writing all binding Actions are also listed as options for Actions. These do not work and an issue is already opened to address it.
The first two are interesting options. For example, one might have a bunch of smart plugs that normally run humidifiers but during Christmas time they run the Christmas lights. One can use the enable/disable Action to disable the humidifier rule and enable the Christmas lights rule when a Switch (or cron expression) indicates that it’s Christmas lights time.
The most commonly used action though will be execute a given script.
Your First Rule
Prerequisites:
- A Switch Item to control a Light, in this case we will use an Item named
MasterBedroom_Light_Power
- A light level sensor that the light should be controlled by, in this case we will use an Item named
MasterBedroomSensors_LightLevel
Scenario: When the light level measured by the sensor goes above a threshold value or it’s 08:00 turn on the light, but only on weekdays.
Navigate to Settings -> Rules and click the + icon to create a new Rule.
Create a reasonable Unique ID, Name, and Description.
We have two events where we want to run this rule. First is when the sensor goes above a certain threshold. That’s a state comparison though so we want to trigger the rule when ever the sensor changes to any state. We will check the level in the but only if section.
Click “Add Trigger” and choose “an Item state changes” as the trigger type. Select the MasterBedroomSensors_LightLevel as the Item and return to the Create Rule main page but clicking Done.
Next we need a trigger at 08:00. Again click to add a trigger and this time choose “it’s a fixed time of day.” Select 08:00 for the time.
The rule should look like this.
Now let’s set the conditions. There are two conditions. The first is that the light sensor is below a threshold value. Click to “Add Condition” and choose “an Item has a given state”. Select the light sensor Item, < as the operator, and the threshold value.
The second condition is that it’s a weekday. For this we will use the day of week condition. Create another condition and choose “it is a certain day of the week” and choose the weekdays.
Now we need the action, turning on the light. Click “Add Action” and choose “send a command” and select the light’s Item and set the command to ON.
The rule now looks like this.
There is one more detail to add to the rule. This is a rule that triggers on a schedule. These rules can be added to the schedule view by adding a “Schedule” tag at the bottom of the page.
The rule is now complete, click Save or hit ctrl-s. Click on “Code” and you can see what the rule looks like a YAML.
triggers:
- id: "1"
configuration:
itemName: MasterBedroomSensors_LightLevel
type: core.ItemStateChangeTrigger
- id: "2"
configuration:
time: 08:00
type: timer.TimeOfDayTrigger
conditions:
- inputs: {}
id: "3"
configuration:
itemName: MasterBedroomSensors_LightLevel
state: "50"
operator: <
type: core.ItemStateCondition
- inputs: {}
id: "4"
configuration:
days:
- MON
- TUE
- WED
- THU
- FRI
type: timer.DayOfWeekCondition
actions:
- inputs: {}
id: "5"
configuration:
itemName: MasterBedroomLights_Power
command: ON
type: core.ItemCommandAction
Note that you can edit the rule through the code tab if that works better for you and the yaml is much better for sharing.
Because we’ve tagged this with “Schedule”, it will also appear on Settings -> Schedule.
You can see the new rule will run every weekday at 08:00.
Previous -> Pages
Next -> Putting it all together