I like to configure my rules in a way that everything that has to do with the device I am controlling happens in the same rule. For a switch this sometimes means multiple triggers which may turn the switch on or off.
I know I can write conditional code to make the decision, but what would really simplify things is to be able to know which trigger triggered the rule. Is there any way to do that ?
Here is one rather simple example, but I have other more complicated ones.
The rule will track the device that triggered it. You just need to put %device% into a local string variable then use that in conditional actions. Unfortunately, a time trigger shows simply as Triggered. You won't be able to tell which time trigger it was but you can tell if it was time or your switch turning on.
LastTrigger - Type String
Actions to Run
Set LastTrigger to %device%
Agree on the need for RM triggers logic to be improved in future updates. I have several time based RM triggers and I have to employ if-then-else conditional logic surrounding 5 mins before and after each time trigger period to decide which time the RM was triggered. I know, I could split up the RM's into only a single time event, but then I have multiple code streams with only a slight change in each to maintain. The RM's work, so "If it isn't broken..."
I also have an RM rule for our his/her towel warmers with separate Z-Wave switches that have a RM trigger using the group virtual switch device and the individual switch devices within that same virtual group, since the towel switches can be turned on/off via a separate switch, button device or the group switch after a designated timeout period in an other RM rule. It is maddening when the RM rule executes twice even with debouncing logic which triggers Alexa to say, "Nancy's towel warmer is off" and then after a few seconds, say "All your towel warmers are off". It depends which event hits the RM first, the group device or the switch within the group.
I will try the "Local Variables" method outlined above by @pseudonym which might solve this issue.
Can you not include logic to look for this? Or are you meaning it would be nice to have some indication of what triggered via the endpoint? That may be hard to do without introducing an optional (internal) parameter, given the endpoint can be triggered from outside HE (I believe).
Without %device% reporting how the rule got triggered, the user has no way of knowing. As @pseudonym points out, certain Triggers and trigger types simply don't populate the metavariable as one would expect. Specific Time just shows 'Triggered' which seems generic, and Local Endpoint shows nothing at all.
I was asking whether you can check for a null value, but I'm likely missing the bigger picture of what you are trying to to do and what is needed.... Plus endpoints weren't mentioned specifically in the OP, so probably best to cover them elsewhere if you are interested, though not sure I can help.
While it's hard to say more without knowing exactly what to want to do, in general, if you want a rule to do different things in response to different triggers, what you really want to do is make different rules. You're doing different things anyway, and it eliminates the need for awkward conditional actions like "fragile" ones that depend on a device name (which you can change independently of the rule). The "simple" example in the OP actually demonstrates this point quite well, though again, a practical example may have other ways to achieve the goal. For example, a trigger-less rule could be written to "share" identical actions among multiple rules, among other options.
This is entirely dependent on the driver. Rule Machine plays no role except reading the value.
If only users could fork and edit/adapt the built-in drivers that underlie "Specific Time" or "Endpoint".... Your suggestion of splitting a multi-Trigger rule into multiple rules makes the most sense, especially if they want to use %device% and/or %text% for the purpose of formatting notifications (not just Logging).
These are not devices; they do not have drivers (only devices do); they are not events (in the platform sense); and, as documented, the "built-in variables" for trigger events are only guaranteed to have meaningful values when the trigger was an event.
All the "make Multiple Rules" suggestions aside....
I think I like your concept of "one place" to look at all the control logic affecting a particular actionable device. There's something here that may be/could be...potentially...possibly...(with expanded RM capability along the lines you suggest and more) ....a Best Practice.
While this could get complicated, so is managing multiple rules and wondering which is in effect, which is overriding another, and maintaining multiple rules relative to the use/activity of said device. As things expand in one's environment the cross collaboration, and consideration/avoidance of stepping on another rule, becomes more pertinent. It's something you often discover is a problem when you least expect it and go "oh, of course that's why it's on/off and back on etc...".
Preparing for the barrage of counter opinions, and that's fine cause I'm still pondering the implications of what you're doing.
I respectfully disagree. Once you start having multiple rules acting on a given device, it becomes hell to debug and hard to have a full picture of what can act on the device.
The ideal scenario to make sense of what happens to a device is to have a single rule that acts on it and nothing else so that all of the logic is in a single place.
And that’s why I asked if it was possible to know which trigger fired off, not which device.
Regardless of the « time » issue not being a device, I may very well want to do something if a contact sensor is open, and something else if it is closed. Same device, different triggers. Contact sensor is an easy workaround, just check its binary state, but not all sensors are binary… I may want to control the state of a fan based on a temperature sensor: if it is lower than X, stop the fan, higher than Y, start on low, higher than Z, start on medium, increased more than A, start on high
I understand this concern, but there are two things that can help:
the "in use by" section on the device detail page shows you what apps are using device, so you do not have to guess (or remember); and
the "Events" page for the device, accessible from the device detail page, shows you what commands were sent to a device and by what app (not just actual events generated by the driver, contrary to its name -- this is a fairly new feature I think many people missed)
This is in addition to other tools you may have, like Logs or careful app naming, which may also help.
It should also be noted that common advice in the community is that multiple, smaller rules are easier to troubleshoot than one large rule.
Thanks, I’m already aware of these. They help, that’s true, but not nearly as much as having all of the logic in a single rule.
Another example, I installed a vibration sensor on the dryer, to know when it’s on, but it’s reset time is short and it is very sensitive, so it turns on and off frequently while the dryer is running, and it also turns on sometimes when the washer is spinning. So what I want is:
If the motion is on for more than 1 minute: turn the virtual switch « dryer » on
If the motion is off for more than 1 minute: turn the virtual switch « dryer » off
Trivial to do in one rule if I can know which one triggered, but impossible two do without. It requires 2 rules when both are dead simple.
In this case, it is not about making the logic simpler to see, it is about removing redundant rules that have no reason to exist other that they can’t not exist, and pollute the logs and list of rules. It’s really the same automation
In that case can't you just trigger the rule on a change and say if the motion is active wait for a minute before turning switch on else wait for a minute to turn it off, making sure the wait action will be cancelled by any subsequent triggers of the rule?