ANY or ALL

in the APP routines, one or more devices can be selected and you can choose ANY or ALL option, is this possible (i assume yes) to do in a Rule? i tried the keyword ANY, but it failed…

{
	"name": "testing (any)",
	"actions": [
		{
			"if": {
				"any": {
					"changes": {
						"equals": {
							"left": {
								"device": {
									"devices": [
										"6e2f6f3f-cbf1-44b6-88a0-bc2c387b7aab",
										"310ea468-554c-4f85-bf8a-a444d4447dc1",
										"f2c2a3d0-c1b6-4ff6-a27a-c9c634453fea"
									],
									"component": "main",
									"capability": "switch",
									"attribute": "switch"
								}
							},
							"right": {
								"string": "on"
							}
						}
					}
				},
				"then": [
					{
						"command": {
							"devices": [
								"49d12d5c-3a48-4b3e-8bba-4411d61b79e5"
							],
							"commands": [
								{
									"component": "main",
									"capability": "switch",
									"command": "switch",
									"arguments": [
										{
											"string": "on"
										}
									]
								}
							]
						}
					}
				]
			}
		}
	]
}
? Select a location. 1
    Error: Request failed with status code 422: {"requestId":"673CAA34-DC18-49DB-8F60-DAFC1869552B","error":{"code":"ConstraintViolationError","message":"The request is
    malformed.","details":[{"code":"BodyMalformedError","target":"any","message":"Unrecognized field \"any\" (class v20190122.internal.st.behaviors.IfAction), not marked as ignorable","details":[]}]}}

Use and or or and use an array of conditions below them.

1 Like

My proposal:

Delete this

and add after this

      "aggregation": "Any",

Just to clarify my answer was for combining conditions. It is the equivalent of the ALL and ANY in Routines. There is also a not for negating single conditions and they can all be nested.

@TapioX gave an answer for changing how devices are handled within a condition. So in your example adding an aggregation property at the same level as left and right would give a choice of All of the devices being on or Any of them being on. Any is the default. It is likely to be used in Member Location in Routines for combining presenceSensor devices.

1 Like

i tried the aggregation approach and found that, if i turned on switch 1, then the condition was met and light turn on.
if i left that switch on, but turned off the target light, then turned on switch 2, the target light would not turn on

{
	"name": "testing (any)",
	"actions": [
		{
			"if": {
				"changes": {
					"equals": {
						"left": {
							"device": {
								"devices": [
									"6e2f6f3f-cbf1-44b6-88a0-bc2c387b7aab",
									"310ea468-554c-4f85-bf8a-a444d4447dc1",
									"f2c2a3d0-c1b6-4ff6-a27a-c9c634453fea"
								],
								"component": "main",
								"capability": "switch",
								"attribute": "switch",
                                 "trigger":"Always"
							}
						},
						"right": {
							"string": "on"
						},
						"aggregation": "Any"
					}
				},
				"then": [
					{
						"command": {
							"devices": [
								"49d12d5c-3a48-4b3e-8bba-4411d61b79e5"
							],
							"commands": [
								{
									"component": "main",
									"capability": "switch",
									"command": "on",
									"arguments": []
								}
							]
						}
					}
				]
			}
		}
	]
}

(i removed the 1st rule before continuing) i changed to the OR pattern and found that this is working more completely

{
	"name": "testing (any2)",
	"actions": [
		{
			"if": {
				"or": [
					{
						"changes": {
							"equals": {
								"left": {
									"device": {
										"devices": [
											"6e2f6f3f-cbf1-44b6-88a0-bc2c387b7aab"
										],
										"component": "main",
										"capability": "switch",
										"attribute": "switch",
										"trigger": "Always"
									}
								},
								"right": {
									"string": "on"
								}
							}
						}
					},
					{
						"changes": {
							"equals": {
								"left": {
									"device": {
										"devices": [
											"310ea468-554c-4f85-bf8a-a444d4447dc1"
										],
										"component": "main",
										"capability": "switch",
										"attribute": "switch",
										"trigger": "Always"
									}
								},
								"right": {
									"string": "on"
								}
							}
						}
					},
					{
						"changes": {
							"equals": {
								"left": {
									"device": {
										"devices": [
											"f2c2a3d0-c1b6-4ff6-a27a-c9c634453fea"
										],
										"component": "main",
										"capability": "switch",
										"attribute": "switch",
										"trigger": "Always"
									}
								},
								"right": {
									"string": "on"
								}
							}
						}
					}
				],
				"then": [
					{
						"command": {
							"devices": [
								"49d12d5c-3a48-4b3e-8bba-4411d61b79e5"
							],
							"commands": [
								{
									"component": "main",
									"capability": "switch",
									"command": "on",
									"arguments": []
								}
							]
						}
					}
				]
			}
		}
	]
}

if switch 1 turns on, then light comes on
turn off light, leaving switch 1 on/
turn on switch 2, light comes back on
etc

1 Like

the aggregation pattern would certainly be much simplier to read and maintain, but it doesn’t appear to work as i would hope (perhaps my rule structure is not correct?)

I haven’t looked closely but you should be aware that changes is documented as only being true when the underlying condition transitions from false to true. I don’t think I even use it anywhere.

I shall qualify that as I have seen an example where changes acted on an operand that wasn’t even boolean. That has never been explained.

3 Likes

@orangebucket, i read your response closer Graham, and i think i understand it now… using the aggregation of “Any” the condition is satisfied as soon as one of the devices meets the condition. as long as one of them is on, then it will never trigger again when one of the other devices in that list comes on. as you mentioned, this is great for check if at least one user is home (using a presence sensor).

thank you to both @orangebucket and @TapioX for your help. !

I think that it is the changes making you see that behaviour.

1 Like

interesting… the use of ‘changes’ was mentioned by @nayelyz in a different post i made where i had added multiple ‘IF’ in the same file and saw that the light in another room, not specified within the If\Then block was was turning on… in that case it was mentioned that down_2x would remain true for a switch until some other event happened

acting on that, i went back to the aggregation pattern but removed the ‘changes’ tag (which is what @TapioX said to do, but i only removed the ‘any’ tag,and not both that was highlighted :face_with_open_eyes_and_hand_over_mouth:) and now i get identical results to the OR case…

{
	"name": "testing (any)",
	"actions": [
		{
			"if": {
				"equals": {
					"left": {
						"device": {
							"devices": [
								"6e2f6f3f-cbf1-44b6-88a0-bc2c387b7aab",
								"310ea468-554c-4f85-bf8a-a444d4447dc1",
								"f2c2a3d0-c1b6-4ff6-a27a-c9c634453fea"
							],
							"component": "main",
							"capability": "switch",
							"attribute": "switch",
							"trigger": "Always"
						}
					},
					"right": {
						"string": "on"
					},
					"aggregation": "Any"
				},
				"then": [
					{
						"command": {
							"devices": [
								"49d12d5c-3a48-4b3e-8bba-4411d61b79e5"
							],
							"commands": [
								{
									"component": "main",
									"capability": "switch",
									"command": "on",
									"arguments": []
								}
							]
						}
					}
				]
			}
		}
	]
}

@TapioX and @orangebucket, I wrote a rules API to refresh my TV plug when the status of TV switch is on but I get this error ‘Error adding rule “Refresh TV Plug”. 422 The request is malformed. actions: Unrecognized field “actions” (class v20190122.internal.st.behaviors.Action), not marked as ignorable’. Can you please let me know what I am doing wrong?

[
{
“actions”: [
{
“if”: {
“equals”: {
“left”: {
“string”: “on”
},
“right”: {
“device”: {
“devices”: [
“c045d3f5-8a09-4b5f-9849-77d433e01b40”
],
“component”: “main”,
“capability”: “switch”,
“attribute”: “switch”
}
}
},
“then”: [
{
“command”: {
“devices”: [
“26a34eeb-aa03-4cc1-a5d0-ce7ee24fd842”
],
“commands”: [
{
“component”: “main”,
“capability”: “refresh”,
“command”: “refresh”
}
]
}
}
]
}
}
]
}
]

I believe that if you are using the ‘Advanced Web App’ to paste a Rule you are pasting content into the "actions": [] array so you don’t need to include it in your content.

1 Like

I removed actions and it worked. Many thanks. If I want to add a delay and check for another IF condition, how do I do that?

Delay:

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

Then you can add again if action

You can have multiples actions (comma separated)

1 Like

If you want a delay you use the sleep action.

If you want the sleep and the extra if to be conditional you add them to the then or else arrays.

You do have to bear in mind that actions can be carried out in serial or parallel. The if action has a sequence property where you select which you want for the then and the else. I can’t remember what the default is but clearly you want serial.

If you don’t want the sleep and delay to be conditional on the first if, you can add them as extra actions after the first one (your first if is actually the one and only entry in an array, so you can add extra ones). The problem there might be that the sequence command for the actions array is written at the same level as name and actions so if the Advanced Web App doesn’t allow for that they’ve boobed.

2 Likes

Thanks, I actually want an AND condition in the IF so I need to check ‘if TV switch is on and Wake up switch is on, then refresh the tv plug’. Do you have a sample code for this which I can use?

IF AND

            "if": {
                "and": [
                    {
                        "equals": {
                            "right": {
                                "device": {
                                    "devices": [
                                        "virtual_switch-ID_1"
                                    ],
                                    "component": "main",
                                    "capability": "switch",
                                    "attribute": "switch"
                                }
                            },
                            "left": {
                                "string": "on"
                            }
                        }
                    },
                    {
                        "equals": {
                            "right": {
                                "device": {
                                    "devices": [
                                        "virtual_switch-ID_2"
                                    ],
                                    "component": "main",
                                    "capability": "switch",
                                    "attribute": "switch"
                                }
                            },
                            "left": {
                                "string": "off"
                            }
                        }
                    }
                ],


THEN…

1 Like

Excellent, it worked in the first go.

1 Like

@TapioX and @orangebucket , just checking if it’s possible to check if the device is offline through Rules API. If yes, how do we do it?

I believe some cloud devices might still use the Health Check capability but that is about it.

There seemed to be a move to take device metadata such as online status, battery level and signal strength out of the mainstream of device status into a separate device health area, but only some of that happened and anything that did move became less accessible to the users. So the connection status is easily accessible in the API and can be subscribed to, but Rules don’t have a way to do so.

3 Likes