Any plans for adding if-then-else statements to routines?
I would think thatâs a longshot. We canât even get âwaitsâ like in amazon routines.
Especially as they are already available in the Rules API and it would involve an overhauling of the app routine UI.
I started using rules for these reasons (including âwaitâ) a while back and have managed to set up nearly all the automations I need.
Not for using every time - the routine interface continues to be easier and quicker to use.
It just needs to happen, or create a rules engineâŚ
Why is it that there seems to be (semi-)active development of the app in general, but seemingly no interest in making routines more powerful by finally implementing the features that are already present in the Rules API? One would think that automations are a pretty important feature of a smart home platform.
The issue I see with if then else is that routines are typically triggered by a condition or are dependent on time constraints.
Putting an else cause in can lead to the trigger looping for ever
Eg
If sensor a (movement detected)
Then turn on light
Else
Turn off light
Either the if clause or the then clause would always be true, execution would repeat ad infinitum without an exit condition. This would waste value processor time for the hub
As a hypothetical Routine, what that would actually do is subscribe to the motion events from the sensor. It would then do nothing until one arrives.
When one is received, which usually means the motion attribute has changed, the Routine will re-evaluate the condition to see if it is true (motion is being detected) or false (motion is not being detected).
The Routine will then be triggered, which means it evaluates all its conditions as a boolean combination (it already knows the boolean values of all its individual preconditions and conditions) to decide whether it needs to run the then
actions or the else
actions.
In this case there is only one condition to consider. If it is true
the light is turned on
. If it is false
the light is turned off
.
It will then do nothing until the next motion event occurs.
The light being turned on
or off
is not going to make the Routine do anything. It is all about handling events.
Ok, but thatâs a little different to else clauses which fire always fire when the if condition is FALSE.
In this case itâs effectively firing only when there is no motion detected.
A better example might be
If (itâs 8pm) then
Flash a light
Else
Play a sound
For most of the day itâs not 8pm so it should be playing sound continuously.
In the event scenario it would have to fire the first time it didnât evaluate to true for the if clause condition and then suppress further executions till the if condition became true again.
It is exactly the same. The prerequisite is that something is evaluating the âif ⌠then ⌠else âŚâ and then taking the required actions.
Thatâs an understandable expectation but it would require that the âif ⌠then ⌠else âŚâ was constantly being evaluated in a loop, or something along similar lines. In the case of Routines that isnât happening.
Yes, thatâs how Routines, and indeed all the broadly similar home automation tools Iâve used work. Something that affects the conditions happens. The automation does something in response. The automation waits for something else that affects the conditions to happen.
Having said all that, this is likely to be one of the reasons that âif ⌠then ⌠elseâ isnât implemented. Users will have different expectations.
I guess it depends on how itâs designed, and if you allow predicates in the else clause then you are stuffed as the else action wonât necessarily fire when the if predicate is false.
But theyâd probably rule that out due to complexity
I think the else condition should also be executed if the âmainâ conditions (i.e., what the Rules API calls the triggers) are met, but not the preconditions.
For example:
If: A button is pressed
And (precondition): The lights are off
Then: Switch on the lights
Else: Switch off the lights
The routine is executed every time the trigger condition is met. If all conditions (including preconditions) are fulfilled, the âthenâ action should be executed, otherwise the âelseâ action.
I think a lot would depend on creating an intuitive UI. The problem is that even with the current UI, it is not always clear what the function of preconditions is. With two conditions, it often makes no difference if one condition is a main condition and the other is a precondition, or if both are main conditions and the routine is set to execute only if both conditions are met. It would be clearer if preconditions would go underneath the main âif conditionsâ as âand conditionsâ. I believe thatâs essentially how they work anyway, isnât it?
In a second step, it should then also be possible to decide if the preconditions (or âand conditionsâ) have to be met cumulatively or alternatively, like it is for the main conditions.
No⌠A precondition needs to be met before the corresponding if condition is evaluated:
so for a routine:
Precondition A
If B (and/or C⌠ect.)
Then D
for D to execute precondition A must first be met and then trigger B must fire.
If trigger B is already met when the precondition is met then action D will not execute until a further trigger B event is received.
For a time based precondition A however there is the option to evaluate the trigger when the time precondition is met:
Which will execute D when the event for trigger B fired before the time was reached (or precondition A was met). This option is only currently available for time preconditions.
It would certainly be the natural way to add else to Routines given they have to map to Rules.
I think a problem with preconditions is that it is a little vague what they actually are, but with an if ⌠then ⌠structure it arguably doesnât really matter that much. Once you introduce an else ⌠it does.
Those who use, or previously used, webCore may be familiar with the âonly whenâ conditions that could be placed at the top of a piston. Those conditions effectively controlled whether the rest of the piston was executed or ignored (leaving out special cases like âeveryâ).
The naming of preconditions and the vague way they are described does hint at an âonly whenâ equivalence. If that were strictly true the logic would be:
IF
ALL the preconditions are true
THEN
IF
ALL/ANY of the conditions are true
THEN
Do stuff
END IF
ENDIF
However if that were the case the UI should present preconditions before the if block. Instead it reflects the actual rules created which have the following basic structure.
IF
ALL the preconditions are true
AND
ALL/ANY of the conditions are true
THEN
Do stuff
END IF
That is logically equivalent to the previous example. The outcome is always either the then actions being performed, or nothing. So it doesnât matter so much how you think about preconditions as long as you understand stuff is only done when the main conditions may have changed.
However stick an else ⌠in and it does matter. In the âonly whenâ example the outcome can then be the then actions running, the else actions running, or nothing happening at all. With the real world example it becomes the then or the else. You have to appreciate what the preconditions are doing.
I understand that that is how itâs worded in the app, but I think this essentially comes down to semantics.
If you look into the Developer Documentation on Rules, on the bottom of the page under âOperandsâ â âtriggerâ there is an example Rule with the name âSample for preconditionâ. This Rule is exactly how I functionally understand preconditions (and else actions) to work:
In the example Rule below:
- The if Action with equals Condition specifies that if button-device-id is pressed (the use of âtriggerâ:âAlwaysâ dictates that this Condition is used as a trigger for this Rule), then the Rule will check whether switch1-device-id is on.
- If switch1 is on, then the Rule will turn switch2-device-id on. The use of âtriggerâ:âNeverâ in this then statement prevents this Condition from triggering the Rule whenever switch1 is on; this Condition is instead used as a check for the remaining Rule logic, determining the next actions of the Rule.
- For all other cases (else), the Rule will turn switch2 off.
I will concede that if we look at how this example Rule is structured, it is actually different than how the JSON of a Routine looks when viewed in the Advanced Web App (my.smartthings.com/advanced
).
The example Rule from the documentation is structured like this:
IF
button is pressed (condition)
THEN
IF
switch1 is on (precondition)
THEN
Turn on switch2
ELSE
Turn off switch2
Whereas a Routine with a precondition would be structured like this (without an else action, as these are not currently possible in Routine):
IF
button is pressed (condition with "trigger":"Always")
AND
switch1 is on (precondition with "trigger":"Never")
THEN
turn on switch2
Functionally, however, both Rules are the same. In both Rules, switch2 will be turned on (action) if switch1 is on (precondition) at the time the button is pressed (trigger).
If you look at such a routine in the Advanced Web App, what it actually does is create a separate every
Action in addition to the if
Action to which the time-based precondition A applies:
IF
time is between X and Y (precondition A)
AND
condition B is fulfilled
THEN
do D
EVERY
time is X
IF
condition B is fulfilled
THEN
do D
Thatâs the perfect summary.
Thatâs why I happen to like the structure of Sharptools Rules. Itâs very straight forward for what is/are the trigger(s) and then what state to evaluate when the trigger(s) occur.