-
Notifications
You must be signed in to change notification settings - Fork 3
/
NTP.h
184 lines (158 loc) · 5.45 KB
/
NTP.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
**
** NTP
**
*/
#ifndef NTP_H
#define NTP_H
static const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
WiFiUDP UDPNTPClient; // NTP Client
struct strDateTime{
byte hour;
byte minute;
byte second;
int year;
byte month;
byte day;
byte wday;
unsigned long NTPtime;
} ;
strDateTime DateTime; // Global DateTime structure, will be refreshed every Second
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[ NTP_PACKET_SIZE];
strDateTime ConvertUnixTimeStamp( unsigned long _tempTimeStamp) {
strDateTime _tempDateTime;
uint8_t year;
uint8_t month, monthLength;
uint32_t time;
unsigned long days;
time = (uint32_t)_tempTimeStamp;
_tempDateTime.second = time % 60;
time /= 60; // now it is minutes
_tempDateTime.minute = time % 60;
time /= 60; // now it is hours
_tempDateTime.hour = time % 24;
time /= 24; // now it is days
_tempDateTime.wday = ((time + 4) % 7) + 1; // Sunday is day 1
year = 0;
days = 0;
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
year++;
}
_tempDateTime.year = year; // year is offset from 1970
days -= LEAP_YEAR(year) ? 366 : 365;
time -= days; // now it is days in this year, starting at 0
days = 0;
month = 0;
monthLength = 0;
for (month = 0; month < 12; month++) {
if (month == 1) { // february
if (LEAP_YEAR(year)) {
monthLength = 29;
} else {
monthLength = 28;
}
} else {
monthLength = monthDays[month];
}
if (time >= monthLength) {
time -= monthLength;
} else {
break;
}
}
_tempDateTime.month = month + 1; // jan is month 1
_tempDateTime.day = time + 1; // day of month
_tempDateTime.year += 1970;
return _tempDateTime;
}
//
// Summertime calculates the daylight saving time for middle Europe. Input: Unixtime in UTC
//
boolean summerTime(unsigned long _timeStamp ) {
strDateTime _tempDateTime = ConvertUnixTimeStamp(_timeStamp);
// printTime("Innerhalb ", _tempDateTime);
if (_tempDateTime.month < 3 || _tempDateTime.month > 10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
if (_tempDateTime.month > 3 && _tempDateTime.month < 10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
if ((_tempDateTime.month == 3 && (_tempDateTime.hour + 24 * _tempDateTime.day) >= (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 4) % 7)) )||( _tempDateTime.month == 10 && (_tempDateTime.hour + 24 * _tempDateTime.day) < (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 1) % 7))))
return true;
else
return false;
}
unsigned long adjustTimeZone(unsigned long _timeStamp, int _timeZone, bool _isDayLightSavingSaving) {
_timeStamp += _timeZone * 360; // adjust timezone
// printTime("Innerhalb adjustTimeZone ", ConvertUnixTimeStamp(_timeStamp));
if (_isDayLightSavingSaving && summerTime(_timeStamp)) _timeStamp += 3600; // Sommerzeit beachten
return _timeStamp;
}
boolean getNTPtime(){
unsigned long _unixTime = 0;
if (WiFi.status() == WL_CONNECTED)
{
UDPNTPClient.begin(2390); // Port for NTP receive
IPAddress timeServerIP;
WiFi.hostByName(config.ntpServerName, timeServerIP);
ECHO_MSG("[NTP] NTP server:%s\n",timeServerIP.toString().c_str());
//ECHO_MSG("sending NTP packet...");
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
UDPNTPClient.beginPacket(timeServerIP, 123);
UDPNTPClient.write(packetBuffer, NTP_PACKET_SIZE);
UDPNTPClient.endPacket();
delay(100);
int cb = UDPNTPClient.parsePacket();
if (cb == 0) {
ECHO_MSG("[NTP] No NTP packet yet\n");
return false;
}
else
{
ECHO_MSG("[NTP] NTP packet received, length=%d\n",cb);
UDPNTPClient.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL;
_unixTime = secsSince1900 - seventyYears;
}
}
else {
ECHO_MSG("[NTP] Internet not yet connected");
delay(500);
return false;
}
yield();
if (_unixTime > 0){
UnixTimestamp = _unixTime; // store universally available time stamp
absoluteActualTime = adjustTimeZone(UnixTimestamp, config.timeZone, config.isDayLightSaving);
DateTime = ConvertUnixTimeStamp(absoluteActualTime); // convert to DateTime format
actualTime = 3600 * DateTime.hour + 60 * DateTime.minute + DateTime.second;
return true;
}
else
return false;
}
void ISRsecondTick(){
AdminTimeOutCounter++;
cNTP_Update++;
UnixTimestamp++;
absoluteActualTime = adjustTimeZone(UnixTimestamp, config.timeZone, config.isDayLightSaving);
DateTime = ConvertUnixTimeStamp(absoluteActualTime); // convert to DateTime format
actualTime = 3600 * DateTime.hour + 60 * DateTime.minute + DateTime.second;
/*
if (millis() - customWatchdog > 30000){
ECHO_MSG("CustomWatchdog bites. Bye");
//ESP.reset();
ESP.restart();
}
*/
}
#endif