It would be good to see the enum one as well as one of the decimal power pistons.
Power Comparison Failed
Hereâs one of the logs that shows an OK comparison and one that is wrong.
2/24/2018, 11:38:00 AM +365ms
+5ms âReceived event [Home].time = 1519497481403 with a delay of -1048ms
+268ms âRunTime Analysis CS > 46ms > PS > 127ms > PE > 100ms > CE
+277ms âRuntime (39934 bytes) successfully initialized in 127ms (v0.2.102.20180116) (265ms)
+282ms ââExecution stage started
+427ms ââComparison (enum) on is (string) on = true (7ms)
+434ms ââCondition #7 evaluated true (47ms)
+503ms ââvalueWas [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:0.2, d::294904ea719da70376d4625934e3c493:, a:power, i:null, x:false, vt:string]]
+514ms âânew comparison: true
+514ms ââoriginal: true
+514ms ââevent duration: 18579
+515ms ââtotal duration: 0
+515ms ââvalue: [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:0.2]]
+515ms âârightValue: [i:9:1:0, v:[t:integer, v:20, d:0, vt:decimal]]
+515ms âârightValue2: null
+520ms âânew comparison: true
+520ms ââoriginal: true
+520ms ââevent duration: 1009
+521ms ââtotal duration: 18579
+521ms ââvalue: [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:1.1]]
+521ms âârightValue: [i:9:1:0, v:[t:integer, v:20, d:0, vt:decimal]]
+521ms âârightValue2: null
+527ms âânew comparison: false
+527ms ââoriginal: true
+527ms ââevent duration: 1003
+527ms ââtotal duration: 19588
+527ms ââvalue: [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:21.9]]
+528ms âârightValue: [i:9:1:0, v:[t:integer, v:20, d:0, vt:decimal]]
+528ms âârightValue2: null
+529ms ââComparison (decimal) 0.2 was_less_than (integer) 20 = false (84ms)
+531ms ââCondition #9 evaluated false (96ms)
+533ms ââCondition group #2 evaluated false (state did not change) (151ms)
+549ms ââComparison (enum) on is (string) off = false (4ms)
+551ms ââCondition #19 evaluated false (12ms)
+552ms ââCondition group #16 evaluated false (state did not change) (15ms)
+567ms ââExecution stage complete. (289ms)
+584ms âSetting up scheduled job for Sat, Feb 24 2018 @ 11:40:01 AM MST (in 120.458s)
+594ms âEvent processed successfully (597ms)
2/24/2018, 11:36:00 AM +405ms
+1ms âReceived event [Home].time = 1519497361403 with a delay of -999ms
+214ms âRunTime Analysis CS > 25ms > PS > 117ms > PE > 72ms > CE
+216ms âRuntime (39932 bytes) successfully initialized in 117ms (v0.2.102.20180116) (214ms)
+217ms ââExecution stage started
+240ms ââComparison (enum) on is (string) on = true (5ms)
+241ms ââCondition #7 evaluated true (13ms)
+281ms ââvalueWas [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:76.6, d::294904ea719da70376d4625934e3c493:, a:power, i:null, x:false, vt:string]]
+285ms âânew comparison: false
+285ms ââoriginal: true
+285ms ââevent duration: 2416
+285ms ââtotal duration: 0
+285ms ââvalue: [i::294904ea719da70376d4625934e3c493::power, v:[t:decimal, v:76.6]]
+286ms âârightValue: [i:9:1:0, v:[t:integer, v:20, d:1, vt:decimal]]
+286ms âârightValue2: null
+286ms ââComparison (decimal) 76.6 was_less_than (integer) 20 = false (36ms)
+288ms ââCondition #9 evaluated false (46ms)
+289ms ââCondition group #2 evaluated false (state did not change) (61ms)
+300ms ââComparison (enum) on is (string) off = false (2ms)
+301ms ââCondition #19 evaluated false (9ms)
+303ms ââCondition group #16 evaluated false (state did not change) (12ms)
+306ms ââExecution stage complete. (89ms)
+308ms âSetting up scheduled job for Sat, Feb 24 2018 @ 11:38:01 AM MST (in 120.691s)
+317ms âEvent processed successfully (317ms)
The logs show that the piston run at 11:38:00 AM was about 20 seconds after a 21.9W reading. Additionally since the power was 76.6W at 11:36:00 AM we wouldnât expect the 15 minutes to be elapsed yet, right?
Right, the 15 min has not up yet. But I did not run it long enough to see what would have happened at 11:53. I was just looking at the result of the comparison that said Comparison (decimal) 0.2 was_less_than (integer) 20 = false (84ms). If itâs OK, then I will keep that version running for now and let it go through some normal cycles to see if anything hiccups.
BTW, that piston that I showed before for the recirc pump that failed the enum test is now running fine with this version with no failures that I can detect. Would it be useful for me to try your original changed version again? Maybe something got screwed up when I did the change the 1st time.
The version you are using will be fine, we plan to do a release today so you can just update later to get rid of the debug code.
The condition is returning false because of the duration rather than the value, itâs just not clear from the âComparison (decimal) 0.2 was_less_than (integer) 20 = false (84ms)â log text. I canât edit that specific text but I could add a debug message above it to specify that the condition check failed because of the duration - I think that would avoid a lot of confusion since the was operator is more complicated than the logs show.
How do you feel about changing the log to the following to clarify the failure? I can add a log line before the comparison:
+711ms | ââDuration 191344ms for was_greater_than >= 900000ms threshold = false |
---|---|
+712ms | ââComparison (decimal) 5762.0 was_greater_than (integer) 1040 = false (72ms) |
Caveat â frequently updated attributes
I will leave this discussion with a final important note: was
comparisons only look at the last 100 events in your device state. If you are trying to observe a 15 minute time window on an attribute that is updated every second your condition will never be true! You could only inspect a window of up to about 100 seconds under those conditions. Instead, consider building your logic around stays
which monitors a state going forward rather than looking back at past values.
For the log line, sure, that makes sense. For the WAS comparison, Iâm only looking at 7 or 8 past events to get to 15 min (once every 2 min). But when the TV is on, it looks like the power adapter is sending 11-15 updates/min back to the hub that I can see in the mobile app, so likely only 7 min worth of data in the 100 samples. But as it is shutting off, it sends less and less data, so that when itâs off, it is sending no data. Used in this way, there might not be a problem at 15 min. But I will look at using STAY instead. And thanks, I did not know or think about a restriction on WAS.
Again, thanks for finding a fix to this problem.
Yep, exactly. The was condition can be quite tricky but Iâm very glad that you were persistent with this issue until it was identified and fixed!
Oops! To address any lingering confusion you may have about the first bit of code that I posted, it turned out to have a serious typo. Rather than casting the power value to a decimal value it was trying to cast the word âdecimalâ to a number because I switched the order of the parameters. The actual comparison ended up being "decimal" < 10.0
which was⌠not right
Figured this out when testing was greater than
and it was saying that 3000 was not greater than 1000.
Does not affect the second bit of code that was posted, and I went back to correct the original one in case anyone finds this thread later.
Ah, that explains why all my pistons that used the WAS condition failed. The 2nd code, the whole function, seems to work well.
Ian - I just updated to the newest WebCore version. Just after I did, it ran my WAS piston. Here are the logs. I like the additional logging for the time restriction of the WAS, thanks, and it shut off the bulb as it was supposed to. But then it was followed by a Skip Execution statement for the 2nd device, but then it tried to Off the device anyway. Hmmm. It does not really matter, just a non-consequential contradiction. Am I interpreting those statements correctly?
2/25/2018, 9:32:40 PM +387ms
+1ms âReceived event [Home].time = 1519619561101 with a delay of -714ms
+206ms âRunTime Analysis CS > 14ms > PS > 87ms > PE > 105ms > CE
+209ms âRuntime (40577 bytes) successfully initialized in 87ms (v0.3.000.20180224) (208ms)
+210ms ââExecution stage started
+231ms ââComparison (enum) on is (string) on = true (2ms)
+233ms ââCondition #7 evaluated true (9ms)
+285ms ââComparison (time) 77560621 is_between (time) 75600000 ⌠(time) 1519565880000 = true (11ms)
+287ms ââTime restriction check passed
+288ms ââCondition #22 evaluated true (55ms)
+327ms ââDuration 935852ms for was_less_than >= 900000ms threshold = true
+328ms ââComparison (decimal) 0.3 was_less_than (integer) 20 = true (33ms)
+330ms ââCancelling condition #23âs schedulesâŚ
+331ms ââCondition #23 evaluated true (41ms)
+332ms ââCancelling condition #2âs schedulesâŚ
+332ms ââCondition group #2 evaluated true (state changed) (109ms)
+335ms ââCancelling statement #10âs schedulesâŚ
+578ms ââExecuted physical command [Living Room Bulb].off() (240ms)
+579ms ââExecuted [Living Room Bulb].off (241ms)
+583ms ââSkipped execution of physical command [Living Room Light].off([]) because it would make no change to the device. (2ms)
+584ms ââ_Executed [Living Room Light].off (4ms)_
+595ms ââComparison (enum) on is (string) off = false (2ms)
+596ms ââCondition #19 evaluated false (8ms)
+597ms ââCondition group #16 evaluated false (state did not change) (10ms)
+600ms ââExecution stage complete. (391ms)
+602ms âSetting up scheduled job for Sun, Feb 25 2018 @ 9:34:41 PM MST (in 120.113s)
+609ms âEvent processed successfully (609ms)
Nothing to worry about there, the âExecutedâ line is always logged after calling the smart app function that performs (or in this case does not perform) the physical command or after calling a command built into webCoRE like setColorTemperature.
This one?
+584ms ââExecuted [Living Room Light].off (4ms)
That one will always be logged regardless of whether the command is physical or virtual and whether it actually interacts with the device or not.
def msg = timer "Executed [$device].${task.c}"
try {
delay = "cmd_${task.c}"(rtData, device, params)
} catch(all) {
executePhysicalCommand(rtData, device, task.c, params)
}
if (rtData.logging > 1) trace msg, rtData // <-- here
Itâs just confusing. The previous statement said it was not going to execute followed by a statement that said it did execute.