Rules API exit from every loop?

In the sample rules repository there is this great example of how to repeat something:

This simple example repeats the light on/off interval forever. Is there a way to put a condition within the actions to stop the loop? Basically, I want something like this:

if (condition) {
  every
     interval
     actions {
          do something
          if (not condition) exit
     }
}

Thanks!

Hi, @guxdude!
I already asked the team about this, so, I’ll get back to you once I get more info.

3 Likes

Following to see what the answer is.

Following up on this question, the team asked me to open a feature request to have a “direct” solution for this use case. However, there’s an option to do this with the feature “limit”. Below, you’ll find a sample Rule where the workflow is:

  1. Every 30 seconds, check if the SwitchLevel value of a device equals 75%
  2. If it is “False”, the execution continues and the command in every.actions is triggered
  3. If it’s “True”, the limit stops the Rule but executes the command inside limit.actions.
    The value of “lifetime” causes the Rule to remove completely.
{
   "name":"Stop loop execution",
   "actions":[
      {
         "every":{
            "interval":{
               "value":{
                  "integer":30
               },
               "unit":"Second"
            },
            "actions":[
               {
                  "if":{
                     "equals":{
                        "right":{
                           "device":{
                              "devices":[
                                 "deviceID"
                              ],
                              "component":"main",
                              "capability":"switchLevel",
                              "attribute":"level"
                           }
                        },
                        "left":{
                           "integer":75
                        }
                     },
                     "then":[
                        {
                           "limit":{
                              "count":1,
                              "period":"Lifetime",
                              "actions":[
                                 {
                                    "command":{
                                       "devices":[
                                          "deviceID"
                                       ],
                                       "commands":[
                                          {
                                             "component":"main",
                                             "capability":"switch",
                                             "command":"off"
                                          }
                                       ]
                                    }
                                 }
                              ],
                              "sequence":{
                                 "actions":"Parallel"
                              }
                           }
                        }
                     ]
                  }
               },
               {
                  "command":{
                     "devices":[
                        "deviceID"
                     ],
                     "commands":[
                        {
                           "component":"main",
                           "capability":"switch",
                           "command":"off"
                        }
                     ]
                  }
               }
            ]
         }
      }
   ]
}

Please, let me know if this helps.

Does this mean to restart the rule it has to be recreated? I really want it to restart again next time the initial condition is true (at a specific time, eg). This does look promising, though. Will have to experiment with it. Thanks.

No problem, I’ll check if there’s another option that doesn’t remove the Rule completely

Well, I tried this and I think I got it formed correctly. I believe the problem I am having is that I basically need two every loops. What I want to set up is every night at midnight, start a loop to run every 5 minutes until a certain condition is met. When I try to submit my rule, the error I get is 'every must be null (see below). I believe there is a limitation that I can’t have two every loops. I can understand that so I will have to think about another way to start the process. Maybe I can start it off with a virtual switch which I can turn on at midnight. Getting late now so will have to try again tomorrow.

{
    "requestId": "550D5BE3-89E0-44BB-A754-9E28A9BDB090",
    "error": {
        "code": "ConstraintViolationError",
        "message": "The request is malformed.",
        "details": [
            {
                "code": "NullError",
                "target": "every",
                "message": "every must be null.",
                "details": []
            }
        ]
    }
}

@nayelyz
I tried again with only one every and using a virtual device to start the rule. Here is my rule body:

{
   "name":"Loop test",
   "actions":[
	{
        "if": {
            "equals": {
                "left": {
                    "device": {
                        "devices": [
                            "850ad9f9-2daf-400a-94d9-5e9ce4f72496"
                        ],
                        "component": "main",
                                    "capability": "switch",
                                    "attribute": "switch"
                    }
                },
                "right": {
                    "string": "on"
                }
        	},
 			"then": [
			    {
				    "if": {
                        "equals": {
                            "left": {
                                "device": {
                                    "devices": [
                                        "c6860ae0-3d96-40bb-a260-9b4f2d770ebe"
                                    ],
                                    "component": "main",
                                    "capability": "switch",
                                    "attribute": "switch"
                                }
                            },
                            "right": {
                                "string": "off"
                            }
        		        },
 				        "then": [
                            {
                                "every":{
                                    "interval":{
                                        "value":{
                                            "integer":5
                                        },
                                        "unit":"Minute"
                                    },
                                    "actions":[
                                        {
                                            "if":{
                                                "equals":{
                                                    "right":{
                                                        "device":{
                                                            "devices":[
                                                                "a69158f0-2e5d-46ca-829b-01ecafc04c55", "a69158f0-2e5d-46ca-829b-01ecafc04c55", "4ffbf90f-8760-4dcc-a471-c5dba2a8d028", "6f81a548-ab24-4c25-9819-df8ba6cfe38e", "e42886db-3662-4d76-a060-6f787253b186", "3460b018-745f-4e02-9506-911b76947a90", "2b9b9281-651d-4cb8-980b-19081c29f0e4", "62127998-5401-445b-b305-e2b9efd4c9e9"
                                                            ],
                                                            "component":"main",
                                                            "capability":"switch",
                                                            "attribute":"switch"
                                                        }
                                                    },
                                                    "left":{
                                                        "string":"off"
                                                    },
			                                        "aggregation":"All"
                                                },
                                                "then":[
                                                    {
                                                        "limit":{
                                                            "count":1,
                                                            "period":"Lifetime",
                                                            "actions":[
                                                                {
                                                                    "command":{
                                                                        "devices":[
                                                                            "c6860ae0-3d96-40bb-a260-9b4f2d770ebe"
                                                                        ],
                                                                        "commands":[
                                                                            {
                                                                                "component":"main",
                                                                                "capability":"switch",
                                                                                "command":"off"
                                                                            }
                                                                        ]
                                                                    }
                                                                }
                                                            ],
                                                            "sequence":{
                                                                "actions":"Parallel"
                                                            }
                                                        }
                                                    }
                                                ]
                                            }
                                        },
                                        {
                                            "command":{
                                                "devices":[
                                                    "1300ba52-1497-48b4-99af-c35e69dab22d"
                                                ],
                                                "commands":[
                                                    {
                                                        "component":"main",
                                                        "capability":"switch",
                                                        "command":"on"
                                                    }
                                                ]
                                            }
                                        }
                                    ]
                                }
                            }
  				        ]
			        }
                }
            ]
	    }
    }]
}

Unfortunately, I still get the same null error:

{
    "requestId": "948DDF0C-BB3D-4B9F-9491-F6E620B5F8AE",
    "error": {
        "code": "ConstraintViolationError",
        "message": "The request is malformed.",
        "details": [
            {
                "code": "NullError",
                "target": "every",
                "message": "every must be null.",
                "details": []
            }
        ]
    }
}

Any idea what this null error is pointing to? Does the every have to be at the top level?
thanks!

Hi, @guxdude

The problem is that an every can’t be nested inside another action

1 Like

Thank you. I had a feeling that was the case. Hopefully, that limitation will be fixed in the future. Very handy to have a temporary loop (like keep dinging a bell until I close the door).