DS_CAP_SYS_TIME - denis-stepanov/esp-ds-system GitHub Wiki

DS_CAP_SYS_TIME — System Time

Description

This capability adds support for system time. The following fields are implemented:

Field Description Default Value
time_t System::time Current time (Unix) 0
struct tm System::tm_time Current time as structure (structure equivalent to 1970-01-01T00:00:00Z)
void (*System::onTimeSync)() Hook to be called when time gets synchronized nullptr

Fields time and time_tm are kept up to date with system time. time_tm takes time zone into account (see below).

The callback onTimeSync() will be called on a time synchronization event. Use it if you need to react on this somehow:

void myTimeSyncHook() {
  ...
}
void (*System::onTimeSync)() = myTimeSyncHook;

The following methods to work with time are available:

time_t System::getTimeSyncTime();                // Return last time sync time
void System::setTimeSyncTime(const time_t new_time); // Set last time sync time
time_sync_t System::getTimeSyncStatus();         // Return time sync status
void System::setTimeSyncStatus(const time_sync_t new_status); // Set time sync status
time_t System::getTime();                        // Return current time
void System::setTime(const time_t new_time);     // Set current time
String System::getTimeStr();                     // Return current time string
String System::getTimeStr(const time_t t);       // Return time string for a given time
bool System::newSecond();                        // Return true if new second has arrived
bool System::newMinute();                        // Return true if new minute has arrived
bool System::newHour();                          // Return true if new hour has arrived
bool System::newDay();                           // Return true if new day has arrived
bool System::newWeek();                          // Return true if new week has arrived
bool System::newMonth();                         // Return true if new month has arrived
bool System::newYear();                          // Return true if new year has arrived

getTime() will return a current time in Unix time_t format (seconds since epoch 1970-01-01T00:00:00Z). This call yields the same result as if just reading the System::time field. getTimeStr() will return the time string, in a format of YYYY/MM/DD hh:mm:ss. If time is not synchronized, a string ----/--/-- --:--:-- will be returned. You can pass a time parameter t to get a time string for a time different from the current. setTime() will set system time to a new value.

getTimeSyncTime() will return the time of a last sync, or 0, if sync has not yet happened. getTimeSyncStatus() will return current status of time synchronization, which can be one of three: TIME_SYNC_NONE (never synchronized), TIME_SYNC_OK (currently synchronized) or TIME_SYNC_DEGRADED (synchronization lost). "Degraded" condition is declared if synchronization delay exceeds two regular synchronization periods (once per hour each). setTime(), apart from setting system time, will update time synchronization time to the current and set its status to TIME_SYNC_OK. Functions setTimeSyncTime(), setTimeSyncStatus() can be used to manipulate these parameters in other time synchronization scenarios.

Currently, the only method of time synchronization supported out of the box is NTP (see network for more details). You can implement your own synchronization methods by calling setTime() whenever needed.

Methods newSecond(), newMinute(), newHour(), newDay(), newWeek(), newMonth() and newYear() will return true once a corresponding time slice is reached. These functions are convenient to organize simple timers, as follows:

if (System::newSecond()) {
    // Do something ...
}

The flags returned are transient (only last for one cycle of loop() function per event). This means that in order for these functions to work reliably, they have to be called from sketch's loop() function (or from functions called from it) unconditionally. New week is counted starting from Monday. Absolute timers bound to a given time kick in with System::update() call following the loop() iteration where newSecond() is active.

When using time, you need to define time zone DS_TIMEZONE in MySystem.h, e.g.:

#define DS_TIMEZONE TZ_Europe_Paris

Refer to the list of available zones in the file TZ.h in the ESP8266 Arduino Core. If no time zone is set, the library will issue a compilation warning and default to UTC.

Requires

Cooperates With

  • DS_CAP_APP_LOG — if application log is enabled, log entries will be timestamped. Also, application startup timestamp will be logged on a first time synchronization event (in the case of NTP, this usually happens 1-2 seconds after system boot);
  • DS_CAP_SYS_LOG — if syslog is enabled, time synchronization event will be sent to it;
  • DS_CAP_SYS_UPTIME — if uptime support is enabled, an additional function getBootTimeStr() will become available, returning boot time string. Boot time will be equally reported on web server "System Information" page, if enabled;
  • DS_CAP_SYS_NETWORK — if network is enabled, time will sync automatically from NTP. Also, additional means will be made available to set or query the NTP server name;
  • DS_CAP_WEBSERVER — if web server is enabled, its "System Information" page will include information about current time, status of time synchronization, as well as information on a time server used.

Conflicts With

None.

Usage

MySystem.h:

#define DS_CAP_SYS_TIME     // Enable system time
#define DS_CAP_SYS_LOG_HW   // Enable syslog on hardware serial line

#define DS_TIMEZONE TZ_Europe_Paris  // Timezone

#include "System.h"         // System global definitions

sketch.ino:

#include "MySystem.h"

using namespace ds;

void printTime() {
  System::log->printf("Current time (seconds since epoch): %lu\n", System::time);
  System::log->print("Current time (string): ");
  System::log->println(System::getTimeStr());
  System::log->print("Time sync status: ");
  switch (System::getTimeSyncStatus()) {
    case TIME_SYNC_NONE:     System::log->println("not synchronized"); break;
    case TIME_SYNC_OK:       System::log->println("synchronized"); break;
    case TIME_SYNC_DEGRADED: System::log->println("degraded"); break;
    default:                 System::log->println("unknown");
  }
}

void setup() {
  System::begin();

  // On boot, time is set to the beginning of epoch
  printTime();

  // Set system time from an external source (e.g., RTC clock), causing it to become synchronized
  const time_t new_time = 1000000000;                 // Some date around 2001
  System::log->print("Time will be set to: ");
  System::log->println(System::getTimeStr(new_time)); // Illustrates getTimeStr() with a parameter
  System::setTime(new_time);
  delay(100);                                         // Allow new time to propagate
  printTime();
}

void loop() {
  System::update();
}

Mandatory Calls

System::begin() Required
System::update() Required (since version 1.1)

Examples

Bugs

  • It appears that setTime() needs additional time to propagate new time, circa 100 ms. It is recommended not to rely on system clock shortly after a time change has been implemented.

Availability

Version 1.0 or later. Functions setTime(), setTimeSyncTime(), setTimeSyncStatus(), newSecond(), newMinute(), newHour(), newDay(), newWeek(), newMonth() and newYear(), as well as the fields time, tm_time are available since version 1.1.

See Also

None.

⚠️ **GitHub.com Fallback** ⚠️