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.
SystemTimeSyncLoop.h
1 #ifndef ACE_TIME_SYSTEM_TIME_SYNC_LOOP_H
2 #define ACE_TIME_SYSTEM_TIME_SYNC_LOOP_H
3 
4 #include <stdint.h>
5 #include "SystemTimeKeeper.h"
6 
7 namespace ace_time {
8 namespace provider {
9 
15  public:
28  uint16_t syncPeriodSeconds = 3600,
29  uint16_t initialSyncPeriodSeconds = 5,
30  uint16_t requestTimeoutMillis = 1000):
31  mSystemTimeKeeper(systemTimeKeeper),
32  mSyncPeriodSeconds(syncPeriodSeconds),
33  mInitialSyncPeriodSeconds(initialSyncPeriodSeconds),
34  mRequestTimeoutMillis(requestTimeoutMillis),
35  mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
36 
41  void loop() {
42  if (mSystemTimeKeeper.mSyncTimeProvider == nullptr) return;
43 
44  unsigned long nowMillis = millis();
45  unsigned long timeSinceLastSync = nowMillis - mLastSyncMillis;
46 
47  if (timeSinceLastSync >= mCurrentSyncPeriodSeconds * 1000UL
48  || mSystemTimeKeeper.getNow() == 0) {
49  acetime_t nowSeconds = mSystemTimeKeeper.mSyncTimeProvider->getNow();
50 
51  if (nowSeconds == 0) {
52  // retry with exponential backoff
53  if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
54  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
55  } else {
56  mCurrentSyncPeriodSeconds *= 2;
57  }
58  } else {
59  mSystemTimeKeeper.sync(nowSeconds);
60  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
61  }
62 
63  mLastSyncMillis = nowMillis;
64  }
65  }
66 
71  uint16_t getSecondsSinceLastSync() const {
72  unsigned long elapsedMillis = millis() - mLastSyncMillis;
73  return elapsedMillis / 1000;
74  }
75 
76  private:
77  SystemTimeKeeper& mSystemTimeKeeper;
78  uint16_t const mSyncPeriodSeconds;
79  uint16_t const mInitialSyncPeriodSeconds;
80  uint16_t const mRequestTimeoutMillis;
81 
82  unsigned long mLastSyncMillis = 0; // should be the same type as millis()
83  uint16_t mCurrentSyncPeriodSeconds;
84 };
85 
86 }
87 }
88 
89 #endif
SystemTimeSyncLoop(SystemTimeKeeper &systemTimeKeeper, uint16_t syncPeriodSeconds=3600, uint16_t initialSyncPeriodSeconds=5, uint16_t requestTimeoutMillis=1000)
Constructor.
void sync(acetime_t epochSeconds)
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from ...
void loop()
If AceRoutine coroutine infrastructure is not used, then call this from the global loop() method...
uint16_t getSecondsSinceLastSync() const
Return the number of seconds since last sync.
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user...
A class that periodically that syncs the SystemTimeKeeper with its syncTimeProvider.
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).