Rules API

Now that we've created our first rule let's cover the rule grammar and review the types of actions that are available within the API.

Rule Body

A rule is described in JSON. A single rule can be used to represent complex behaviors. A rule has a name and a list of actions, which is a tree that is evaluated when the rule is triggered.

Actions are a core primitive of the Rules API and define what a rule "does". One of the simplest actions is an "if" action. Let's first see an example of an IfAction and then we will break it apart.

{
    "name": "If my door is opened then turn on my lights",
    "actions": [
        {
            "if": {
                "equals": {
                    "left": {
                        "device": {
                            "devices": [
                                "5F869A33-ECBC-43D8-AFAB-B1BA6D96E77E"
                            ],
                            "component": "main",
                            "capability": "contactSensor",
                            "attribute": "contact"
                        }
                    },
                    "right": {
                        "string": "open"
                    }
                },
                "then": [
                    {
                        "command": {
                            "devices": [
                                "420CC6DD-4DC6-497E-855A-48C1FCB70E61", "19306729-8D2F-4A68-820B-3172A43403F6", "995C0DFC-67EC-444C-8CD4-E7B2F3FEB9F4"
                            ],
                            "commands": [
                                {
                                    "component": "main",
                                    "capability": "switch",
                                    "command": "on",
                                    "arguments": []
                                }
                            ]
                        }
                    }
                ],
                "else": [
                ]
            }
        }
    ]
}

In this rule we introduce the idea of a condition. A condition is evaluated by the rule engine during rule execution. An IfAction takes a top level condition, in this case the EqualsCondition. The EqualsCondition requires left and right fields, these are evaluated for equality. In this specific case the left field will resolve to the value of the device's Contact Sensor capability. If it is set to open, then the EqualsCondition will evaluate to true and execute the actions defined in the then block. Otherwise if it is not set to open, then the actions in the else block will execute. (In this case this is a no op)

Current List of Support Actions

  • IfAction
  • SleepAction
  • CommandAction
  • EveryAction

Example Actions:

SleepAction is a type that can be used to introduce a pause between the execution of other actions. One example would be the case where you would like to turn on a light but then have that light turn off automatically after some time has elapsed.

{
    "name": "Turn on a light, after 1 Minute, turn the light off",
    "actions": [
        {
            "if": {
                "equals": {
                    "left": {
                        "device": {
                            "devices": [
                                "61902075-5932-4EF6-8EF7-5A9D8B7D9B28"
                            ],
                            "component": "main",
                            "capability": "motionSensor",
                            "attribute": "motion"
                        }
                    },
                    "right": {
                        "string": "active"
                    }
                },
                "then": [
                    {
                        "command": {
                            "devices": [
                                "945D4539-855B-44EA-9DF4-43407F482691"
                            ],
                            "commands": [{
                                "component": "main",
                                "capability": "switch",
                                "command": "on",
                                "arguments": []
                            }]
                        }
                    },
                    {
                        "sleep": {
                            "duration": {
                                "value": {
                                    "integer": 1
                                },
                                "unit": "Minute"
                            }
                        }
                    },
                    {
                        "command": {
                            "devices": [
                                "945D4539-855B-44EA-9DF4-43407F482691"
                            ],
                            "commands": [{
                                "component": "main",
                                "capability": "switch",
                                "command": "off",
                                "arguments": []
                            }]
                        }
                    }
                ]
            }
        }
    ]
}

In this rule we are chaining together a few different actions to complete our goal of turning a light on, pausing for 1 minute and then turning it off. As you can see we are making use of an IfAction to trigger the rule execution when motion events occur for this device. When motion is active, 3 actions will take place in sequence:

  1. Send the on command to light 1
  2. Sleep for 1 minute
  3. Send the off command to light 1

Rules containing an EveryAction can be used to setup automations that execute at a defined interval.

{
    "name": "Every 10 minutes turn on a light",
    "actions": [
        {
            "every": {
                "interval": {
                    "value": {
                        "integer": 10
                    },
                    "unit": "Minute"
                },
                "actions": [
                    {
                        "command": {
                            "devices": [
                                "FE7AD97B-F45A-4298-BAA0-39A9A2F56A99"
                            ],
                            "commands": [{
                                "component": "main",
                                "capability": "switch",
                                "command": "on",
                                "arguments": []
                            }]
                        }
                    }
                ]
            }
        }
    ]
}

EveryAction also supports a specific option as well. In this case we can create a rule where we turn on a light at a given time each day. The reference field allows for a number of options: (Now, Sunrise, Noon, Sunset, Midnight). You can then use the offset to fine tune the time to execute at an exact time every day.

{
    "name": "Turn on a light at 8:45 am",
    "actions": [
        {
            "every": {
                "specific": {
                    "reference": "Noon",
                    "offset": {
                        "value": {
                            "integer": -195    
                        },
                        "unit": "Minute"
                    }
                },
                "actions": [
                    {
                        "command": {
                            "devices": ["5C362438-E463-4BA9-9A3A-50AFFA597694"],
                            "commands": [ {
                                "component": "main",
                                "capability": "switch",
                                "command": "on"
                            }]
                        }
                    }    
                ]
            }
        }    
    ]
}

Beyond the EqualsCondition used earlier, the Rules API supports a number of different conditions. These include: GreaterThanCondition, LessThanCondition, GreaterThanOrEqualsCondition, LessThanOrEqualsCondition, and BetweenCondition

{
    "name": "If a light's level is greater than 50 set location mode to Home",
    "actions": [
        {
            "if": {
                "greater_than": {
                    "left": {
                        "integer": 50
                    },
                    "right": {
                        "device": {
                            "devices": ["15E8ED60-422A-45D7-91A6-131502BE77ED"],
                            "component": "main",
                            "capability": "switchLevel",
                            "attribute": "level"
                        }
                    }
                },
                "then": [
                    {
                        "location": {
                             "mode": "D6537244-04DA-4B8F-A278-66AE7DB24481"
                        }
                    }
                ]
            }
        }
    ]
}

Rather than check if the level of the light is greater than or less than we can further restrict that condition with the BetweenCondition, checking that the light's level is between two provided values.

{
    "name": "If the light is between 1 and 50 then set location mode to away",
    "actions": [
        {
            "if": {
                "between": {
                    "value": {
                        "device": {
                            "devices": ["0746171B-DF74-4C57-8B1B-6676AB449C71"],
                            "component": "main",
                            "capability": "switchLevel",
                            "attribute": "level"
                        }
                    },
                    "start": {
                        "integer": 1
                    },
                    "end": {
                        "integer": 50
                    }
                },
                "then": [
                    {
                        "location": {
                             "mode": "D6537244-04DA-4B8F-A278-66AE7DB24481"
                        }
                    }
                ]
            }
        }
    ]
}

CommandActions support sending commands to device(s) to control their state. In the Rules API you will provide the devices id's that you want to control as well as a list of commands. In the following example we are using the colorControl capability and the setColor command along with arguments to change the color of a light bulb. To learn more about the types of capabilities available view the Capabilities Reference.

{
    "name": "If switch is turned on then turn light red.",
    "actions": [{
        "if": {

            "equals": {
                "left": {
                    "device": {
                        "devices": ["0184D5F5-FC6B-473A-89A9-12F32747B50D"],
                        "component": "main",
                        "capability": "switch",
                        "attribute": "switch"
                    }
                },
                "right": {
                    "string": "on"
                }
            },
            "then": [{
                "command": {
                    "devices": ["CEE36D71-9375-4D3D-BD0B-F70208933A89"],
                    "commands": [{
                        "component": "main",
                        "capability": "colorControl",
                        "command": "setColor",
                        "arguments": [{
                            "map": {
                                "saturation": {
                                    "integer": 240
                                },
                                "hue": {
                                    "integer": 100
                                }
                            }

                        }]
                    }]
                }
            }]
        }
    }]

}