AceTime  0.1
Date and time classes for Arduino that supports the TZ DAtabase, and a system clock synchronized from an NTP server or an RTC chip.
SystemTimeKeeper.h
1 #ifndef ACE_TIME_SYSTEM_TIME_KEEPER_H
2 #define ACE_TIME_SYSTEM_TIME_KEEPER_H
3 
4 #include <Arduino.h> // millis()
5 #include <stdint.h>
6 #include "../common/TimingStats.h"
7 #include "../common/logger.h"
8 #include "TimeKeeper.h"
9 
10 namespace ace_time {
11 namespace provider {
12 
46  public:
47 
55  explicit SystemTimeKeeper(
56  TimeProvider* syncTimeProvider /* nullable */,
57  TimeKeeper* backupTimeKeeper /* nullable */):
58  mSyncTimeProvider(syncTimeProvider),
59  mBackupTimeKeeper(backupTimeKeeper) {}
60 
61  void setup() {
62  if (mBackupTimeKeeper != nullptr) {
63  setNow(mBackupTimeKeeper->getNow());
64  }
65  }
66 
67  acetime_t getNow() const override {
68  if (!mIsInit) return kInvalidSeconds;
69 
70  while ((uint16_t) ((uint16_t) millis() - mPrevMillis) >= 1000) {
71  mPrevMillis += 1000;
72  mEpochSeconds += 1;
73  }
74  return mEpochSeconds;
75  }
76 
77  void setNow(acetime_t epochSeconds) override {
78  if (epochSeconds == kInvalidSeconds) return;
79 
80  mEpochSeconds = epochSeconds;
81  mPrevMillis = millis();
82  mIsInit = true;
83  backupNow(epochSeconds);
84  }
85 
96  void sync(acetime_t epochSeconds) {
97  if (epochSeconds == kInvalidSeconds) return;
98  if (mEpochSeconds == epochSeconds) return;
99 
100  mEpochSeconds = epochSeconds;
101  mPrevMillis = millis();
102  mIsInit = true;
103  mLastSyncTime = epochSeconds;
104 
105  if (mBackupTimeKeeper != mSyncTimeProvider) {
106  backupNow(epochSeconds);
107  }
108  }
109 
114  acetime_t getLastSyncTime() const {
115  return mLastSyncTime;
116  }
117 
119  bool isInit() const { return mIsInit; }
120 
121  protected:
123  virtual unsigned long millis() const { return ::millis(); }
124 
125  private:
126  friend class SystemTimeSyncCoroutine;
127  friend class SystemTimeSyncLoop;
128 
134  void backupNow(acetime_t nowSeconds) {
135  if (mBackupTimeKeeper != nullptr) {
136  mBackupTimeKeeper->setNow(nowSeconds);
137  }
138  }
139 
140  const TimeProvider* const mSyncTimeProvider;
141  TimeKeeper* const mBackupTimeKeeper;
142 
143  mutable acetime_t mEpochSeconds = 0; // time presented to the user
144  mutable uint16_t mPrevMillis = 0; // lower 16-bits of millis()
145  bool mIsInit = false; // true if setNow() or sync() was successful
146  acetime_t mLastSyncTime = 0; // time when last synced
147 };
148 
149 }
150 }
151 
152 #endif
SystemTimeKeeper(TimeProvider *syncTimeProvider, TimeKeeper *backupTimeKeeper)
virtual unsigned long millis() const
Return the Arduino millis().
bool isInit() const
Return true if initialized by setNow() or sync().
A TimeProvider whose time can be set by the end-user.
Definition: TimeKeeper.h:14
void sync(acetime_t epochSeconds)
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from ...
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
void setNow(acetime_t epochSeconds) override
Set the time to the indicated seconds.
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user...
acetime_t getLastSyncTime() const
Return the time (seconds since Epoch) of the last valid sync() call.
A class that periodically that syncs the SystemTimeKeeper with its syncTimeProvider.
Base class for objects that provide a source of time whose time cannot be changed by the end-user...
Definition: TimeProvider.h:14
virtual void setNow(acetime_t epochSeconds)=0
Set the time to the indicated seconds.
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
A coroutine that syncs the SystemTimeKeeper with its syncTimeProvider.