How do I create Rules against custom attributes with non-binary states?

So the scenario is that I have a weather station that every couple of weeks likes to lose network connectivity. The solution is to power cycle it and I have the Indoor unit on a Zigbee outlet for this reason.

However, I cant for the life of me figure out how to get a rule to detect that it hasn't updated for say 35mins (it sends data to the cloud every 10 mins) and then power cycle it.

It has this super handy attribute called "lastupdate" which stops updating if the Indoor unit goes offline.

Here's the Logic I want to use:

Trigger:
Indoor unit - "lastupdate" changed (cause I cant find a way to measure duration in a trigger)

Actions:

  • Is the Power On? (checks against a mesh wifi presence sensor that doesn't have battery backup)
    • If no, exit rule
    • If Yes, wait for 35 mins to see if "lastupdate" changes,
      • if yes, exit rule
      • if no, Power Cycle Indoor unit.

But I cant figure out how to do this. :man_facepalming: Initially I thought about using a Trigger based on "lastupdate" not changing within a period of time, but that isnt possible AFAIK.

Your suggested trigger will work. Triggers are events, not conditions, so you can't use duration there. But what you can do is use a "Wait for event: elapsed time" in your actions. This wait will either be cancelled if/when the rule re-triggers (so nothing will happen, except scheduling this wait again) or continue with the next action (if/when the time expires). You might want this as your first action, or perhaps you want it after you check the state of your presence device.

If that doesn't work (maybe I don't understand your goal), what you wrote could pretty much literally be a rule as-is. The tricky part might be knowing that "Wait for event: lastupdate *changes* --> timeout 0:35:00" is a thing you can do, and keep in mind that %device% (the built-in variable) will be either "timeout" after the wait if that action is running because the time expired, or it will be the name of the triggering device (the former is likely the more useful piece of information here). But I wouldn't really do that since the same event is also your trigger, and a re-trigger will cancel any wait, so a simple one for elapsed time should suffice.

If this isn't enough to get you started, maybe try explaining what you want to do in "regular" words, not thinking of things in terms of Rule Machine. Good luck!

I know I can do that, but the issue is the lastupdate attribute is non binary (hence the title), and I can’t find a way to either compare the time stored in it vs actual time or use Boolean logic to check and see if it has changed at the end of the wait period.

You mean like I did in the first 3 paragraphs?

I do appreciate the attempt to help me but unfortunately you’ve missed the crux of the problem.

Unless I’m missing something, if the rule is set up the way @bertabcd1234 describes, I don’t think you ever need to check the actual value of ā€˜lastupdated’. The rule starts a 35-minute countdown to power cycle the weather station every time lastupdated changes. If it changes before the countdown is up, the countdown restarts. If the countdown actually runs out, then by definition the difference between lastupdated time and current time is >35 minutes. Why would you need to verify that?

Yes, sorry, I was scrolled down to look at your other/rule-ish description, didn't see it at that point, and forgot it was there.

But please keep in mind that everyone here is volunteering their time to help you and would appreciate not having to deal with an ... attitude. :slight_smile:

I'm not sure I did, again, unless I missed something in your description. The "Wait" for elapsed time (or whatever you use, but again I think this is sufficient) gets cancelled on a retrigger, and your trigger is lastupdated changing. So, if you make it past the wait, you know this is what happened. Basically what @EdMcW is also saying above.

1 Like

Apologies for the snark, I’m running on fumes ATM due to too many long days / early mornings at work this week. #MIMLife

I guess I don’t understand what is going to prevent this rule from just simply power cycling my weather station when the condition changes?

That's a good question! The answer is that a "Wait" gets cancelled any time a trigger event happens, meaning that both the wait will be unscheduled and nothing after it will run--including your power cycling actions. So, if the lastupdate attribute (your trigger event) changes, the power cycle--your next actions--won't happen because of this cancellation. (If you're familiar with the behavior of delays, this is different; those require explicit cancellation. Waits really make this easier in a lot of cases, I think.)

But along those lines, I'd use a simple Wait for event: elapsed time --> 0:35:00 or similar here. A Wait for conditions: X *changed* doesn't really make sense (that is an event, not a condition), and I suspect the fact that the UI even lets you choose this is a bug. I'll tag @bravenel to see if he agrees. (Bruce: choosing a "Custom Attribute" for a "Wait for conditions" is, it seems, how you get this option, or at least nothing else I tried got it to appear. I could do this in both 4.1 and 5.0; not sure if it was new with this slight change in 4.1.)

In your actions, there's really no reason to care about this attribute or its specific value; your trigger, if written the way you currently have it (which I'd recommend), takes care of everything you should need for this automation. You can also get rid of that entire ELSE section since it doesn't do anything--"Exit Rule" just stops running additional actions (but doesn't un-schedule or un-subscribe to anything that might already be in place), and you have no actions after it in this case. If you want to check that the router is still online before you reboot, maybe you could add a conditional to check again after the wait; otherwise, as-is, it at least won't start that countdown if it's offline at that moment.

1 Like

Oh nice, thank you for the clear explanation, I really appreciate it. :sunglasses:

That’s great, I’ll give that a try. :+1:

I had that there when I was playing with different scenarios trying to get my brain around the problem. But you are right it was quite redundant in the end.

Ok so hopefully this does the trick:

I would use a "Wait for event: elapsed time --> 0:35:00" instead of your "Wait for event: Indoors is lastupdate..." event. The "elapsed time" thing is an option you can choose (instead of a real capability/event, but they're all in the same list) when you create the "Wait for event" action. Otherwise, your trigger and wait are the same event, and it creates the possibility of a race condition with an undefined outcome (does the trigger process fist, cancelling the wait, or does it see the wait event and continue, which you don't want?).

Other than that, looks good to me!

1 Like

Ok done. How does the "Wait for event: elapsed time" know what event it's waiting for?

It's waiting for however long you specify. In this case 35 minutes.

Yep! It's basically like "Delay" (the standalone action--different from a delay on an action, though both have similarities), except it's cancelled on re-trigger. It's easier to write since you don't have to mark the delay as cancelable or use "Cancel Delayed Actions," which could otherwise achieve the same effect. It was made more discoverable in recent versions and has become my preference unless I need control over the cancellation. (FWIW, I like the plain "delay" on your last "on" action--ensures it will turn back on even if an update happens to occur right after it gets turned off, so your power cycle will indeed finish an important part of that process.)

1 Like

Cheers, I really appreciate the help.

1 Like

Yes, this is a bug. Will sort it out for next release.

1 Like

Thanks for your help on this, I added a notification so I’d know when it happened and today I woke up to find this:

:+1:

1 Like