ESP8266 v1.50 - SETTIME error

Here we can discuss about the problem found
Post Reply
ChipBurner
Posts: 10
Joined: Tue Mar 19, 2024 6:54 am
Has thanked: 2 times

ESP8266 v1.50 - SETTIME error

Post by ChipBurner »

Hi all!
1.When the time zone setting has a DST rule, then the SETTIME statement sets the time incorrectly.
2.The DST offset is used with the wrong sign.
My test code:

Code: [Local Link Removed for Guests]

wlog "--- DST test. Used tz: CET-1CEST,M3.5.0,M10.5.0/3 ---"
wlog "SETTIME 24/03/31 00:00:00"+" winter (STD) time"
SETTIME 24,3,31,0,0,0
wlog "date$+time$: "+date$+" "+time$
dt1=dateunix(date$)+timeunix(time$)
dtc=dateunix("31/03/24")+timeunix("00:00:00")
wlog "result dateunix(date$)+timeunix(time$): "; STR$(dt1,"%10u",1)
wlog "result dateunix(24/3/31)+timeunix(00:00:00): "; STR$(dtc,"%10u",1)
wlog "SETTIME 24/03/31 04:00:01"+" summer (DST) time"
SETTIME 24,3,31,4,0,0 
wlog "date$+time$: "+date$+" "+time$
dt2=dateunix(date$)+timeunix(time$)
dtc2=dateunix("31/03/24")+timeunix("04:00:00")
wlog "result dateunix(date$)+timeunix(time$): "; STR$(dt2,"%10u",1)
wlog "result dateunix(24/3/31)+timeunix(00:00:00): "; STR$(dtc2,"%10u",1)
wlog "difference dt2-dt1(sec): "; dt2-dt1;":"; (dt2-dt1)\3600;" hours"
wlog "--------------------------------"
wlog "SETTIME 24/10/27 00:00:00"+" summer (DST) time"
SETTIME 24,10,27,0,0,0
wlog "date$+time$: "+date$+" "+time$
dt1=dateunix(date$)+timeunix(time$)
dtc=dateunix("27/10/24")+timeunix("00:00:00")
wlog "result dateunix(date$)+timeunix(time$): "; STR$(dt1,"%10u",1)
wlog "result dateunix(24/10/27)+timeunix(00:00:00): "; STR$(dtc,"%10u",1)
wlog "SETTIME 24/10/27 04:00:00"+" winter (STD) time"
SETTIME 24,10,27,4,0,0 
wlog "date$+time$: "+date$+" "+time$
dt2=dateunix(date$)+timeunix(time$)
dtc2=dateunix("27/10/24")+timeunix("04:00:00")
wlog "result dateunix(date$)+timeunix(time$): "; STR$(dt2,"%10u",1)
wlog "result dateunix(27/10/24)+timeunix(04:00:00): "; STR$(dtc2,"%10u",1)
wlog "difference dt2-dt1(sec): "; dt2-dt1;":"; (dt2-dt1)\3600;" hours"
wlog "----------- winter/summer time change test --------------"
wlog "SETTIME 24/03/31 02:59:59"+" winter time ends"
SETTIME 24,03,31,2,59,59
for i=1 to 4
  wlog date$+" "+time$
  pause 1000
next i
wlog "----------- summer/winter time change test --------------"
wlog "SETTIME 24/10/27 02:59:59"+" summer time ends"
SETTIME 24,10,27,2,59,59
for i=1 to 4
  wlog date$+" "+time$
  pause 1000
next i
 
end
ChipBurner
Posts: 10
Joined: Tue Mar 19, 2024 6:54 am
Has thanked: 2 times

Re: ESP8266 v1.50 - SETTIME error

Post by ChipBurner »

It seems to me that the date and time functions available in Annex Basic now cannot correctly convert date and time strings separately to unix format due to the daylight saving time rule.
IMHO, new functions datetimeunix(concatenated datetime$) and unixdatetime$(value, format) are needed to handle data according to time zone and daylight saving time rules. The existing functions dateunix, timeunix, unixdate$, unixtime$ should use the time zone and not use the DST rule.
User avatar
Electroguard
Posts: 1094
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 373 times
Been thanked: 392 times

Re: ESP8266 v1.50 - SETTIME error

Post by Electroguard »

Hi ChipBurner,
CiccioCB is probably enjoying a well-earned Christmas holiday, and I am replying with my initial thought so that you don't feel ignored.

I haven't had opportunity to deep dive into your problem, but as far as I know the Annex date$ and time$ are purely local, and it is only the 'get internet date/time' routine which actually uses the DST setting to produce the local Annex time with the required offset from the world time.
In which case it would be incorrect to try to add the DST offset again to any local date/time and local unixdate/time, because they have already been adjusted by the DST offset.

It may help to consider that Annex local date and time plus its unix date and time all have to work correctly on an isolated device without internet connection and therefore no knowledge of internet time or DST offsets,

So whatever you are trying to do, it may simply be a matter of commenting out wherever you are trying to add/subtract the DST offset to any of the local times.
ChipBurner
Posts: 10
Joined: Tue Mar 19, 2024 6:54 am
Has thanked: 2 times

Re: ESP8266 v1.50 - SETTIME error

Post by ChipBurner »

Hello, Electroguard!
Thank you for your comment and participation in the problem that I encountered when writing code for using the timekeeper ds1302. As you know, almost all timekeeper chips use bcd code to count time and cannot switch to and from summer time. Therefore,
it would be logical to use them to track time in the UTC time zone, without offset and summer time, but when displayed on the display and further used in the program, convert the time from UTC to the local time zone taking into account summer time. But with the functions implemented in the language, this is very difficult to do. As a result, the code that works in one location will not work in another. The language has the ability to synchronize time using the ntp protocol, and therefore the UTC->TZ+DST conversion is already implemented and works, but is not available to the user. Therefore, I propose to extend the language to be able to perform binary(utc) <-> bcd(tz+dst) and binary(utc) <-> bcd(utc) conversions.
User avatar
PeterN
Posts: 641
Joined: Mon Feb 08, 2021 7:56 pm
Location: Krefeld, Germany
Has thanked: 296 times
Been thanked: 357 times
Contact:

Re: ESP8266 v1.50 - SETTIME error

Post by PeterN »

Hello ChipBurner

Firstly, I have to admit that I haven't really dealt with the problem you describe, as I only use two constantly running "old" ESP8266s and otherwise use the ESP32. I remember that CiccioCb did not want to invest time in new versions for the ESP8266.

One of my "old" ones is a clock that switches its LED matrix between time and temperature display.
This has been running for several years now, uses NTP time and switches automatically and correctly between winter and summer time.
Could this be a question of being creative with the config settings and avoiding the use of settime if the time has already been set by the DST rules at startup? Could this be a workaround?
Shoudn’t Settime only be necessary if you want to use a different time source, or am I wrong?
I'm sorry if I misinterpreted something because I read the thread too superficially.

Have a happy new year!
User avatar
Electroguard
Posts: 1094
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 373 times
Been thanked: 392 times

Re: ESP8266 v1.50 - SETTIME error

Post by Electroguard »

Hi ChipBurner, I originally used RTC.date$ and RTV,times with the script, causing it to do all date/time calculations relative to the RTC clock, which could get complicated.
But then I had an epiphany, and decided it was only necessary to refer to the rtc at startup in order to set the local esp time/date, so then all subsequent date/time calculations could be done using the local esp clock.

Later I decided it was unnecessary to use an rtc module on all devices except for one, which I would use as a dedicated little esp timeserver from which all other devices would sync their local esp date/time from when they start up, and also re-sync their time when any of the other devices start up.

The great advantage of having the single time server was that whenever it supplied its date/time to all other listening devices it could automatically include any required offset for drift or summertime changes.

A short simple bit of code allows the timeserver (or any device) to check if it has its own local rtc clock or not.

Code: [Local Link Removed for Guests]

i2c.setup 8,9
pause 10
rtc=0: i2c.begin 104
if i2c.end=0 then rtc=1
All non rtc devices send a utp timesync request at startup to the timeserver which sends back its current date and time, complete with any offsets or adjustments.

Code: [Local Link Removed for Guests]

send "TimeServer TimeSync"              'request an EasyNet TimerServer to respond by syncing out its time
The TimeServer has onscreen buttons for things like syncing to internet time, sending its timesync to all devices, setting its rtc clock from esp time, or setting esp time from the rtc time ... so it allows easily keeping on top of the time situation for all devices.
TimeServer.jpg

Code: [Local Link Removed for Guests]

AddTimeOffset:
t$ = time$
d$ = date$
day = val(word$(d$,1,"/"))
month = val(word$(d$,2,"/"))
year = val(word$(d$,3,"/"))
hour = val(word$(t$,1,":"))
min = val(word$(t$,2,":"))
sec = val(word$(t$,3,":"))
'wlog str$(day)+"-"+str$(month)+"-"+str$(year)+" "+str$(hour)+"."+str$(min)+"."+str$(sec)
min=min+8
if min>59 then min=min-60: hour=hour+1
SETTIME year, month, day, hour, min, sec
return

SyncTime:
send "All TimeSync " + word$(date$,3,"/")+","+word$(date$,2,"/")+","+word$(date$,1,"/")+","+word$(time$,1,":")+","+word$(time$,2,":")+","+word$(time$,3,":")
return

TimeSyncSent:
data$="x"
TimeSync:
if data$="" then
 if timeserver=1 then wlog "timesync request from: " + udp.remote$: gosub SyncTime
elseif data$="x" then
 data$=""
 return
else
 year=val(word$(data$,1,","))
 month=val(word$(data$,2,","))
 day=val(word$(data$,3,","))
 hour=val(word$(data$,4,","))
 mins=val(word$(data$,5,","))
 secs=val(word$(data$,6,","))
 SetTime year,month,day,hour,mins,secs 
 if rtc=1 then rtc.SetTime year,month,day,hour,mins,secs
endif
data$=""
return

netsync:
'Snippet to sync the date of the module using the date coming from the browser
'the Output Page must be open before running the script (otherwise there will be no effects)
A$ = |{|
A$ = A$ + |const d = new Date();|
A$ = A$ + |const year = d.getFullYear() % 100;|
A$ = A$ + |const month = d.getMonth() + 1;| ' Months are zero-based, so add 1|
A$ = A$ + |const day = d.getDate();|
A$ = A$ + |const hours = d.getHours();|
A$ = A$ + |const minutes = d.getMinutes();|
A$ = A$ + |const seconds = d.getSeconds();|
A$ = A$ + |const Settime = `SETTIME ${year},${month},${day},${hours},${minutes},${seconds}`;|
A$ = A$ + |connection.send("cmd:immediate" + Settime);|
A$ = A$ + |}|
jscall a$
return

rtc2esp:
'Used to set ESP internal timekeeper from RTC module time  
t$ = rtc.time$
d$ = rtc.date$
'wlog "rtc = " + t$ + "   " + d$
day = val(word$(d$,1,"/"))
month = val(word$(d$,2,"/"))
year = val(word$(d$,3,"/"))
hour = val(word$(t$,1,":"))
min = val(word$(t$,2,":"))
sec = val(word$(t$,3,":"))
'wlog str$(day)+"-"+str$(month)+"-"+str$(year)+" "+str$(hour)+"."+str$(min)+"."+str$(sec)
SETTIME year, month, day, hour, min, sec
refresh
return

esp2rtc:  
'Used to set RTC module time from ESP internal timekeeper  
t$ = time$
d$ = date$
rtctime$=t$
'wlog "esp = " + t$ + "   " + d$
day = val(word$(d$,1,"/"))
month = val(word$(d$,2,"/"))
year = val(word$(d$,3,"/"))
hour = val(word$(t$,1,":"))
min = val(word$(t$,2,":"))
sec = val(word$(t$,3,":"))
'wlog str$(day)+"-"+str$(month)+"-"+str$(year)+" "+str$(hour)+"."+str$(min)+"."+str$(sec)
RTC.SETTIME year, month, day, hour, min, sec
refresh
return
I'm not suggesting you need a timeserver, but I am suggesting that you may be able to use some of these capabilities to resolve your own issues.
You do not have the required permissions to view the files attached to this post.
Post Reply