Home automation often follows a set cycle or states. In the morning the house needs to wake up and come alive as the inhabitants get ready for the day. Next the house should go to sleep a bit while everyone begins the work day. Later in the afternoon the house may wake up again to prepare for everyone’s return and so on.
There are a number of ways to define such states but a common approach is to use times of day. This rule template establishes a rule that uses DateTime Items to drive a state machine. A different set of DateTime
Items can be defined for different types of days (e.g. one set for workdays, another for weekends, and a third for holidays) with Ephemeris used to choose between the sets of DateTime
Items for a given day.
This is a complete rewrite of the rule for OH 3.x using JS Scripting and the openhab_rules_tools library. The behavior is slightly different in that only the time portion of the DateTime
Items is used to schedule the timers so there is no longer a need for the To Today rule template to drive static times. Also, there is a ton more validation of the config with meaningful error messages for how to correct it.
How it Works
Initial Setup
-
The user creates a
String
Item to hold the current time of day state. For this documentation we’ll call it “TimeOfDay” but you can choose any name. -
The user creates a
Group
Item to hold all theDateTime
Items that drive the state machine. For this documentation we’ll call it “TimesOfDay” but you can choose any name. -
The user creates one or more sets of
DateTime
Items. Each Item is populated with the start time for the time of day state that Item represents. For example, aDateTime
Item that representsMORNING
might be populated from the Android App’s Alarm Clock feature or Astro’s sunrise time or hard coded to 07:00. -
Each of those Items must have metadata defined. See below for details. This Item metadata is used to identify which type of day the Item belongs to and what time of day state it represents the start of.
-
Each of those Item are also made direct members of the “TimesOfDay”
Group
. -
All the members of “TimesOfDay” need to be configured with Persistence for
restoreOnStartup
.
Metadata
Each DateTime
Item requires Item metadata. The namespace can be defined by you. For this documentation we will use “tsm”.
// Item metadata defined in .items files
tsm="<STATE>"[type="<daytype>", set="<dayset>", file="<uri>"]
// Item metadata defined in the UI
value: <STATE>
config:
type: <daytype>
set: <dayset>
file: <uri>
<STATE>
Replace this with the string you want sent to “TimeOfDay” at the date time held by this Item. The string will be sent as a command but only if it is different from the current state of “TimeOfDay”.
type
The rule supports six types of days as defined by Ephemeris.
Type | Purpose |
---|---|
custom |
When custom holidays are defined in an XML file (see the Ephemeris docs, link above) use custom for the type and the file parameter is required. |
holiday |
When configured with country and region in MainUI (Settings → Ephemeris), Ephemeris will become preconfigured with the national holidays observed by that region. |
dayset |
Ephemeris allows for the definition of a custom dayset, such as defining “trash_day” to occur every Monday. When used as the type, the set parameter is required. |
weekend |
For the days defined as weekend in the Ephemeris configuration. |
weekday |
For the days not defined as weekend in the Ephemeris configuration. |
default |
If Ephemeris doesn’t match any of the above day types or if there is no set of DateTime Items defined for any of the above types this set of DateTime Items is used. |
The day types are processed in the order presented above. For example, if Ephemeris says today is a holiday
, that set of DateTimes
will be used even if today is also a weekend
and there is a set of DateTimes
for that also.
set
Replace <dayset>
with the custom named dayset defined in the Ephemeris config to use. This parameter is required when the type
is dayset
and should be absent in all other cases.
file
Replace <uri>
with the full path to the custom Ephemeris XML file with the custom holidays defined. This parameter is required when the type
is custom
and should be absent in all other cases.
Examples:
The following are for illustrative purposes, they must be customized for your configuration.
// .items files examples
DateTime Default_Bed (TimesOfDay) { tsm="BED"[type="default"] }
DateTime Weekend_Evening (TimesOfDay { channel="astro:sun:local:set#start", tsm="EVENING"[type="weekend"] }
DateTime Trash_Morning (TimesOfDay) { tsm="MORNING"[type="dayset", set="trash"] }
DateTime Birthday_DAY (TimesOfDay) { tsm="DAY"[type="custom", file="/etc/openhab/service/birthdays.xml"] }
// UI Metadata
value: BED
config:
type: default
value: EVENING
config:
type: weekend
value: MORNING
config:
type: dayset
set: trash
value: DAY
config:
type: custom
file: /etc/openhab/service/birthdays.xml
Item Sets
At a minimum there should be a set of DateTime
Items defined for “default” type days. This will be the sets of states and times used when no other sets are found for the current day type. You might stop with just the default
sets of Items. However, if that is your plan, see Creating Capabilities with Rule Templates: Time of Day for a simpler approach. A warning will appear in the logs if there is no “default” set but the rule will still try to run without them.
The states for each day type must be unique. If a state is repeated an error will be generated by the rule.
There must be a completely separate set of start times for each day type for which you want to have a state machine. The rule does not support reusing the same DateTime
Item for more than one day type though.
Populating the DateTime Items
Actually populating and managing the DateTime
states of the Items is outside the scope of this rule. Options include:
- Astro binding based on solar or lunar events.
- iCal and similar bindings that can define start times.
- Android app’s Alarm Clock option that publishes the next scheduled Alarm to an Item.
- Populated by hand via the REST API, the karaf console, or a widget (see DateTime Standalone Widget and DateTime List Item which can be installed from the marketplace)
- A more advanced timeline picker widget such as Timeline which can be installed from the marketplace.
- Populated from a Rule.
What the Rule Does
Whenever one of the members of TimesOfDay
changes its state, openHAB restarts, and a few minutes after midnight, the rule triggers.
First the rule waits for ten seconds before doing anything. The Astro binding calculates the new times for the celestial events a minute after midnight, updating all the linked Items. This can result in the rule triggering a bunch of times. This delay causes the rule to wait for the updates to stop before calculating the new state machine timers.
After the initial delay, the rule first validates the Item configs. After changing the Item configs for this rule, run it manually to validate and apply them immediately.
Next it determines what type of day it is and selects those DateTime
Items that are for that day type (if no Items exists the “default” set is chosen, if no Items are found an error is logged).
Then it sorts the date times based on their time, skips those that have already passed, and creates a timer to command the “TimeOfDay” Item to the state in the metadata at that time.
Language: JS Scripting
Dependencies:
- A “TimeOfDay”
String
Item - A “TimesOfDay”
Group
- Sets of
DateTime
Items who are members of the “TimesOfDay”Group
and have valid Item metadata and states - openhab-js 4.5+
- openhab_rules_tools 2.0.3+
Changelog
Version 1.0
- decided this is stable and used enough to give it a full version number, finally 1.0!
- fixed error caused by breaking change in openhab-js 4.9.0, the fix is backwards compatible so it should work with any version from 4.5 on.
Version 0.5
- improved error checking for cases where one or more member of the DT Group doesn’t have metadata at all.
Version 0.4
- do not pass raw ZonedDateTime Objects to create timers
Version 0.3
- adjustments for changed made to OHRT
Version 0.2
- now throws an exception if the openhab-js or openhab_rules_tools are not new enough
Version 0.1
- initial release
Sponsorship
If you want to send a tip my way or sponsor my work you can through Sponsor @rkoshak on GitHub or PayPal. It won’t change what I contribute to OH but it might keep me in coffee or let me buy hardware to test out new things.