Time Is Between condition not working properly


#1

1) Give a description of the problem
Time between condition not working properly.

2) What is the expected behaviour?
I expect the location mode to change to Night at 11:00 PM, and Home at 7:00 AM.

3) What is happening/not happening?
Instead, the location mode changed to Home at 11:00 PM and Night at 11:00 AM.

4) Post a Green Snapshot of the piston![image|45x37](

5) Attach logs after turning logging level to Full
9/14/2020, 6:59:59 AM +56ms
+0ms ╔Received event [Home].time = 1600081200000 with a delay of -945ms
+256ms ║RunTime Analysis CS > 25ms > PS > 5ms > PE > 227ms > CE
+259ms ║Runtime (39716 bytes) successfully initialized in 5ms (v0.3.110.20191009) (258ms)
+260ms ║╔Execution stage started
+280ms ║║Comparison (enum) present is (string) not present = false (2ms)
+283ms ║║Condition #3 evaluated false (18ms)
+284ms ║║Condition group #1 evaluated false (state did not change) (20ms)
+298ms ║║Comparison (time) 25199342 is_between (time) 82800000 … (time) 25200000 = false (10ms)
+300ms ║║Cancelling condition #6’s schedules…
+300ms ║║Condition #6 evaluated false (15ms)
+301ms ║║Cancelling statement #6’s schedules…
+306ms ║║Requesting time schedule wake up at Mon, Sep 14 2020 @ 11:00:00 PM EDT
+309ms ║║Cancelling condition #2’s schedules…
+309ms ║║Condition group #2 evaluated false (state changed) (24ms)
+312ms ║║Cancelling statement #4’s schedules…
+587ms ║║Executed virtual command setLocationMode (272ms)
+592ms ║║Calculating (string) Location mode changed to + (string) Night >> (string) Location mode changed to Night
+595ms ║║Calculating (string) Location mode changed to Night + (string) >> (string) Location mode changed to Night
+607ms ║║Executed virtual command sendPushNotification (10ms)
+610ms ║║Cancelling statement #14’s schedules…
+612ms ║║Executed virtual command setState (0ms)
+614ms ║╚Execution stage complete. (355ms)
+616ms ║Setting up scheduled job for Mon, Sep 14 2020 @ 11:00:00 PM EDT (in 57600.329s)
+622ms ╚Event processed successfully (622ms)
9/13/2020, 10:59:59 PM +80ms
+0ms ╔Received event [Home].time = 1600052400000 with a delay of -920ms
+136ms ║RunTime Analysis CS > 48ms > PS > 20ms > PE > 68ms > CE
+139ms ║Runtime (39719 bytes) successfully initialized in 20ms (v0.3.110.20191009) (138ms)
+140ms ║╔Execution stage started
+169ms ║║Comparison (enum) present is (string) not present = false (2ms)
+171ms ║║Condition #3 evaluated false (25ms)
+173ms ║║Condition group #1 evaluated false (state did not change) (27ms)
+191ms ║║Comparison (time) 82799255 is_between (time) 82800000 … (time) 25200000 = true (12ms)
+192ms ║║Time restriction check passed
+195ms ║║Cancelling condition #6’s schedules…
+198ms ║║Condition #6 evaluated true (24ms)
+205ms ║║Cancelling statement #6’s schedules…
+209ms ║║Requesting time schedule wake up at Mon, Sep 14 2020 @ 7:00:00 AM EDT
+213ms ║║Cancelling condition #2’s schedules…
+214ms ║║Condition group #2 evaluated true (state changed) (40ms)
+217ms ║║Cancelling statement #7’s schedules…
+2142ms ║║Executed virtual command setLocationMode (1920ms)
+2148ms ║║Calculating (string) Location mode changed to + (string) Home >> (string) Location mode changed to Home
+2151ms ║║Calculating (string) Location mode changed to Home + (string) >> (string) Location mode changed to Home
+2192ms ║║Executed virtual command sendPushNotification (38ms)
+2195ms ║║Cancelling statement #14’s schedules…
+2198ms ║║Executed virtual command setState (1ms)
+2200ms ║╚Execution stage complete. (2061ms)
+2201ms ║Setting up scheduled job for Mon, Sep 14 2020 @ 7:00:00 AM EDT (in 28798.719s)
+2208ms ╚Event processed successfully (2208ms)


#2

I did not dig into your piston or the log. But when I want to span time over midnight, I use the NOT option.

Time is NOT between 7am and 11pm.

It sometimes takes a little thought to understand. But it works well and avoids the situation of the date/time change at midnight.


#3

Why would that fix it?


#4

In our minds, 11PM to 7AM is an 8 hr window overnight…

But in computer logic… that window can be 16 hrs long, and in the daytime.
For example: 4PM is in between 11PM and 7AM.
(IE: 57,600,000 is in between 82,800,000 and 25,200,000)

By keeping both times in the same day with inverted logic:
IF Time is NOT between 7am and 11pm
then it will be true overnight, and false all other times.


Also, I would ditch the ELSE IF, and simply make it a standard IF down below.
(in an independent block)

In other words, keep your presence logic in one block, and time logic in another.

IF Presense X
    Then do stuff
END IF

IF Time is not between 7am and 11pm
    Then set Night mode
    ELSE set Home mode
END IF

Set piston state

#5

I took another look at this…and I am somewhat confused.

82799255 (hour 22.9997) is between 82800000 (11 PM) and 25200000 (7 AM) and the “Time restriction check passed” and Condition 6 is true. So why did Location mode get changed to “Home” in the ELSE statement?


#6

Well, technically, 82799255 is in between 82800000 and 25200000…
(but 0.745 seconds later, it would be false)

I suspect the ELSE IF is causing havoc.

Notice how after the time evaluation, webCoRE does not change the location.
(it checks condition #2 first… whatever that is)


Pro Tip:

When this condition:
IF Time is between X and Y
is treated like a trigger, it only fires twice a day.

I usually write these as separate blocks. Either:

IF Time happens daily at 7am
    Set location to Home
END IF

… or …

Every day at 7am
    Set location mode to Home
END EVERY

Note the first example runs thru the entire piston…
The second example only executes that one block, and then stops.


#7

Just another case point why I don’t like using ELSE IF.


#8

Oh, one more point I just noticed…

Notice how the log shows:
+ 198ms ║║Condition #6 evaluated true
+2142ms ║║Executed virtual command setLocationMode

… and then 0.009 seconds later…

+2151ms ║║Calculating (string) Location mode changed to Home

How likely do you think that 9 ms is enough time for a device to receive a request… take action… and update the hub afterwards?


#9

I’m sure it is but I have no idea why it would be. Seems like a very straightforward elseif to me. But I have very little experience in WebCore, just a little bit in other languages.

@WCmore I totally get why it’s clearer to write them in separate blocks as triggers at a certain time. That being said, I was hoping to figure out why this isn’t working because if I go that route, I’m afraid i’ll end up having 3 different blocks with triggers for each mode, which would be a lot less clean than the logic I’m currently trying to make work. If that makes sense.


#10

Perhaps… but remember every single trigger will run thru the entire piston, top to bottom…
(no matter where you place the trigger)

So I recommend coding to make the piston run smoother.
(even if it may LOOK more complicated)


Note:

  • A trigger for location X

will execute the piston, and run top to bottom on ANY change to location.
(you do not need three lightning bolts)


#11

Have you confirmed that independently of the piston? Or are you just assuming $locationMode is correct when you use it? Might it only be updated when the piston runs for example?


#12

Made some changes… this is what it looks like now:

First of all, it did not correctly change the mode to Night at 11:00PM last night. Second of all, why is there no lightning bolt next to the IF statement on line 44? That looks like a trigger to me.


#13

That block at 42-51 looks good… I would love to see a Full log of this…


Line 45 is a condition, not a trigger.
(We cannot place triggers inside an EVERY block)

But that being said, Sensor 1 and Sensor 2’s presense IS a trigger on line 22… So any changes to presence will run thru the entire piston, top to bottom. (ignoring anything inside an EVERY block)


Side Note:

You did not mention it, but your final block (52-57) will never execute. Try this method instead:

pic

This should place a lightning bolt next to that line.
pic

(just remember it runs thru the entire piston at each change)


#14

Sorry, I actually must’ve gotten my line numbers mixed up, that was the block I was talking about (52-57)! I was wondering why the variable $locationMode wasn’t being subscribed to. Why won’t it ever execute? Is the $locationMode variable different than the virtual device “Location mode”? I figured they were one and the same. With that in mind, should I also change line 55 to this instead?
image

But thank you for the suggestion, I will try it!


#15

Quick answer: Yes, in some cases.


Piston state is simply text, so both of yours may work… but here is how I code that line:

pic


Side Note:

The reason I switched your line 53 away from $locationMode is because system variables (starting with $) typically make lousy triggers.