Clean code to repeat actions for 2 minutes?

What's the cleanest way to repeat actions for 2 minutes?

I see a related answer here:

There, the solution was to use a simple conditional. I guess I could do the same sort of thing, but it would require capturing the current time, then doing arithmetic to see if more than 2 minutes have passes, etc. Is that the cleanest / best solution though?

My first attempt used a stoppable repeat that repeated actions 1 time every 2 seconds, and then stopped repeating actions when a counter reached 60. But that didn't seem to work (the counter never seemed to update so it repeated indefinitely)

Seems way more complicated than it should be for a simple thing like this, so maybe I'm missing something.

For 2 minutes or every two minutes? Repeat actions for 2 minutes every how many seconds? What exactly are you trying to repeat for/every 2 minutes?

When I put the house to sleep, I am using an LED light strip to show the status of things, like whether all lights are off, whether the security system is armed, whether garage doors are closed, etc. I want to update the colors of the LED light strip to reflect the status of things as they shut off, arm, etc. So, I want the LED light strip to stay on for 2 minutes, and then update the colors of the light strip for those 2 minutes, but after that turn the light strip off. If everything shut down correctly, I want to turn off the light strip earlier than 2 minutes, but if something didn't shut down right then I'll just turn it off after 2 minutes. So, repeat actions for 2 minutes every few seconds, then stop repeating after 2 minutes.
For 2 minutes, I want to update the colors of a Lifx Z LED strip to reflect the status of different things. After 2 minutes, turn the LED strip off.

You're not really repeating actions for 2 minutes thoughl...you want different actions to happen during that 2 minutes. A repeating action is having the same action repeat over a certain interval for a number of reps, for a period of time, or until stopped. I don't really think that what you are trying to do would count as a repeat function. Or maybe I'm not understanding you.

Your requirements are not very clear though. How are you going to tell when the light strip lights up, what it is referring to at the moment? Or do you want it to show the status of everything all in one color? What you are going to end up doing is puling out your phone to see why the color showed up the way it did more often than not.

What are you trying to check the status of?

How are you going to decide what color to set the strip to?

But in a nutshell, you want the strip to set to a particular color for 2 minutes and then go back the way it was?

It sounds like he's trying to repeat some actions every 2 seconds, for 2 minutes total.

Here's a framework for repeating like that, requiring 2 rules. In the first, which I've called "repeat (1)", set up a local Number variable called "count"; then, here are the actions of the rule:

Log: REPEAT (1) count = %count%
Add 1 to count
IF (Variable count(0) >= 60(F) [FALSE]) THEN
    Set count to 0
ELSE
    [put actions you want to repeat here]
    Run Actions: repeat (2)  --> delayed: 0:00:02
END-IF

Add whatever triggers you need to start the sequence, of course. Here's the other rule, "repeat (2)", in its entirety:

Log: REPEAT (2)
Run Actions: repeat (1) 

I've done it with two rules, only because a rule (apparently) can't "Run Actions" on itself.

One caveat: this will actual result in a repeat roughly every two-and-a-half seconds, depending on what else is going on on your hub; you can look at the log entries from the two rules to see exactly what kind of speed you're getting, and adjust the delay and count value accordingly.

It's a LIFX multi-zone LED strip capable of showing different colors. Triggering is not an issue. Here's my attempt at a rule.

zonesLoad(RRRR) on Master Bedroom Lightstrip
On: Master Bedroom Lightstrip
Repeat 1 times every 0:00:02 (stopable)
	IF (Security System closed(F) [FALSE]) THEN
		setZones(0:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500", 1:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	ELSE
		setZones(0:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500", 1:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	END-IF
	IF (Fireplace Switch Sensor open(T) [TRUE]) THEN
		setZones(2:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500", 3:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	ELSE
		setZones(2:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500", 3:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	END-IF
	IF (Garage Door Main Sensor, Garage Side Door Sensor all closed(T) [TRUE]) THEN
		setZones(4:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500", 5:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	ELSE
		setZones(4:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500", 5:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	END-IF
	IF (All Lights(on) is off(F) [FALSE]) THEN
		setZones(6:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500", 7:"hue: 260, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	ELSE
		setZones(6:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500", 7:"hue: 0, brightness: 1, saturation: 100, kelvin: 4500") on Master Bedroom Lightstrip
	END-IF
	IF (Security System closed(F)  AND 
	Fireplace Switch Sensor open(T)  AND 
	Garage Door Main Sensor, Garage Side Door Sensor all closed(T)  AND 
	All Lights(on) is off(F) [FALSE]) THEN
		Delay 0:00:10
		Stop Repeating Actions
	END-IF
	Add 1 to counter
	IF (Variable counter(3) >= 60(F) [FALSE]) THEN
		Stop Repeating Actions
	END-IF
END-REP
Off: Master Bedroom Lightstrip

I still fail to see what you want repeated. I asked a few questions too.....

Will repeat (2)'s call of repeat(1) not instantiate a new instance of repeat(1), where that new instance initializes count = 1?

repeat (2)'s call of repeat(1) will instantiate a new instance of repeat(1), but the value of count will not be reset.

I will have different sections of the strip show the status of different devices. I believe I'll be able to remember what 4 sections mean.

(1) Security system armed/disarmed
(2) gas fireplace on or off
(3) garage doors closed
(4) all lights off

When my goodnight routine is triggered, I turn the LED strip on and set it to all red. As the goodnight routine executes, things will happen. Security system arms, lights turn off, garage doors close, etc. Blue in a section (1-4) means the goodnight routine completed successfully; red means it did not. I know I can go to bed when the whole strip turns blue. If there's a red section, something went wrong.

I want it to turn on for 2 minutes, change the colors of the different sections during that 2 minutes, and turn off after those 2 minutes.

The repeating action is to check the status of things, and update the colors of the light strip.

Glad I asked, because that's counter intuitive from my programming experience. I'll give this a try later tonight.

Oh, actually, I didn't look close enough. I see what you did there now. Was assuming count was a local variable to that rule, but it is a global variable in your code right? That does look like a good solution.

No, "count" is a Local Variable for the rule, but Local Variables are static, even to the point of surviving hub reboots.

I discovered that fact a couple of weeks ago. I have a number of almost-identical rules that handle individual light areas assigning them minimum nighttime values, which I had been holding in RM Global Variables like THESE_LIGHTS_NIGHT_VALUE and THOSE_LIGHTS_NIGHT_VALUE and so on. But, I found I could leave each of those values in a Local Variable called NIGHT_VALUE for each area, thus making the rule just that much more easily clone-able when new areas were added to the system.