Simultaneous, Independent Handling of Multiple Devices


#1

1) Give a description of the problem
I have a fairly simple piston that monitors if a light is set below 20% and if so, waits 1 minute, sets the light’s level to 100, turns it off and sends a notification.

I want to apply this piston to many lights. Yes, I could just duplicate it X times one for each light, but it seems there is a more elegant solution that would handle all the lights in one piston and process each individually, simultaneously, if multiple lights are set under 20% at the same time. I can’t get that to work though.

2) What is the expected behaviour?
See above

3) What is happening/not happening?
I tested with two lights. The lights that triggered the piston first were NOT turned off/notification sent, but the lights that triggered the piston second WERE turned off/notification sent.

**4) Post a Green Snapshot of the piston![image|45x37]
Piston working with one light:

Piston not working with multiple lights:

5) Attach logs after turning logging level to Full

10/22/2020, 4:11:46 PM +596ms
+6ms ╔Received event [187 Montgomery Avenue Hubitat].time = 1603397506993 with a delay of -397ms, canQueue: true, calledMyself: false
+28ms ║RunTime initialize > 27 LockT > 1ms > rtDT > 2ms > pistonT > 1ms (first state access 24 7 20)
+31ms ║Runtime (6960 bytes) successfully initialized in 2ms (v0.3.110.20200916_HE)
+34ms ║Synchronizing scheduled event, waiting for 364ms
+430ms ║╔Execution stage started
+452ms ║║Comparison (enum) off is (string) on = false (3ms)
+454ms ║║Cancelling condition #15's schedules...
+455ms ║║Condition #15 evaluated false (10ms)
+457ms ║║Cancelling condition #14's schedules...
+458ms ║║Condition group #14 evaluated false (state changed) (14ms)
+463ms ║╚Execution stage complete. (33ms)
+466ms ╚Event processed successfully (464ms)

10/22/2020, 4:11:27 PM +403ms
+5ms ╔Received event [187 Montgomery Avenue Hubitat].time = 1603397487265 with a delay of 138ms, canQueue: true, calledMyself: false
+28ms ║RunTime initialize > 27 LockT > 1ms > rtDT > 3ms > pistonT > 2ms (first state access 23 6 21)
+31ms ║Runtime (6952 bytes) successfully initialized in 3ms (v0.3.110.20200916_HE)
+34ms ║╔Execution stage started
+49ms ║║Calculating (string)Webcore: + (string)Master bedroom lights >> (string)Webcore: Master bedroom lights
+51ms ║║Calculating (string)Webcore: Master bedroom lights + (string) >> (string)Webcore: Master bedroom lights
+54ms ║║Calculating (string)Webcore: Master bedroom lights + (string)off >> (string)Webcore: Master bedroom lights off
+128ms ║║Executed virtual command [Master bedroom lights].sendPushNotification (67ms)
+136ms ║╚Execution stage complete. (102ms)
+158ms ║Setting up scheduled job for Thu, Oct 22 2020 @ 4:11:46 PM EDT (in 19s)
+160ms ╚Event processed successfully (159ms)

10/22/2020, 4:11:17 PM +263ms
+5ms ╔Received event [187 Montgomery Avenue Hubitat].time = 1603397477224 with a delay of 39ms, canQueue: true, calledMyself: false
+77ms ╚Event queued (75ms)

10/22/2020, 4:11:16 PM +911ms
+4ms ╔Received event [Master bedroom lights].level = 99 with a delay of 48ms, canQueue: true, calledMyself: false
+52ms ║RunTime initialize > 51 LockT > 1ms > rtDT > 1ms > pistonT > 0ms (first state access 49 5 46)
+56ms ║Runtime (6926 bytes) successfully initialized in 1ms (v0.3.110.20200916_HE)
+57ms ║╔Execution stage started
+70ms ║║Comparison (integer) 10 is_less_than (integer) 20 = true (2ms)
+72ms ║║Condition #2 evaluated true (10ms)
+74ms ║║Condition group #1 evaluated true (state did not change) (12ms)
+75ms ║║Cancelling statement #12's schedules...
+79ms ║║Executed virtual command wait (1ms)
+82ms ║║Requesting a wake up for Thu, Oct 22 2020 @ 4:11:46 PM EDT (in 30s)
+90ms ║║Synchronizing scheduled event, waiting for 224ms
+342ms ║║Executed physical command [Master bedroom lights].off() (14ms)
+344ms ║║Executed [Master bedroom lights].off (17ms)
+351ms ║║Executed virtual command [Master bedroom lights].wait (1ms)
+353ms ║║Requesting a wake up for Thu, Oct 22 2020 @ 4:11:27 PM EDT (in 10s)
+361ms ║╚Execution stage complete. (303ms)
+383ms ║Setting up scheduled job for Thu, Oct 22 2020 @ 4:11:27 PM EDT (in 10s), with 1 more job pending
+386ms ╚Event processed successfully (384ms)

10/22/2020, 4:11:15 PM +133ms
+6ms ╔Received event [187 Montgomery Avenue Hubitat].time = 1603397475060 with a delay of 73ms, canQueue: true, calledMyself: false
+25ms ║RunTime initialize > 24 LockT > 1ms > rtDT > 2ms > pistonT > 1ms (first state access 21 7 17)
+27ms ║Runtime (6785 bytes) successfully initialized in 2ms (v0.3.110.20200916_HE)
+34ms ║╔Execution stage started
+48ms ║║Comparison (enum) on is (string) on = true (2ms)
+50ms ║║Cancelling condition #15's schedules...
+53ms ║║Condition #15 evaluated true (10ms)
+55ms ║║Cancelling condition #14's schedules...
+56ms ║║Condition group #14 evaluated true (state changed) (14ms)
+60ms ║║Cancelling statement #16's schedules...
+81ms ║║Executed physical command [Master bedroom lights].setLevel([100], ) (15ms)
+83ms ║║Executed [Master bedroom lights].setLevel (17ms)
+88ms ║║Executed virtual command [Master bedroom lights].wait (0ms)
+90ms ║║Requesting a wake up for Thu, Oct 22 2020 @ 4:11:17 PM EDT (in 2s)
+98ms ║╚Execution stage complete. (67ms)
+120ms ║Setting up scheduled job for Thu, Oct 22 2020 @ 4:11:17 PM EDT (in 2s)
+123ms ╚Event processed successfully (122ms)

10/22/2020, 4:10:45 PM +8ms
+3ms ╔Received event [Master bedroom lights].level = 10 with a delay of 61ms, canQueue: true, calledMyself: false
+20ms ║RunTime initialize > 19 LockT > 2ms > rtDT > 2ms > pistonT > 1ms (first state access 15 5 14)
+22ms ║Runtime (6763 bytes) successfully initialized in 2ms (v0.3.110.20200916_HE)
+24ms ║╔Execution stage started
+37ms ║║Comparison (integer) 10 is_less_than (integer) 20 = true (2ms)
+39ms ║║Condition #2 evaluated true (12ms)
+41ms ║║Condition group #1 evaluated true (state did not change) (14ms)
+43ms ║║Cancelling statement #12's schedules...
+49ms ║║Executed virtual command wait (0ms)
+52ms ║║Requesting a wake up for Thu, Oct 22 2020 @ 4:11:15 PM EDT (in 30s)
+61ms ║╚Execution stage complete. (37ms)
+89ms ║Setting up scheduled job for Thu, Oct 22 2020 @ 4:11:15 PM EDT (in 30s)
+91ms ╚Event processed successfully (90ms)

10/22/2020, 4:10:32 PM +815ms
+3ms ╔Received event [Layla’s lights].level = 10 with a delay of 59ms, canQueue: true, calledMyself: false
+56ms ║RunTime initialize > 55 LockT > 2ms > rtDT > 41ms > pistonT > 40ms (first state access 12 5 50)
+60ms ║Runtime (6693 bytes) successfully initialized in 41ms (v0.3.110.20200916_HE)
+62ms ║╔Execution stage started
+78ms ║║Comparison (integer) 10 is_less_than (integer) 20 = true (3ms)
+80ms ║║Condition #2 evaluated true (14ms)
+82ms ║║Condition group #1 evaluated true (state did not change) (16ms)
+84ms ║║Cancelling statement #12's schedules...
+93ms ║║Executed virtual command wait (2ms)
+102ms ║║Requesting a wake up for Thu, Oct 22 2020 @ 4:11:02 PM EDT (in 30s)
+115ms ║╚Execution stage complete. (53ms)
+138ms ║Setting up scheduled job for Thu, Oct 22 2020 @ 4:11:02 PM EDT (in 30s)
+140ms ╚Event processed successfully (138ms)

10/22/2020, 4:10:15 PM +587ms
+30ms ╔Subscribing to devices...
+174ms ║Device missing from piston. Loading all from parent (138ms)
+186ms ║Subscribing to Layla’s lights.level...
+199ms ║Subscribing to Master bedroom lights.level...
+221ms ╚Finished subscribing (193ms)
+240ms ║Comparison (integer) 94 is_less_than (integer) 20 = false (2ms)
+243ms ║Comparison (integer) 12 is_less_than (integer) 20 = true (2ms)
+260ms ║Comparison (string) 187 Montgomery Avenue Hubitat is (string) on = false (4ms)
+273ms ╔Starting piston... (v0.3.110.20200916_HE)
+274ms ╚Piston successfully started (253ms)
10/22/2020, 4:10:15 PM +587ms
+30ms ╔Subscribing to devices...
+174ms ║Device missing from piston. Loading all from parent (138ms)
+186ms ║Subscribing to Layla’s lights.level...
+199ms ║Subscribing to Master bedroom lights.level...
+221ms ╚Finished subscribing (193ms)
+240ms ║Comparison (integer) 94 is_less_than (integer) 20 = false (2ms)
+243ms ║Comparison (integer) 12 is_less_than (integer) 20 = true (2ms)
+260ms ║Comparison (string) 187 Montgomery Avenue Hubitat is (string) on = false (4ms)
+273ms ╔Starting piston... (v0.3.110.20200916_HE)
+274ms ╚Piston successfully started (253ms)

#2

currentEventDevice only holds one device which is the last one that triggered the piston. If you could have one, the other, or both at 20%, I suggest you store matching devices to another device variable and then change your with to that new variable for turning off the lights. Something like this:

define
 device lights = switch 1, switch 2
 device selectedLights
end define

if lights level is less than 20%
   save matching drives to selectedLights
   then
     wait 10 seconds
     if any of selectedLights switch is on
     then
       with selectedLights
           set level to 100%
           wait 2 seconds
           turn off
           wait 10 seconds
           send PUSH notification "blah"
        end with
    end if
end if

#3

This goal still makes me smile, but honestly, it is not a path I would normally recommend…


#4

I had the same dream (not being sarcastic) but realized really fast that the most elegant Webcore pistons are the simplest ones.


#5

Thanks for the replies. I guess I will just do one light per piston. As the saying goes, the simples solution is usually the best one.


#6

Seems like this would have implications for pistons that try to switch home states based on presence. I have one that listens for arrival/departure notifications for three phones (Life360 on iPhones using Life360 with States on Hubitat). Every now and then when all three phones leave home together the piston fails to execute departure actions.

Unfortunately I don’t have the logs from the most recent hiccup; I lost them when I edited the piston to add a bunch of traces to try to diagnose it next time it happens. I do recall though that a “device not present” event was recorded but then the trace on line 37 ({$currentEventDevice " departed."}) wasn’t there. So somehow the piston saw a presence sensor depart but then didn’t appear to do anything else.

Is there documentation somewhere that describes how webCoRE handles parallel execution of pistons?