# Nested condition based on time of previous events not running

#1

1) Give a description of the problem
I have a nested condition that reads:

if door lock was not (unknown, unlocked) for at least 5 minutes
and
previousAge(motion sensor) > 30s is true

that doesn’t seem to be evaluated even though it has subscribed to the door lock event.

For further context, if it is needed I have a motion sensor in my garage and an August door lock leading to the backyard.

time is not* between sunset-30 and nextSunrise+30
if rear door is unlocked
then turn on garage rear light, garage light, riser lights
Else if garage motion is active
Then turn on garage lights, riser lights
else
/* PROBLEM AREA */
if rear door was not (unknown, unlocked) for at least 5 minutes
and
previous age motion > 30000
/* END PROBLEM AREA */
then
if all/any other outdoor lights are on,
then turn off garage light, riser light (keep outdoor light on)
else
turn off garage, riser and back door light
else
If garage motion is active
then turn on garage lights, riser lights
else wait 5 minutes and turn off

(*in the image, I have the time reversed just because I want to test this during the day)

2) What is the expected behavior?
I expect that the condition will be evaluated at 5 minutes after the lock is locked for 5 minutes.

3) What is happening/not happening?
The rest of the condition runs when motion/locks change. However, if nothing happens with either of these the piston doesn’t seem to be evaluated. I waited ~15 minutes after the condition should be evaluated but nothing appeared in the logs.

**4) Post a Green Snapshot of the piston

**5) Attach any logs

Piston successfully ran at 8:39. It had one more event at 8:43. Then nothing happened for 15 minutes.

12/7/2018, 8:43:30 AM +102ms
+0ms	╔Received event [Home Hub].time = 1544201011944 with a delay of -1843ms
+190ms	║RunTime Analysis CS > 18ms > PS > 109ms > PE > 64ms > CE
+193ms	║Runtime (48257 bytes) successfully initialized in 109ms (v0.3.108.20180906) (192ms)
+194ms	║╔Execution stage started
+195ms	║╚Execution stage complete. (1ms)
+197ms	╚Event processed successfully (196ms)
12/7/2018, 8:39:07 AM +187ms
+1ms	╔Received event [Garage Motion Sensor].motion = inactive with a delay of 104ms
+184ms	║RunTime Analysis CS > 21ms > PS > 101ms > PE > 62ms > CE
+187ms	║Runtime (48260 bytes) successfully initialized in 101ms (v0.3.108.20180906) (185ms)
+188ms	║╔Execution stage started
+251ms	║║Calculating (decimal) 0.0 - (decimal) 30.0 >> (decimal) -30.0
+265ms	║║Comparison (datetime) 1544200747382 is_not_between (datetime) 1544228400000 .. (datetime) 1544283480000 = true (4ms)
+267ms	║║Condition #47 evaluated true (73ms)
+268ms	║║Condition group #13 evaluated true (state did not change) (75ms)
+282ms	║║Comparison (enum) locked is_any_of (string) unknown,unlocked,unlocked with timeout = false (4ms)
+284ms	║║Condition #21 evaluated false (13ms)
+285ms	║║Condition group #30 evaluated false (state did not change) (15ms)
+293ms	║║Comparison (enum) inactive is (string) active = false (2ms)
+295ms	║║Cancelling condition #53's schedules...
+296ms	║║Condition #53 evaluated false (8ms)
+297ms	║║Cancelling condition #51's schedules...
+298ms	║║Condition group #51 evaluated false (state changed) (12ms)
+447ms	║║Duration 261349ms for was_not_any_of >= 300000ms threshold = false
+448ms	║║Comparison (enum) locked was_not_any_of (string) unknown,unlocked,unlocked with timeout = false (141ms)
+450ms	║║Condition #56 evaluated false (150ms)
+451ms	║║Condition group #52 evaluated false (state did not change) (152ms)
+454ms	║╚Execution stage complete. (266ms)
+455ms	╚Event processed successfully (455ms)

#2

I’ve also tried to replace the problem statements with:

if lock was locked for at least 5 minutes
and
previous age motion > 30000

and also

if (previous age motion < previous age door lock ? previous age door lock : previous age motion)
is greater than 60000 (1 min)

but nothing seems to trigger the else-if statement when there isn’t an actual event (a non-condition? - if that’s the right terminology).

I also tried to make the condition a trigger (based on IS (for at least../for less than)). This subscribed to the trigger (but none of the other conditions) but still never ran after a minute.

I’m sure there is a way to do this and I could use some help…

#3

I’m no expert but is there a reason why you look for not unlocked/unknown vs locked? Are you just testing this by running piston manually? I don’t think this will actually ever run except at sunrise (for the current condition). Have you tried locking the door leaving and waiting for >5 minutes and then forcing the piston to run using the test button? Seems like it might work then. Overall, I think you need to get your conditions/triggers out of the time if and check the time when one of those go off rather than the other way around.

#4

I agree with @guxdude
I would make triggers top level (far left un-indented) and place your conditions inside that.

IE:

IF Lock 1's lock changes away from locked  <-- Trigger
Then
IF Time is between X & Y               <-- Condition
Then
Turn on lights etc
END IF
END IF

The triggers will get lightning bolts in the left margin, the conditions will not

#5

Thanks @WCmore. Understand about the trigger then condition thought. I’ve tried to get that working in the revision below.

@guxdude Good questions. I’ve gotten to the below piston which works for nearly all situations.

The one it doesn’t work for is as follows:
I come in through the back door and unlock it. Indoor/outdoor lights turn on. I close the door behind me and lock it. Timer goes for 30 seconds and wants to turn off all the same lights. However, then the motion sensor sees me and (with the door now being locked), only waits and then turns off the indoor light.

The logic flow that I’m trying to work with is:

2. Evaluate condition
3. Wait
4. Take action

Is there a good way to reverse 2 and 3?

2. Wait
3. Evaluate condition
4. Take action

EG - My logic would be much easier if I could do something like:

1. Event/Trigger received for  door lock changed or motion changed
2. If time=night
then turn on indoor and outdoor lights
3. Wait 30 seconds
4. If other nearby back yard lights are on,
then turn off only indoor light
else turn off indoor/outdoor lights
5. else if time=day
then turn on indoor light
6.  wait 30 seconds
7.  turn off indoor light

This is essentially what I was trying to accomplish in the initial example with the “if the lock was not unlocked/unlocked with timeout/unknown for at least the past 5 minutes” in the first example. Even though that statement is a trigger, it acts more like a condition.

#6

Ok, I think I finally got it. That ended up being pretty tricky. The “door lock is open OR door lock has changed in the past x seconds” coupled with the repeat…until block were the missing pieces.

Thanks again to both of you.