Edit: OH 4 Updates
Problem Statement
Often in home automation there is a need to track certain states that the system is in. Events occur to transition from one state to another state (e.g. at noon we transition to the AFTERNOON state). The collection of all the possible states and the transitions between events is called a “state machine”.
This design pattern illustrates some ways OH can implement very simple state machines.
One of the most common uses of a state machine like this is to track time periods throughout the day, week, or year (e.g. seasons).
In all of the examples below, there is a String Item that stores the state machine’s state.
Simple: Event Always Transitions to Fixed State
In this example, no matter what state the machine is in, when a given event occurs it always transitions to a fixed state.
This approach can be implemented with the simplest of rules, even UI rules. All it requires is writing a rule that triggers based on the event and an action that commands the State Item to the state associated with that event. For example, a time based simple state machine might have the these three rules:
Event | Command |
---|---|
Astro dawn | DAY |
12:00 pm | AFTERNOON |
Astro dusk | EVENING |
11:00 pm | NIGHT |
Note that OH 4.0 introduced a “Time is Item” trigger that will trigger the rule at the time held in a DateTime Item.
Another simple state machine can be to track presence.
Event | Command |
---|---|
One or more phones respond to an arping | ON |
No phones respond to arping | OFF |
If using a script action you can create just one rule and send the command based on the event that triggered the rule.
Complex: Events and/or Transitions Depend on Conditions
In this case, which events are considered to be transition events differs based on some condition. For example, you might have a different set of time of day states on weekends and holidays as compared to weekdays.
For a time of day example that takes into account ephemeris see Time Based State Machine [4.0.0.0;4.9.9.9]. This implements a time of day state machine using sets of DateTime Items and shows one way to implement something complex using timers for a time based state machine.
When using the UI one can use Conditions to determine whether or not to transition to the new state. For example:
configuration: {}
triggers:
- id: "1"
configuration:
time: 06:00
type: timer.TimeOfDayTrigger
conditions:
- inputs: {}
id: "3"
configuration:
offset: 0
type: ephemeris.WeekdayCondition
actions:
- inputs: {}
id: "2"
configuration:
itemName: TimeOfDay
command: MORNING
type: core.ItemCommandAction
This is the YAML of a simple UI rule that triggers at 6:00 AM and commands TimeOfDay
to “MORNING” but only if it’s a Weekday according to Ephemeris.
Related Design Patterns
Design Pattern | How It’s Used |
---|---|
Design Pattern: Unbound Item (aka Virtual Item) | vTimeOfDay, Irrigation, and other Items are examples of a Virtual Item |
Design Pattern: Separation of Behaviors | This DP is a specific implementation of Separation of Behaviors |
A State Machine Primer with HABlladin, the openHAB Genie - #6 by jswim788 | This DP is a simplified implementation of a state machine |
Design Pattern: Using Item Metadata as an Alternative to Several DPs | The Python versions use metadata to define the times of day. |
Edit: A near complete rewrite to match formatting of other DP postings and reflect changes in OH 2.3. Eliminated examples for prior versions of OH.
Edit: Use toString instead of going through the long set of calls to get a millis to convert DateTimeType to DateTime
Edit. Remove call to millis in the switch statement.
Edit: Resorted the headings and added a reference to the openhab-rules-tools implementation.