Closed pkkrusty closed 2 years ago
Added TasmotaGlobal.rules_flag.time_init = 1;
after line 492 in support_rtc.ino to trigger time#initialized when time is entered manually. Not sure if that's acceptable to the broader community but it makes sense to me, if someone is purposely not using NTP, that time is initialized once it's entered from an alternative source (in this case, my fingers on the keyboard). Once I get some feedback from higher-ups, I can submit a PR.
After more digging, it looks like an issue with my use of > with the time#initialized trigger. With a straight time#inititalized trigger, it fires normally at around 300ms after boot (before I'd like it to, since I get some conflicts with the resulting backlog execution from system#init. Thus I want to use time#initialized>10 to let the system settle down before my next set of rules executes. But between the DS3231 setting the time and 10 seconds, the flag gets lost.
While I'm messing around with DS3231 driver, I'd like to change the offset for re-writing to the DS3231 to 10 second instead of 60 (Line 157). Any objections to that? Personal preference, but computation time is cheap, and a sync every 5 days instead of 30 days doesn't make too much difference in terms of CPU load, but would keep the DS3231 much closer to true time if internet goes out for an extended period.
Latest work: If I flash a lite build, without tasmesh, influxdb, sunrise, ping, expression, if_statement, and most sensors disabled, time#initialized>10 triggers. so does >50. And time#initialized fires at around 130ms.
However, I note that 120 does not equal 120 seconds as indicated by documentation. Makes no difference what number I put in, it still triggers about 20ms after the initial trigger.
00:00:00.001 HDW: ESP8266EX
00:00:00.020 UFS: FlashFS mounted with 1992 kB free
00:00:00.095 CFG: Loaded from File, Count 26
00:00:00.101 QPC: Count 1
00:00:00.103 CFG: CR 458/699, Busy 0
00:00:00.107 SRC: Restart
00:00:00.109 Project pkkrusty - Tasmota Version 10.0.0.3(tasmota)-2_7_4_9(2022-01-07T15:03:18)
00:00:00.111 I2C: DS3231 found at 0x68
00:00:00.131 Set time from DS3231 to RTC (UTC) 2022-01-07T15:33:15, (DST) 2022-03-27T00:00:00, (STD) 2022-10-30T00:00:00
00:00:00.131 RTC: Rtc.utc_time set correctly by DS3231
00:00:00.132 Rtc.utc_time 1641569595
00:00:00.132 Rtc.local_time 0
00:00:00.218 WIF: Attempting connection...
00:00:00.555 WIF: Connecting to AP2 beersheba Channel 6 BSSId D8:0D:17:B3:A6:E6 in mode 11n as pkkrusty-AF8D12-3346...
00:00:00.001 RTC: Not synced
15:33:16.010 RUL: TIME#INITIALIZED performs "power1 1"
15:33:16.011 SRC: Rule
15:33:16.012 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:33:16.015 RSL: RESULT = {"POWER":"ON"}
15:33:16.016 RSL: POWER = ON
15:33:16.027 RUL: TIME#INITIALIZED>111 performs "power1 1"
15:33:16.028 SRC: Rule
15:33:16.029 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:33:16.032 RSL: RESULT = {"POWER":"ON"}
15:33:16.033 RSL: POWER = ON
15:33:16.044 RUL: TIME#INITIALIZED>120 performs "power1 1"
15:33:16.045 SRC: Rule
15:33:16.046 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:33:16.049 RSL: RESULT = {"POWER":"ON"}
15:33:16.050 RSL: POWER = ON
If I remove the DS3231 and just use NTP servers, same issue.
00:00:00.001 HDW: ESP8266EX
00:00:00.022 UFS: FlashFS mounted with 1992 kB free
00:00:00.100 CFG: Loaded from File, Count 29
00:00:00.105 QPC: Count 1
00:00:00.107 CFG: CR 458/699, Busy 0
00:00:00.111 SRC: Restart
00:00:00.113 Project pkkrusty - Tasmota Version 10.0.0.3(tasmota)-2_7_4_9(2022-01-07T15:03:18)
00:00:00.221 WIF: Attempting connection...
00:00:00.558 WIF: Connecting to AP2 beersheba Channel 6 BSSId D8:0D:17:B3:A6:E6 in mode 11n as pkkrusty-AF8D12-3346...
00:00:01.753 WIF: Connected
00:00:02.005 HTP: Web server active on pkkrusty-AF8D12-3346 with IP address 192.168.1.50
00:00:02.006 UPP: Multicast (re)joined
00:00:02.312 HTP: Console
00:00:02.438 NTP: Synch time...
00:00:02.551 NTP: Runtime 0
00:00:02.551 Rtc.utc_time 1641569930
00:00:02.552 Rtc.local_time 2
00:00:02.554 RTC: UTC 2022-01-07T15:38:50, DST 2022-03-27T00:00:00, STD 2022-10-30T00:00:00
00:00:02.554 support_rtc function running correctly, rtc.utc_time set
00:00:02.555 Rtc.utc_time 1641569930
00:00:02.556 Rtc.local_time 2
15:38:50.000 NTP: Synched
15:38:50.035 RUL: TIME#INITIALIZED performs "power1 1"
15:38:50.036 SRC: Rule
15:38:50.037 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:38:50.040 RSL: RESULT = {"POWER":"ON"}
15:38:50.041 RSL: POWER = ON
15:38:50.054 RUL: TIME#INITIALIZED>10 performs "power1 1"
15:38:50.055 SRC: Rule
15:38:50.056 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:38:50.059 RSL: RESULT = {"POWER":"ON"}
15:38:50.061 RSL: POWER = ON
15:38:50.070 RUL: TIME#INITIALIZED>120 performs "power1 1"
15:38:50.071 SRC: Rule
15:38:50.072 CMD: Grp 0, Cmnd 'POWER', Idx 1, Len 1, Data '1'
15:38:50.075 RSL: RESULT = {"POWER":"ON"}
15:38:50.077 RSL: POWER = ON
If sleep
is activated it is normal that the MCU reacts not so fast.
Reducing the drivers lowers the CPU load. So the behaviour you see is normal and as expected. Tasmota is NOT RTOS
So documentation is not accurate? The > symbol doesn't seem to do anything. Load average for even the big firmware is only 19, leaving plenty of overhead in the sleep cycle. Seems like > symbol in that trigger is just getting executed on the next loop.
A low LoadAVG does not mean the device will react as fast as when sleep is switched off.
Makes sense. But > modifier still doesn't have an effect even on a lightly loaded processor.
Also doesn't work correctly if Sleep 0
Do not assume that LoadAvg is a simple measure of how busy it is. It can even get above 100, depending on circumstances.
@sfromis any way to get any kind of real-time feedback on load? I'm curious what levels it hits with various builds. For example, things definitely feel slower on the WebUI when I have Tasmesh included.
Not really. And even having the LoadAvg every TelePeriod (not available faster, unless you fire off lots of commands to query state all the time), you may be assuming too much importance of that number.
While I've not at all looked into the Tasmesh driver, on a general level timing-depend things doing blocking delays can really mess with how well Tasmota operates, as techniques quite viable for the MCU only having one thing to do may just not work when it has to relinquish control to other functions having urgent needs of being allowed to run.
I'm not surprised if mixing types of network communication at the same time may not be snappy, as there is no "real multitasking".
Looks for me also as a bug. Maybe you can output the value of time initialized when the rule gets executed. It looks like this value is much higher than the 10 or 120. this would explain why all the triggers get executed immediately.
I added some debugging when I thought it was a problem with the ds3231 driver, and the two key values are rtc.local_time and rtc.utc_time being less than and greater than 2016-01-01 in epoch time, respectively. That lets an if statement trigger the flag. But I can't figure out the rules code that deals with comparators to see what the >10 or >120 is comparing against. Epoch time? Milliseconds since boot?
Ah i didn't initially understand your suggestion, but now I do. I published %value% and sure enough, it looks like milliseconds from boot. I can work with that, but either documentation or implementation should get fixed. Votes?
Never the implementation as it has been working for many people for many years.
I haven't read this whole thread but from the beginning I understand the supposed rule time#initialized>10
was never meant to be used like this. Only time#initialized
is supposed to be used and occurs when the RTC code is initialised with some kind of time but not a time after 2016.
Looking at the code you'll see what happens:
if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01
TasmotaGlobal.rules_flag.time_init = 1;
} else {
TasmotaGlobal.rules_flag.time_set = 1;
}
The goal of this code is twofold:
Again see code below:
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break;
case 3: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break;
I suggest you rather learn to read the code than keep suggesting solutions based on guess work to eleviate long discussions like this.
Based on my last test, time#initialized value is milliseconds since boot. Thus the comparator will work, but not as described in documentation. I'm happy to fix that.
I'm also happy to leave my issues threads just stating the problem, but wanted to fill in readers with steps I took to narrow it down, since often problems are user error rather than coding or documentation. Reading code is like learning a language, it takes time. I'm currently at the 2-year-old copycat stage.
I totally understand but...
From the code you can clearly see it's NOT milliseconds after a reboot BUT it's minutes past midnight.
Feel free to update any documentation with valid information.
To overcome your problem just use time#initialized and fire a 10 second timer. The the timer will finally execute your script. I think this should work
Closing since it is answered. As designed
Question: Has anyone ever had success with Time#Initialized>10 (or any number) trigger? Even when I evaluate it as MinutesPastMidnight, it doesn't trigger when the threshhold is reached. Maybe doesn't belong in the Rules documentation.
Did a small test, restarted with:
on Time#Initialized do var1 %value% endon on Time#Initialized>100 do var2 %value% endon
Seems to work as already suggested here.....
18:34:17.020 RUL: TIME#INITIALIZED performs "var1 1114"
18:34:17.022 SRC: Rule
18:34:17.023 CMD: Grp 0, Cmnd 'VAR', Idx 1, Len 4, Data '1114'
18:34:17.028 RSL: VAR = {"Var1":"1114"}
18:34:17.039 RUL: TIME#INITIALIZED>100 performs "var2 1114"
18:34:17.040 SRC: Rule
18:34:17.042 CMD: Grp 0, Cmnd 'VAR', Idx 2, Len 4, Data '1114'
18:34:17.046 RSL: VAR = {"Var2":"1114"}
Your phrase it doesn't trigger when the threshhold is reached
does not seem to suggest you being aware that it is only being evaluated once, and not continuously. For "normal" timers, you may want Time#Minute>10
Anyway, while a number can be used with Time#Initialized
, I'd say that the value of reacting to time-of-day at NTP init time may not be a very common use case.
PROBLEM DESCRIPTION
A clear and concise description of what the problem is. When DS3231 is attached and functioning, the 8266 gets its time from the DS3231 before hitting the NTP server, and my rule trigger (time#initialized>10) never fires. Rule doesn't fire whether I have a valid NTP server or not, since DS3231 driver pre-empts the time#initialized flag in rtc_support.ino from firing by causing rtc.local_time to get filled in before the first rtcsecond() function call. Maybe because the rule is triggered before rtc.utc_time is distributed to all the system components, and thus the 10 second delay has a math error when it comes time to publish it?
When DS3231 is disconnected, and I have a valid NTP server, the time#initialized>10 trigger fires (albeit at the incorrect time).
REQUESTED INFORMATION
Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!
Backlog Template; Module; GPIO 255
:Status 0
:TO REPRODUCE
Steps to reproduce the behavior: Add a DS3231 and try to get time#initialized>5 or 10 or anything triggered
EXPECTED BEHAVIOUR
A clear and concise description of what you expected to happen. time#initialized>10 triggered once rtc.utc_time is set by either ntp or ds3231 (or ideally the time command)
SCREENSHOTS
If applicable, add screenshots to help explain your problem.
ADDITIONAL CONTEXT
Add any other context about the problem here.
(Please, remember to close the issue when the problem has been addressed)