/* ; Project: Open Vehicle Monitor System ; Date: 14th March 2017 ; ; Changes: ; 1.0 Initial release ; ; (C) 2011 Michael Stegen / Stegen Electronics ; (C) 2011-2017 Mark Webb-Johnson ; (C) 2011 Sonny Chen @ EPRO/DX ; ; Permission is hereby granted, free of charge, to any person obtaining a copy ; of this software and associated documentation files (the "Software"), to deal ; in the Software without restriction, including without limitation the rights ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ; copies of the Software, and to permit persons to whom the Software is ; furnished to do so, subject to the following conditions: ; ; The above copyright notice and this permission notice shall be included in ; all copies or substantial portions of the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ; THE SOFTWARE. */ #include "ovms_log.h" static const char *TAG = "time"; #define STALETIMEOUT 120 static const char *ntp = "ntp"; #include #include #include #include "lwip/apps/sntp.h" #include "ovms.h" #include "ovms_time.h" #include "ovms_config.h" #include "ovms_command.h" #include "ovms_events.h" #include "ovms_netmanager.h" OvmsTime MyTime __attribute__ ((init_priority (1500))); void time_status(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv) { time_t rawtime; time ( &rawtime ); char tb[64]; char* tz = getenv("TZ"); writer->printf("Time Zone: %s\n", (tz!=NULL)?tz:"Not defined"); struct tm* tmu = gmtime(&rawtime); if (strftime(tb, sizeof(tb), "%Y-%m-%d %H:%M:%S UTC", tmu) > 0) writer->printf("UTC Time: %s\n", tb); tmu = localtime(&rawtime); if (strftime(tb, sizeof(tb), "%Y-%m-%d %H:%M:%S %Z", tmu) > 0) writer->printf("Local Time: %s\n", tb); writer->printf("Provider: %s\n",(MyTime.m_current)?MyTime.m_current->m_provider:"None"); if (! MyTime.m_providers.empty()) { writer->printf("\nPROVIDER STRATUM UPDATE TIME\n"); for (OvmsTimeProviderMap_t::iterator itc=MyTime.m_providers.begin(); itc!=MyTime.m_providers.end(); itc++) { OvmsTimeProvider* tp = itc->second; time_t tim = tp->m_time + (monotonictime-tp->m_lastreport); struct tm* tml = gmtime(&tim); writer->printf("%s%-20.20s%7d%8d %s", (tp==MyTime.m_current)?"*":" ", tp->m_provider, tp->m_stratum, monotonictime-tp->m_lastreport, asctime(tml)); } } } void time_set(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv) { struct tm tmu; if (strptime(argv[0], "%Y-%m-%d %H:%M:%S", &tmu) != NULL) { time_t tim = mktime(&tmu); MyTime.Set(TAG, 15, true, tim); writer->puts("Time set (at stratum 15)"); } } extern "C" { void sntp_setsystemtime_us(uint32_t s, uint32_t us) { MyTime.Set(ntp, 1, true, s, us); } } OvmsTimeProvider::OvmsTimeProvider(const char* provider, int stratum, time_t tim) { m_provider = provider; m_time = tim; m_lastreport = monotonictime; m_stratum = stratum; } OvmsTimeProvider::~OvmsTimeProvider() { } void OvmsTimeProvider::Set(int stratum, time_t tim) { m_stratum = stratum; m_time = tim; m_lastreport = monotonictime; } OvmsTime::OvmsTime() { ESP_LOGI(TAG, "Initialising TIME (1500)"); m_current = NULL; m_tz.tz_minuteswest = 0; m_tz.tz_dsttime = 0; // SNTP defaults sntp_setoperatingmode(SNTP_OPMODE_POLL); sntp_setservername(0, (char*)"pool.ntp.org"); // Register our commands OvmsCommand* cmd_time = MyCommandApp.RegisterCommand("time","TIME framework",time_status, "", 0, 0, false); cmd_time->RegisterCommand("status","Show time status",time_status,"", 0, 0, false); cmd_time->RegisterCommand("set","Set current UTC time",time_set,"