Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTC timezone issue - Should the EVSE's clock be in UTC? #916

Open
kimble4 opened this issue Sep 30, 2024 · 2 comments
Open

RTC timezone issue - Should the EVSE's clock be in UTC? #916

kimble4 opened this issue Sep 30, 2024 · 2 comments

Comments

@kimble4
Copy link
Contributor

kimble4 commented Sep 30, 2024

For clarity: I have the new TFT WiFi/Display module. This has no RTC.

As I sometimes want to use my OpenEVSE for portable charging where NTP isn't necessarily available, and since the code's already in there, I added a DS3231 module to the OpenEVSE's i2c bus. This appears to Just Work: The WiFi module gets the time via NTP and sets the OpenEVSE's time, which also sets the RTC. On power-up without WiFi available, the OpenEVSE gets the time from the RTC as expected, and the WiFi module sets its clock to the OpenEVSE. The DS3231's temperature also appears in the sensors list, as expected.

Except the WiFi module's time is now an hour ahead of what it should be (I'm in the Europe/London timezone, which is currently 1 hour ahead of UTC).

It looks like the problem arises from confusion over whether the EVSE's clock is in local time or UTC.

In time_man.cpp we have:

OpenEVSE.setTime(utc_time.tv_sec, [this](int ret) This passes UTC time as a time_t...

And then in openevse.cpp we have:

void OpenEVSEClass::setTime(time_t time, std::function<void(int ret)> callback)
{
  // S1 yr mo day hr min sec - set clock (RTC) yr=2-digit year

  struct tm tm;
  localtime_r(&time, &tm);

  setTime(tm, callback);
}

localtime_r converts the UTC time_t to local time. SetTime then passes it to the EVSE.

Meanwhle, in input.cpp we have:

  OpenEVSE.getTime([](int ret, time_t evse_time)
  {
    if(RAPI_RESPONSE_OK == ret)
    {
      time_t local_time = time(NULL);
      if(evse_time > local_time) {
        struct timeval set_time = { evse_time, 0 };
        settimeofday(&set_time, NULL);
      }
    }
  });

Which takes the time from the EVSE and sets the WiFi module's UTC clock to that.

So, either the EVSE's clock is supposed to be in local time, and this needs accounting for in input.cpp, or it's supposed to be in UTC time and openevse.cpp should be using gmtime_r() instead?

@jeremypoulter
Copy link
Collaborator

Hi, thanks for the report. The Open EVSE time used to be set as local when the timers and LCD were managed on the OpenEVSE. There may still be a small value in the OpenEVSE time being local in which case, we need to convert the local time to UTC before setting the WiFi clock, but the reality is it largely doesn't matter anyway more so it may be easiest to set to UTC.

@kimble4
Copy link
Contributor Author

kimble4 commented Oct 1, 2024

Setting the EVSE to UTC is certainly easier, and having tried it, it appears to work fine on my setup. Timers and history seem to have the right times, anyway.

Of course, if that might break things for older hardware, we need a way to determine the timezone offset to subtract it before calling settimeofday(). I don't think that's easy on an ESP32...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants