OmEspHelpers
OmNtp.h
1 /*
2  * OmNtp.h
3  * 2016-12-13
4  *
5  * This class implements a background time service.
6  *
7  * HOW DOES IT WORK
8  *
9  * It is not very accurate. Every couple of minutes it queries a well-known
10  * time server (time.nist.gov), and adds on-board millis() when you ask
11  * for the time. It gives you the time in Hours, Minutes, and Seconds.
12  *
13  * If Wifi is not available, the time is "unknown" or (-1,-1,-1).
14  *
15  * EXAMPLE
16  *
17  * OmNtp ntp;
18  *
19  * in setup():
20  *
21  * ntp.setTimeZone(-8); // for California in the winter
22  *
23  * when wifi is established:
24  *
25  * ntp.setWifiAvailable(true);
26  *
27  * in loop():
28  *
29  * ntp.tick();
30  *
31  * when you want the time:
32  *
33  * int hour, minute, second;
34  * bool gotTheTime = ntp.getTime(hour, minute, second);
35  * const char *string = ntp.getTimeString(); // HH:MM:SS or "unknown"
36  *
37  * Adapted from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino
38  */
39 
40 #ifndef __OmNtp__
41 #define __OmNtp__
42 
43 #include "OmLog.h"
44 
45 // for testing, the utilities can be built on mac. But the main class is Arduino only.
47 {
48 public:
49  bool acquired = false;
50  unsigned long acquiredMs = 0; // when it was acquired
51  unsigned long reportedSeconds = 0; // seconds since 1970 or seconds since midnight.
52 
53  // constructors
54  OmNtpSyncRecord(){};
55  OmNtpSyncRecord(unsigned long nowMs, int hour, int minute, int second);
56 
57  // seconds within day
58  float getSwd(unsigned long nowMs, int zone = 0);
59 
60  // get the raw seconds, only sensible for a UTC time. no zone.
61  double getU(unsigned long nowMs);
62 };
63 
64 float omGetSecondsWithinDay(unsigned long nowMs, OmNtpSyncRecord &utcTime, OmNtpSyncRecord &localTime, int zone);
65 bool omGetHms(float secondsWithinDay, int &hourOut, int &minuteOut, float &secondOut);
66 bool omGetHms(float secondsWithinDay, int &hourOut, int &minuteOut, int &secondOut);
67 
68 #ifndef NOT_ARDUINO
69 #include "WiFiUdp.h"
70 #include "OmUdp.h"
71 
73 class OmNtp
74 {
75 public:
76  OmNtp();
77 
79  void setWifiAvailable(bool wifiAvailable);
80 
82  void tick(unsigned int deltaMillis); // millis since last tick, mediated by the owner.
83 
86  void setTimeZone(int hourOffset);
87 
88 
89  int getTimeZone();
90 
92  void getLocalTime();
93 
94  /*
95  <?
96  print date("Y-m-d H:i:s");
97  print " + ";
98  print date("e");
99  ?>
100  */
104  void setTimeUrl(const char *timeUrl);
105 
109  void setTimeUrlOffset(int hoursFromTimeUrl);
110 
112  bool getTime(int &hourOut, int &minuteOut, int &secondOut);
114  bool getTime(int &hourOut, int &minuteOut, float &secondOut);
115 
118  const char *getTimeString();
119 
120  bool getUTime(uint32_t &uTimeOut, int &uFracOut); // seconds of 1970-1-1, and milliseconds.
121  uint32_t getUTime(); // lite version
122 
124  static OmNtp *ntp();
125 
127  {
128  public:
129  const char *ntpServerName = "";
130  IPAddress ntpServerIp;
131  const char *timeUrl = NULL;
132  unsigned int ntpRequestsSent = 0;
133  unsigned int ntpRequestsAnswered = 0;
134  long ntpRequestMostRecentMillis = -1;
135  unsigned int timeUrlRequestsSent = 0;
136  unsigned int timeUrlRequestsAnswered = 0;
137  long timeUrlRequestMostRecentMillis = 0;
138  };
139 
140  OmNtpStats stats;
141 
143  static void sGetTimeOfDay(int &minuteWithinDayOut, float &secondWithinMinuteOut);
144 
145 private:
146  // Internal implementation methods and details.
147  void begin();
148  void checkForPacket();
149 
150  static const unsigned int kLocalPort = 2390; // local port to listen for UDP packets
151  OmUdp udp = OmUdp(kLocalPort);
152 // WiFiUDP udp; // the connection
153  int timeZone; // offset the hour reported by this much.
154  bool wifiAvailable;
155  const char *timeUrl = 0;
156  int timeUrlOffset = 0;
157 
158  OmNtpSyncRecord ntpTime;
159  OmNtpSyncRecord localTime;
160 
161  bool begun = false;
162  static const int kNtpPacketSize = 48;
163  byte packetBuffer[kNtpPacketSize]; //buffer to hold incoming and outgoing packets
164  IPAddress ntpServerIp; // resolved IP address (time.nist.gov)
165 
166  bool ntpRequestSent = 0; // is set "true" after sending ntp request, and cleared when we get answer.
167 
168  int localTimeRefetchCountdown = 0; // now and then, reget local time.
169  long countdownMilliseconds = -1;
170 
171  static OmNtp *lastNtpBegun; // handy global of if instance exists.
172 public:
174  WiFiClient client; // shared, for sending requests
175 };
176 #endif //NOT_ARDUINO
177 
178 #endif // __OmNtp__
OmNtp::tick
void tick(unsigned int deltaMillis)
Definition: OmNtp.cpp:361
OmNtp::ntp
static OmNtp * ntp()
Definition: OmNtp.cpp:424
OmNtpSyncRecord
Definition: OmNtp.h:47
OmNtp::getLocalTime
void getLocalTime()
Definition: OmNtp.cpp:183
OmNtp::client
WiFiClient client
Definition: OmNtp.h:174
OmNtp::setWifiAvailable
void setWifiAvailable(bool wifiAvailable)
Definition: OmNtp.cpp:162
OmNtp::OmNtpStats
Definition: OmNtp.h:127
OmNtp::getTimeString
const char * getTimeString()
Definition: OmNtp.cpp:280
OmUdp
Definition: OmUdp.h:15
OmNtp
Definition: OmNtp.h:74
OmNtp::setTimeZone
void setTimeZone(int hourOffset)
Definition: OmNtp.cpp:173
OmNtp::setTimeUrl
void setTimeUrl(const char *timeUrl)
Definition: OmNtp.cpp:429
OmNtp::setTimeUrlOffset
void setTimeUrlOffset(int hoursFromTimeUrl)
Definition: OmNtp.cpp:437
OmNtp::getTime
bool getTime(int &hourOut, int &minuteOut, int &secondOut)
Definition: OmNtp.cpp:273
OmNtp::sGetTimeOfDay
static void sGetTimeOfDay(int &minuteWithinDayOut, float &secondWithinMinuteOut)
Static methods to get the time, and return -1's if time does not exist in space.
Definition: OmNtp.cpp:443