Turn select devices off based on age and restrictions

#1

1) Give a description of the problem
Yet another ambitious piston that I don’t even know is possible.
Trying to make an energy saving piston. It will save devices that are on to a variable and loop every 10 mins. If the same device is on 6 times, turn off.

2) What is the expected behaviour?
I need some way of comparing the devices listed in the 2 variables.
Method 1: Originally I was going to use an expression, somehow, and if the same device is mentioned in 2 variables, save matching devices to a different variable. But I would need to add a count after each device So Bed Light 2, Hall Light 6, Toilet 4. IF \$Device count <=6, Turn off.
Method 2: Save the devices matched over x amount of 10 min loops to the 1 variable, then count how many times the same device appears. Later, IF \$Device count <=6 (10mins x 6 = 1 hour) turn \$Device off. Although I don’t prefer this method as a device turning on 15 mins in wont count up to 6 occurrences in an hour before being told to switch off.

Ideally I would want it to work down to the 10 mins. So the max time a device would be left on is an hour (ish).
Rather then comparing over 1 hour in method 2.
Even if I have to have 6 variables and save the device list to them on rotation, I just need to know how to compare devices listed in 2 variables and if so, save to another variable.

**4) Post a Green Snapshot of the piston
I don’t have much so far.

Any ideas?

#3

Instead of playing with variables maybe you can just do a 10 minute timer that checks devices you want to monitor if they’ve been on than 60 minutes then turn it off.

``````for each device in deviceVar
if (([device:switch] is on) && age([device:switch]) > 3600000
with device
turn off``````

#4

Hmmm… What a very interesting new approach to my dilemma. Thank you for the suggestion.
I had a quick scroll through the expression list but must have missed the age one. I’ll give it a try

#5

Well thank you sir, your solution was genius. Had to tweak and move some lines around but works perfectly and is a lot easy to edit then what I would have ended up with.
Cheers for the help and for anyone who is interested I’ve attached the piston.

#6

I’m still having some problems actually. I want to be able to set restrictions for the actions so certain lights will only turn off if it’s a certain time or if a system variable is false etc.
I’m having trouble correctly using the \$device variable. I’ve tried a few different ways but can’t get it to work reliably. Could help me with the correct use of this \$Device variable?

Expressions:
Only when;
[\$devices : switch] is equal to Room Light’s switch, gives an error
get Variable null [name:null, index:null] null Invalid empty variable name

[\$device : switch] is Room Light’s switch, was doing weird things like turning off a device that it shouldn’t and sending a push notification that it turned off a different device.

[\$device] is Room Light’s switch, seemed to ignore other restrictions (time between sunrise and sunset) and turn the device off anyway.

Physical Device:
Only when;
\$device switch is Room Light’s switch

If you let me know which way should work I can provide a log. The log provided is for the piston in it’s current state below. In this state the push notifications are doubling or tripling.

``````16/07/2023, 7:56:48 am +817ms
+3ms 	╔Received event [Hubitat Home].time = 1689458208799 with a delay of 18ms, canQueue: true, calledMyself: false
+10ms 	║RunTime initialize > 9 LockT > 1ms > r9T > 1ms > pistonT > 0ms (first state access 4 m:7 4 5)
+15ms 	║Runtime (14113 bytes) initialized in 1ms (v0.3.114.20230222_HE)
+19ms 	║╔Execution stage started
+25ms 	║║scheduleTimer Requesting every schedule wake up at Sun, Jul 16 2023 @ 7:57:48 AM AEST (in 59958ms) for 1 (st:-1)
+28ms 	║║Executed virtual command setVariable (2ms)
+37ms 	║║Comparison (enum) off is (string) on = false (1ms)
+39ms 	║║Comparison (enum) on is (string) on = true (0ms)
+40ms 	║║Comparison (enum) off is (string) on = false (0ms)
+41ms 	║║Comparison (enum) off is (string) on = false (1ms)
+42ms 	║║Comparison (enum) off is (string) on = false (1ms)
+43ms 	║║Comparison (enum) off is (string) on = false (0ms)
+45ms 	║║Comparison (enum) off is (string) on = false (0ms)
+46ms 	║║Comparison (enum) off is (string) on = false (1ms)
+47ms 	║║Comparison (enum) off is (string) on = false (1ms)
+49ms 	║║Comparison (enum) off is (string) on = false (1ms)
+50ms 	║║Comparison (enum) off is (string) on = false (0ms)
+51ms 	║║Comparison (enum) off is (string) on = false (1ms)
+52ms 	║║Comparison (enum) off is (string) on = false (1ms)
+54ms 	║║Comparison (enum) on is (string) on = true (0ms)
+55ms 	║║Comparison (enum) off is (string) on = false (0ms)
+56ms 	║║Comparison (enum) off is (string) on = false (0ms)
+57ms 	║║Comparison (enum) off is (string) on = false (1ms)
+58ms 	║║Comparison (enum) off is (string) on = false (0ms)
+60ms 	║║Comparison (enum) on is (string) on = true (0ms)
+61ms 	║║Comparison (enum) off is (string) on = false (1ms)
+63ms 	║║Comparison (enum) off is (string) on = false (0ms)
+64ms 	║║Comparison (enum) off is (string) on = false (0ms)
+65ms 	║║Comparison (enum) off is (string) on = false (1ms)
+66ms 	║║Comparison (enum) off is (string) on = false (1ms)
+67ms 	║║Comparison (enum) off is (string) on = false (1ms)
+69ms 	║║Condition #5 evaluated true (40ms)
+70ms 	║║Condition group #4 evaluated true (condition did not change) (41ms)
+75ms 	║║Comparison (long) 99767 is_greater_than_or_equal_to (integer) 3600000 = false (1ms)
+76ms 	║║Condition #8 evaluated false (4ms)
+76ms 	║║Condition group #7 evaluated false (condition did not change) (5ms)
+81ms 	║║Comparison (long) 99772 is_greater_than_or_equal_to (integer) 7500000 = false (1ms)
+82ms 	║║Condition #43 evaluated false (4ms)
+82ms 	║║Condition group #42 evaluated false (condition did not change) (5ms)
+88ms 	║║Comparison (long) 2897202 is_greater_than_or_equal_to (integer) 3600000 = false (1ms)
+89ms 	║║Condition #8 evaluated false (4ms)
+89ms 	║║Condition group #7 evaluated false (condition did not change) (5ms)
+94ms 	║║Comparison (long) 2897208 is_greater_than_or_equal_to (integer) 7500000 = false (1ms)
+94ms 	║║Condition #43 evaluated false (4ms)
+95ms 	║║Condition group #42 evaluated false (condition did not change) (5ms)
+100ms 	║║Comparison (long) 6767680 is_greater_than_or_equal_to (integer) 3600000 = true (1ms)
+102ms 	║║Condition #8 evaluated true (4ms)
+103ms 	║║Condition group #7 evaluated true (condition changed) (7ms)
+107ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+109ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (0ms)
``````

In this log it turned off the Gaming light ignoring the restriction only when gaming pc switch is off (Switch 30).

``````16/07/2023, 8:09:29 am +742ms
+3ms 	╔Received event [Hubitat Home].time = 1689458969723 with a delay of 19ms, canQueue: true, calledMyself: false
+12ms 	║RunTime initialize > 11 LockT > 0ms > r9T > 1ms > pistonT > 0ms (first state access 7 m:10 3 8)
+16ms 	║Runtime (14303 bytes) initialized in 1ms (v0.3.114.20230222_HE)
+20ms 	║╔Execution stage started
+29ms 	║║Comparison (long) 3658069 is_greater_than_or_equal_to (integer) 3600000 = true (1ms)
+30ms 	║║Condition #10 evaluated true (5ms)
+32ms 	║║Condition group #9 evaluated true (condition changed) (6ms)
+37ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (0ms)
+38ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (0ms)
+39ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (0ms)
+40ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+41ms 	║║Condition #14 evaluated false (9ms)
+42ms 	║║Condition group #11 evaluated false (condition did not change) (10ms)
+59ms 	║║Comparison (dynamic) on is_equal_to (enum) on = true (0ms)
+60ms 	║║Condition #18 evaluated true (8ms)
+61ms 	║║Condition group #15 evaluated true (condition did not change) (17ms)
+125ms 	║║Executed device command [Gaming Room Light].off() (61ms)
+129ms 	║║Calculating (string)Gaming Room Light + (string) turned off due to being on too long >> (string)Gaming Room Light turned off due to being on too long
+211ms 	║║Executed virtual command [Gaming Room Light].sendPushNotification (77ms)
+223ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+225ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+227ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+228ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+230ms 	║║Condition #22 evaluated false (12ms)
+231ms 	║║Condition group #19 evaluated false (condition did not change) (18ms)
+237ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+239ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+241ms 	║║Comparison (dynamic) on is_equal_to (enum) off = false (1ms)
+242ms 	║║Condition #27 evaluated false (9ms)
+243ms 	║║Condition group #24 evaluated false (condition did not change) (11ms)
+249ms 	║║Comparison (dynamic) on is_equal_to (enum) on = true (1ms)
+250ms 	║║Condition #31 evaluated true (5ms)
+254ms 	║║Comparison (enum) on is (string) off = false (1ms)
+256ms 	║║Condition #32 evaluated false (5ms)
+257ms 	║║Condition group #28 evaluated false (condition did not change) (12ms)``````

#7

The piston you posted is pretty involved, I didn’t look at it in detail but one thing I noticed is the restriction of `[\$device:switch]`. This will give you the value on or off, not the name of the device. I don’t think that’s what you’re intending to get, probably best to use \$device. Also, add some debug entries to check if you’re actually getting the result you’re looking for. Try with a simple piston first then build from that.