re-trigger time?

Hi Patrick,
Thinking about Reactor as kind of a motion sensor, i saw the re-trigger Variable, but no re-trigger time so that we can set a delay for the time it takes it to re-set. maybe i am over thinking this, I was trying to create a reactor that turns off several outdoor lights during daytime hours. i created a reactor and it does it’s job as soon as daytime hours start which is expected. the outlier case is when those lights are switched on by mistake during daytime hours, Reactor doesn’t re-trigger a call to shut them off by default. I was worried than enabling re-trigger would just constantly fire the Reactor sensor all the time. in the mean time, i added an activity that waits 30 minutes and resets the reactor, but thought i would check with you if there was a better way.

[quote=“sebby, post:1, topic:200461”]Hi Patrick,
Thinking about Reactor as kind of a motion sensor, i saw the re-trigger Variable, but no re-trigger time so that we can set a delay for the time it takes it to re-set. maybe i am over thinking this, I was trying to create a reactor that turns off several outdoor lights during daytime hours. i created a reactor and it does it’s job as soon as daytime hours start which is expected. the outlier case is when those lights are switched on by mistake during daytime hours, Reactor doesn’t re-trigger a call to shut them off by default. I was worried than enabling re-trigger would just constantly fire the Reactor sensor all the time. in the mean time, i added an activity that waits 30 minutes and resets the reactor, but thought i would check with you if there was a better way.[/quote]

Retrigger=1 will cause the ReactorSensor to re-trip (or re-untrip) and re-run its respective activities any time it is restarted or Luup reloads. This could be an answer for your problem, if you system experiences several Luup reloads throughout the normal course of the day (but that doesn’t really happen to anybody, does it? :wink: )

Version 2.0 (previous release to current) introduced a new “Interval” condition type that is more likely to do what you want. The Interval condition will be true for a brief period on the specified interval. So if you set the interval period to two hours, then every two hours the condition will pulse true for (nominally) 15 seconds–plenty of time to kick off the actions. The most efficient, but a bit more complicated when you first look at, is to use the device counting expression documented in this post in combination with an interval condition. That would look something like this:

On the “Expressions” tab, create a variable called “NumLightsOn” and use this expression:

[tt]len( iterate( list( 11,12,13 ), if( getstate( dev, “urn:upnp-org:serviceId:VSwitch1”, “Status” )==“1”, 1, null ), “dev” ) )[/tt]

Where I’ve provided “11,12,13”, replace with your comma-separated list of device numbers or names (names in quotes, numbers bare); you can mix and match (e.g. 13,“Porch Light”,3). Then go back to the Status tab and hit the restart button. The result should be a number which is equal to the number of lights on the list you provided that are “on” at that moment. The ReactorSensor will be watching each of those devices, so any change triggers an immediate re-evaluation of the expression. Onward…

In the “Conditions” tab:

Group 1

  • Service condition, choose the ReactorSensor you are working on, and you’ll now see [tt]NumLightsOn[/tt] listed as a variable available in that sensor (choose it). Select the “>” operator and use value 0.
  • Date/time: between start-time and finish-time
  • Interval: every 2 hours (for example)

This condition group will be pulsed true every two hours during the specified period of time from start-time to finish-time (when lights should not be left on) and [tt]NumLightsOn[/tt] is greater than 0 (i.e. any of the listed lights is on). Your activities for this ReactorSensor, then, would be to simply turn off those lights.

By the way, you can also accomplish this, perhaps in a more (house) user-friendly way, without the interval condition: remove the interval condition, and use the “sustained for” option on the [tt]NumLightsOn[/tt] service condition. If you set the sustain period to 1800 seconds (30 minutes), for example, then when she-who-must-be-obeyed turns on a light during the day, it will be allowed to stay on for 30 minutes and then turn off, rather than turning off randomly (from her perspective) at some point–she can’t know when the interval is going to trigger, and it could trigger 3 seconds after she turns the lights on. Murphy says exactly this will happen most often, or when it’s most bothersome to her. :slight_smile: Using “sustained for” instead of the interval will make the triggering more deterministic.

About that expression…

The [tt]list()[/tt] function produces an array of the listed devices. The [tt]iterate( array, expr, varname )[/tt] function iterates over the array passed to it (the array of devices made by [tt]list()[/tt] in this case) and performs the expr expression on each one. The current array value is assigned to the name in varname. When done, [tt]iterate()[/tt] returns a new array containing the results of each expression. So, for example, if we did [tt]iterate( list( 1,3,5 ), num*3, “num” )[/tt] the result would be an array containing 3, 9, 15, because the expression multiplies each value by 3. One special case: if the result of an expression is the special value null, that is not put on the return list.

The expression we’re using in [tt]iterate()[/tt] is an [tt]if( test-expr, true-expr, false-expr )[/tt] function (modeled after the function of the same name in most spreadsheet applications, and works the same way). The test-expr is evaluated, and if the result is true, the true-expr expression is evaluated; otherwise, the false-expr is evaluated. Our test expression uses the [tt]getstate( dev, service, variable )[/tt] function to get the [tt]Status[/tt] variable in the current device’s SwitchPower1 service that tells if it’s on or off (as a switch). If it’s on (Status==“1”), the true-expr is simply the number 1, so that’s the expression result if the light is on: 1. The false-expr is null, which causes [tt]iterate()[/tt] to not put the value on the return value list.

So what all of this is doing is building an array of 1s, in which there is one 1 for each light that is currently on (it doesn’t matter which lights it is). Then [tt]len()[/tt] function wraps the entire expression, and all it does is tell us how many elements that final array contains, that is, how many lights are on.

Brilliant! implemented it with the “sustained for” condition and so far have not been yelled at. Thanks!

Excellent! Can you tell I’ve been well-trained? :slight_smile:

OK this is a really cool idea, love this. I have 3 lights that get left on constantly (all smart controlled). And while I have a schedule for them to be shut off at a predetermined time, I’d like to be able to implement this 30 minute to auto-shut down rule. So I thought I’d try building a sensor that would at least trip when any of these lights were turned on (I haven’t got to the ‘sustained for’ piece yet but I think that makes sense)

I can’t seem to make it work, but this admittedly a bit deep for me so I hope you can help me navigate where I’ve gone wrong, and it’s something simple… lol

So my 3 devices…, I looked up their device ID’s, (21, 38, 39), and I created a new Reactor Sensor called “selected lights on”. I created the “NumLightsOn” variable in the expressions tab like this:

len(iterate( list(21,38,39), if(getstate( dev, “urn:upnp-org:serviceId:VSwitch1”, “Status” )==“1”, 1, null ), “dev” ))

Then under the conditions for this SAMEsensor, I created “service variable”; “Selected lights on” ; and set “NumLightsOn > 0”

I’ve tested the expression by running it (hit the little button under the defined variables in the expressions tab), and I’ve tried it with any of my 3 devices (21, 38, 39) being turned on and off. No matter what, it always says: “The expression result is: 0 (number)”.

Running: Reactor ver 2.2stable-19015 (perhaps I just need the latest?)

Can anybody spot where I’ve gone wrong, and why this might not be tripping when one of the selected 3 devices is on?

appreciate the help! :slight_smile:

if they are actual physical switches, try “urn:upnp-org:serviceId:SwitchPower1” instead of “urn:upnp-org:serviceId:VSwitch1” that should solve it

Thanks sebby, I can’t believe I overlooked that. ::slight_smile: That mod worked perfectly. 8)

So just for clarity, I’d use the “urn:upnp-org:serviceId:VSwitch1” only if the condition was evaluating another reactor sensor, is that right?

not really, the “urn:upnp-org:serviceId:VSwitch1” is the URN for a device that emulates a switch, so a virtual switch (hence the VSwitch). some people used them to perform actions on things that don’t have an easy trigger like a physical switches do. I used them extensively as overrides for some of the automation i created so that the wife can turn things off if they are bugging her. for example, i have an automation that uses our phone locations to set the house mode, but if we are out of town and someone is staying there, or (a more likely scenario), i am out of town and the wife left her phone at work, then we can toggle that virtual switch and my automation script thinks we are home. Many uses for the virtual switches, you should definitely look into them.

Nice!! LOL, omg I can see that exact scenario happening in my house! OK, I haven’t branched into virtual switches yet, but an over-ride on some of the automation sequences could come in handy in situations just as you describe. I’ll have to d/l that plug in and play around with it. Thanks for the clarification regarding the VSwitch serviceID