ropg / ezTime

ezTime — pronounced "Easy Time" — is a very easy to use Arduino time and date library that provides NTP network time lookups, extensive timezone support, formatted time and date strings, user events, millisecond precision and more.
MIT License
336 stars 93 forks source link

How to tell if NTP has been successfully update after manually setting time with setTime #143

Open mattygsa opened 2 years ago

mattygsa commented 2 years ago

Since ezt::timeStatus() == timeset even if only due to being set manually, I was hoping there was just as easy way to find out if time was set by NTP only after having set the time manually with setTime say after a reboot with no internet where a manual time entry is required and then subsequently the internet becomes available again. How can I tell (in code without monitoring serial) that the NTP time is available again?

I'm sure I'm missing something obvious here!!

AussieMakerGeek commented 2 years ago

I have come across this too and was hoping for an event that might be fired off when the time is synced with NTP successfully.

I have a project that requires very accurate time but may be offline. It is using an RTC as it's time source but synced/Set with ezTime. If the device boots with no internet, it relies on the battery backed RTC only, then theoretically, once the device has internet it will update the RTC. I was using the RTC time to set ezTime on boot but confused that when I called a function containing waitForSync() to update the time on the RTC after internet was connected, it did not update.

i.e

DateTime now = rtc.now();
UTC.setTime(now.unixtime());

if (waitForSync(10)){  //Get the time from the internet..
  rtc.adjust(DateTime(UTC.now())); //Set the time on the RTC
}

UTC.now() will actually be the rtc time and not the internet time, regardless of internet connectivity.

waitForSync() does not seem to actually check internet time if timeStatus() == timeSet (which seems to be the case if you have called setTime() less than 1hr ago.

Because my project will behave differently between RTC time and ezTime, i need to know when ezTime has synced with NTP rather than the RTC.

Author seems to be MIA this year...

Edit: This is confirmed by the source - Line 537 of ezTime.cpp...

if (_time_status != timeSet) {
                infoln(F("Waiting for time sync"));
                while (_time_status != timeSet) {
                    if ( timeout && (millis() - start) / 1000 > timeout ) { triggerError(TIMEOUT); return false;};
                    delay(250);
                    events();
                }
                infoln(F("Time is in sync"));
            }

So because the time is set, regardless of the source, it's not actually checking internet time...

AussieMakerGeek commented 2 years ago

I managed to work around this issue by reviewing the source code of the library

If you call updateNTP() directly, rather than using waitForSync() (Which calls uptateNTP() but only if time_status !=timeSet) the time_status should now be either timeNeedsSync or timeSet, purely based on NTP success/fail.

Unfortunately, updateNTP() does not return a variable itself.

I ended up with:

void syncTimeToRTC(){
  //Force the ezTime library to try internet time
  updateNTP();
  // time_status should now be either timeNeedsSync or timeSet 
  if (timeStatus() == timeSet){
    rtc.adjust(DateTime(UTC.now())); //Set the time on the RTC
    rtcInUse = 0;
  }else{
    // Relying on RTC time
    DateTime now = rtc.now();
    UTC.setTime(now.unixtime());  //Set EZTime to whatever the RTC is.
    rtcInUse = 1;
    lastFailure = millis();   
  }
}

By setting an if statement such as: if (millis() - lastFailure > 60000 && rtcInUse == 1) syncTimeToRTC(); I can make sure it's always in sync.

I also run it if network gets disconnected/reconnected.