Best way to avoid duplicate runs

I have a rule app that has multiple triggers and may run for over a minute. I'm trying to avoid two copies of the same app running at the same time. At present, I check a global variable at the top of the rule, and exit the rule if marked running. If not running, I set the variable as running. At the very end of the rule, I mark the variable as not running.

This seems to work, but I'm afraid that if something blows up in the middle of my rule and the variable is left as running, the rule will never run again.

Is there a better way to do this?

The approach you’re using is pretty much the standard approach, but most people use the rule’s private Boolean and use it in a required expression.

If you’re really concerned about it getting stuck as you describe, you could always use a switch instead of a boolean that has an auto turn off in “x” minutes.

3 Likes

A couple of other options would be:

  1. Set the global variable to not running with a 5 or 10 minute delay
  2. Have another rule occasionally set the global variable to not running
  1. 5 or 10 minutes later, it may be running again, so saying it is not running, would be wrong.
  2. Again, random setting of not running may be wrong if it is actually running properly at that time.

Possibly, but we have no idea what you actual rule is doing. I would guess that what you are doing could be done easier in Webcore without needing to set Booleans.

I really don't want to learn another computer language. I have a 130 line rule that is working just fine. It controls my water heater through various calculations and conditionals. It runs at least once every 4 minutes, but can run more often based on triggers caused by sudden changes in usage.

Use a global variable as a counter. Each time you exit due to the variable being set, increment the counter. If the counter reaches a set number, believe that the variable is stuck and reset it and clear the counter to zero. Always clear the counter when you go out the bottom successfully.

3 Likes

This seems good to me.

Got it, it would certainly take some time to get up to speed on Webcore, though it is not a language, it is just another app you need to learn how to use, just like RM.

You would be amazed, though, how much simpler this would likely be, and easier to read back, if this was put in Webcore. Complex calculations are easier in Webcore with expressions, and conditionals are very straight forward and clear. Each piston has local variables, which could be used for your counter. If you are ever bored, you might want to look into it.

4 posts were split to a new topic: Discussion on whether Rule Machine and WebCoRE are languages

I would be happy to learn Webcore if someone got me started by volunteering to convert my water heater Rules app.

If want to post your rules, or even better, a description of how the rule needs to work, I would find some time to whip up a piston to demonstrate the differences.

It needs to do different things at different times based on a bunch of different data items. The rules show what needs to be done. It also logs everything to a file, and sends messages to my cell phone. The cell phone and log file are just being used for now so I can fine tune the parameters.

How do I post my rules?

Screenshots are really the only way to post rules, outside of writing up some pseudo-code that just shows the logic that is being done.

Like,

If Time is X and if some value is Y
then do something, and send a notification.
else if time is Z and some value is Y
then do something different

That would be incorrect. Rules can be exported into a JSON-like text format, which can be pasted into a post on this forum.

Rules exported in that format can also be imported into a different instance of Rule Machine. More details are in the Hubitat Documentation page linked below:

https://docs2.hubitat.com/en/apps/rule-machine/rule-5-0

Ok, but I am talking about readability formats, not trying to copy or reuse. I think JSON format would not be clear logic for simply seeing what a rule does over seeing a screenshot, but I've never exported a rule and looked at the JSON.

1 Like

Readable by importing it into RM ….. I’ve done that a few times while rewriting rules for others.

1 Like

Without having the devices used in the rules, I think a screenshot would tell me more.

Ok, you asked for it. Please keep in mind that I never wrote a rule before a few weeks ago, so some things may not have been done as efficient as possible.






OK. There is a lot there, so rewriting all of it is a bit pointless. Here are some examples of how it would be done in Webcore. The real advantage is how you write the the piston, compared to RM rules.

A piston is just a container for some rules. It can have one rule or many, and pistons can call other pistons. A piston is a way to group rules together that make sense, and it is best to not do too much in one piston so it doesn't get cluttered and unmanageable.

First, Webcore is dropdown selections and fields, just like RM. One nice thing is that your if statements are already formatted. You just fill in the sections, and you never have to close an if or else if manually.

image
The basics of Webcore are better looked up on the internet instead of me going into all that here.

Like in your Rule, Webcore cannot combine timers and conditional checks together. So in this case I would make a trigger piston, that calls the calculation piston.

I used a thermostat where needed for demonstration, since I have no Water Heater device.

Here would be the trigger piston:

In this case, you do still need a boolean to check if the calcs are running, since your triggers can overlap. The case in Webcore you don't need that check is with things rising and falling over targets. In RM you want to trigger once when it falls below a target, you have to set a bool that it fell below, and that is where you can save a boolean with Webcore because Webcore accounts for that with the "falls below" or "rises above" conditions and it will only trigger once.

This is a limited version of your calcs in the called piston, just to demo things you are doing in RM.

You have a LOT of variables. Those are declared at the top of a piston. You can declare a type, or just use Dynamic.

Yeah, not sure if this really reads much clearer than RM, but at least it uses indentation.




Not worth your time to rewrite this rule in Webcore for sure, but you could just try it out just to see how it actually works when building rules. You just follow the logic flow, and everything builds as it reads.

1 Like