Help understanding how to notify after delay

Hi there, I set up a rule around notifying presence: Here's the rule text:

IF (Scott present(T)  OR Another present(T) [TRUE]) THEN
    Cancel Wait
    Cancel Delayed Actions
    On: Someone Home
    Notify Scott’s iPhone X: 'Someone home!'
ELSE
    Off: Someone Home --> delayed: 0:00:05 (cancelable)
    Wait for events: Someone Home(on) turns off
    Notify Scott’s iPhone X: 'No one home!'
END-IF

I know I could use a Notifications app to separately manage the notifications (and I got this working great), but wondering if reasonable to notify all within this role and if there's a different/better way to do it. And/or any suggestions about the presence notification also welcome! Presence provided by Life360.

I edited it slightly to use a virtual contact sensor rather than a virtual switch so I can trigger Routines in Alexa with this state change. I also added another conditional inside the first if on whether to trigger the notification because if one person is home and the other comes home, I don't want to trigger a notification.

However, I still feel like I'm doing something wrongly/sub-optimally. Any tips?

IF (Scott present(T)   OR Person B present(T) [TRUE]) THEN
	Cancel Wait
	Cancel Delayed Actions
	open() on Someone Home
	IF (Someone Home closed(F) [FALSE]) THEN
		Notify Scott’s iPhone X: 'Someone home!'
	END-IF
ELSE
	close() on Someone Home --> delayed: 0:00:05 (cancelable)
	Wait for events: Someone Home closed
	Notify Scott’s iPhone X: 'No one home!'
END-IF

For one, I see that when the second person leaves, it seems that after the 5 second delay, I'm getting more log messages than I expect. I am playing with a version of the above that uses two virtual switches to test that everything is working, and I'm testing the case where one person is already away and the second person leaves home. I correctly only get one notification, but the log line highlighted in the screenshot below and all the lines following in confuse me -- it seems like everything runs a second time after the 5 second delay?

Can you show the whole rule, including triggers (and actions)?

Sure. I haven't updated the one actually using Presence to be totally inline with what I have on my test rule, so I'll share that. Almost no differences except Presence instead of Switches.

Ah! I think that made me realize it. With "Someone Home closed" as a trigger, when the 5s delay is done and Someone Home is indeed closed, it triggers the entire block again. Suggestions? And general suggestions for what I'm trying to accomplish?

Thanks in advance! Having fun diving in with Hubitat and into RM!

Is there indeed any way to not make "Someone Home closed" as a trigger but still trigger a condition off of it? Would I have to use a local variable?

Okay, I figured out the answer to that question: under "Define condition", you can specify any condition. Doesn't have to be related to any triggers.

Sounds like you got it figured out! If not, I can take a closer look.

There are a couple things that do seem odd as written above, however:

  • You run open() on the device, then immediately check if it's closed with IF (Someone Home closed) THEN.... This seems odd to me, like that IF would never be true because you just opened the device.
  • Similarly, you run close() on the device then have a Wait for events: Someone Home closed. Unless this isn't a virtual device (my assumption is that it is) and actually waits for something to respond that might take a while, then that command would generally be followed by that event, so it's not clear to me why it's waiting until it happens.

I assume you have reasons for choosing these actions over others based on whatever your devices actually do (again I'm just guessing that this is a virtual contact sensor that would respond more or less immediately), but I thought I'd mention these things regardless.

Finally, there's another issue that won't affect the way your rule runs but is just extra clicking:

  • Any time your rule triggers, in-progress "Waits" will be cancelled, so you do not need to do this explicitly in your first IF

Glad you got something figured out, it appears!

1 Like

Hi there, thanks for the thoughts! Glad to dip my toe in this community!

Regarding the three bullets you have, in order, here are my thoughts. Open to feedback!

  1. You're right that the conditional doesn't make sense. What I really mean is for the conditional notification to be just above the open() call. That way if both people are gone, but before the cancelable period (5 seconds in this example) one returns, I don't want a notification. Since the virtual contact sensor will still be closed, I won't get it with that conditional.
  2. I think the Wait here is vital so that I get the notification after the cancelable delay. Right? I assumed that something on a delay is basically an async command, so I'd need a wait to make the rest of the statement synchronous, no?
  3. I think I need to Cancel Delayed Actions at the very least because without that the cancelable close() won't be canceled if, in the scenario in #1 again, I return during the cancelable period. It does seem that I can get rid of Cancel Wait. I thought I'd need that to avoid the notify in the ELSE block, but it seems that I don't need that indeed. If I leave and return, the wait for events will be canceled and the notification that no one is home won't be triggered.

So here's my updated Actions:

IF (Scott present(T)  OR Person B present(T) [TRUE]) THEN
	Cancel Delayed Actions
	IF (Someone Home closed(F) [FALSE]) THEN
		Notify Scott’s iPhone X: 'Someone home! Canceling Roomba'
	END-IF
	open() on Someone Home
ELSE
	close() on Someone Home --> delayed: 0:00:05 (cancelable)
	Wait for events: Someone Home closed
	Notify Scott’s iPhone X: 'No one home! Starting Roomba maybe.'
END-IF

Any further changes you'd suggest?

That looks better! While what you have should work, it seems less awkward to me to do something like this:

ELSE
  Delay 0:00:05 (cancelable)
  close() on Someone Home
  ...

instead of:

ELSE
  close() on Someone Home --> delayed: 0:00:05 (cancelable)
  Wait for events: Someone Home closed
  ...

with the reason being that a "standalone" delay action (first example) effectively pauses execution at that step until the delay is up (in which case it resumes with the next action) or cancelled (in which case everything after it is also not executed). The "delay" option on an action schedules that (delayed) action for the specified time in the future, then immediately continues on with the next action. I assume you may have observed the latter behavior and used a "Wait" to combat this problem. With the delay, the problem disappears, and you don't need the "Wait" at all--when (if) execution resumes, you'll know the state will have been changed (or technically have been commanded to change). But again, what you have should work--thanks for the explanation! (My failure to see this was a result of the fact that the only way I'd think to do this would be the first way, which is what you'll see in most examples.)

You are correct that (with the delay) you do need the "Cancel Delayed Actions" to have the effect you want. I should also note that five seconds seems like a really short time for what I assume is the intended use, but I assume you might just be doing that for testing.

Everything else makes sense to me!

1 Like