Advanced Automations with the Rules API

Advanced Rules API Tutorial

We will use the rules API to create a trigger that will evaluate a condition then schedule to evaluate that condition again after a defined period of time. This rule could replace SmartApps like “Notify Me When” that were previously complex groovy apps.

Requirements:

Postman
PAT Token

Getting Started

Open Postman and add your PAT token to the header

Refresher

If you are new to the Rules API, you will need to supply the locationId you want to work with for most requests

GET https://api.smartthings.com/v1/rules?locationId=yourID

Will return a list of your existing rules

Let’s Go

Use Postman in a new tab to GET some device IDs. You will need to get a contact sensor and a light bulb.

Once you have these, we are going to be sending a POST command with the Rule.

We are going to post the following to the Rules endpoint

POST https://api.smartthings.com/v1/rules?locationId=your-location-id

{
  "name": "Notify Me When Door Left Open 2",
  "actions": [
    {
      "if": {
        "equals": {
          "left": {
            "device": {
              "devices": [
                "your-contact-id"
              ],
              "component": "main",
              "capability": "contactSensor",
              "attribute": "contact"
            }
          },
          "right": {
            "string": "open"
          }
        },
        "then": [
            {
                "sleep": {
                    "duration": {
                        "value": {
                            "integer": 30
                        },
                        "unit": "Second"
                    }
                }
            },
              {
                "if": {
                    "equals": {
                    "left": {
                        "device": {
                        "devices": [
                            "your-contact-id"
                        ],
                        "component": "main",
                        "capability": "contactSensor",
                        "attribute": "contact"
                        }
                    },
                    "right": {
                        "string": "open"
                    }
                },
                "then": [
                            {
                                "command": {
                                    "devices": [
                                        "your-light-id"
                                    ],
                                    "commands": [
                                        {
                                            "component": "main",
                                            "capability": "switch",
                                            "command": "on",
                                            "arguments": []
                                        }
                                    ]
                            }
                        }
                    ]
                }
            }
        ]
      }
    }
  ]
}

Let’s break down what is happening here.

We are first using a door open event as a trigger, that is the first IF block. If the door opens we will schedule to sleep for 30 seconds.

 {
          "if": {
            "equals": {
              "left": {
                "device": {
                  "devices": [
                    "your-contact-id"
                  ],
                  "component": "main",
                  "capability": "contactSensor",
                  "attribute": "contact"
                }
              },
              "right": {
                "string": "open"
              }
            },
            "then": [
                {
                    "sleep": {
                        "duration": {
                            "value": {
                                "integer": 30
                            },
                            "unit": "Second"
                        }
                    }
                },

After 30 Seconds, we will check the door again. If it is open we will turn on a light as a notification that the door has been left open.

  {
                "if": {
                    "equals": {
                    "left": {
                        "device": {
                        "devices": [
                            "your-contact-id"
                        ],
                        "component": "main",
                        "capability": "contactSensor",
                        "attribute": "contact"
                        }
                    },
                    "right": {
                        "string": "open"
                    }
                },
                "then": [
                            {
                                "command": {
                                    "devices": [
                                        "your-light-id"
                                    ],
                                    "commands": [
                                        {
                                            "component": "main",
                                            "capability": "switch",
                                            "command": "on",
                                            "arguments": []
                                        }
                                    ]
                            }
                        }
                    ]
                }
            }
        ]
      }
    }
  ]
}

This simple example shows off the power of the rules engine. Soon you will be able to schedule notifications and trigger scenes just like this.

5 Likes

Jody, just so i’m clear, this is checking again after a simple wait period. It isn’t truly checking a duration over time, right? So the door could have opened and closed X number of times between that 30 seconds and it would still run at 30 seconds if the door was open.

Now i’m confused. Is soon today?
https://mailchi.mp/smartthings/developer-newsletter-august2020?e=a45052f395

That is correct. The trigger is the door opening and then it is waiting for the specified amount of time to check if the condition is still true. If the door closes within the time frame the second check will fail. If you open the close and open the door again during the time frame there will be another check triggered N minutes from that event.

This is basically an example of the popular “Notify me when”, we are still waiting on notifications to be added to the rule API and I don’t have a hard date for those features.

2 Likes

sorry but it’s ugly… the basic

if (contact_id.is_open) {
sleep(30*1000)
if (contact_id.is_open) {
your-light-id.on()
}
}

now takes 50 lines of json =(
Do you believe many developers will use this “language”?
what gonna happen if I do a mistake like “unit”: “Scond” ?

2 Likes

It’s true, your example takes a few lines. The complexity is just hidden.

  • How many lines is the function is_open
  • How many lines is the function .on()
  • Would this accept any conditional function?
  • Units have validation

The rule is just JSON it’s not a new language. The grammar is specific to the usage of running rules on the SmartThings platform.

If you have suggestions on how to improve, happy to hear them. Give it a shot.

@ady624 and @vlad might be able to elaborate on the design choices.

The rule is just JSON it’s not a new language. The grammar is specific to the usage of running rules on the SmartThings platform.

you are promoting “sleep” function like something “Advanced” in 2020, just think about it.
and now sleep takes 250 characters and 13 words.

 "sleep": {
                        "duration": {
                            "value": {
                                "integer": 30
                            },
                            "unit": "Second"
                        }
                    }

I’d rather use something with hidden complexity. So I can build more complex (advanced) apps by myself.

for example

n = 1
on_door_open {
  your-light-id.on()
  n*=2
  sleep (n*1000)
  your-light-id.off()
}
2 Likes

Could there be a way to actually wait for any updates for a period of time, rather than poll twice and miss temporary events? E.g. by adding a "for": {"duration": ...} to the "if" clause?
Example use-case:
I want to get a notification that my dehumidifier’s tank is full. It has an internal humidity sensor, and stops working when either the humidity is low enough, or the tank is full. With the current API, after initially finding that the power usage is low, the automation needs to sleep for long enough that the dehumidifier will kick in again, but not too long that it will may stop working once more.

Also, is there a plan to make automations created using the app available in the API?

Yes. There is an upcoming feature that is “remains”, so if a thing remains in a certain state then do something.

This is just an example of something that you can do today.

You may be looking for something more like our JS SDK. This is not “Advanced for 2020” it’s a more advanced example of how to use our new rules engine.

Excellent, thank you for adding this.

I have to say that trying to build an executable language out of JSON is just about the worst idea I have seen in a very long time.
The programmatic flow gets lost within the required json syntax.

Please please please reconsider this, because I will not write code this way. Consider something cleaner like putting the program text into a single json object.

But this is stupid and breaks all the rules of new computer language definition. It is overly verbose, has multiple syntaxes (json and whatever the other syntax is), and provides little added functionality (the new functionality is added by the platform- not the language or syntax).

Please, i am completely serious here. I will leave the SmartThings platform if you guys continue down this road.

Ray

2 Likes

Maybe programming with jsons is common practice in korea but I’m already sick of this new platform after two days with the CLI.

If it ain’t broke don’t fix it

I think most of the developers will jump ship to that other platform that shall not be named

1 Like

Why not name the other platforms? I think anything we can do to start a full on developer revolt would help to get some attention from Samsung. Without real developers, the platform is doomed to be over taken by many of the other platforms be them open source Raspberry PI based or very large company based with voice control built in.

It doesn’t matter, we can revolt but no one will listen. This forum is only . 1% of the userbase. Samsung doesn’t care.

I have to say I’m with @RayCaruso and @mvevitsis on this. I think I understand from an architecture standpoint that this approach makes rules simpler to interpret on the server side (and therefore faster and cheaper, which is good) but it does so at a significant cost to developer accessibility.

Of course, rules are only a small part of the platform and thankfully actual SmartApps are not this hideous. But getting rules to work still matters, and the poor readability of using JSON for this will result in bugs that would otherwise be easy to avoid. Hell, it looks like it already has - even after preconditions were fixed, for months now the built-in official automation tool in the app still doesn’t work consistently if you use location modes in conjunction with presence conditions in a “when any condition below is met” rule.

If SmartThings own developers can’t implement rules this way without bugs creeping in, what hope do the rest of have?

3 Likes