93 lines
2.7 KiB
C++
93 lines
2.7 KiB
C++
#include "HermitCrab.h"
|
|
#include "TimeManager.h"
|
|
#include "ConnectWiFi.h"
|
|
#include <sys/time.h>
|
|
#include "Config.h"
|
|
#define TAG_TIME "Time"
|
|
TimeManager timeManager;
|
|
|
|
void TimeManager::begin() {
|
|
setenv("TZ", "UTC", 1); // Set time zone to Asia/Seoul (UTC+9)
|
|
tzset(); // Apply the timezone setting
|
|
|
|
// Initialize UDP only if WiFi is connected
|
|
if (isWiFiConnected() && !udpInitialized) {
|
|
udpInitialized = udp.begin(localPort);
|
|
}
|
|
// Send an initial NTP request on startup
|
|
sendNTPRequest();
|
|
lastNTPRequestMillis = millis();
|
|
}
|
|
|
|
void TimeManager::Stop() {
|
|
if (udpInitialized) {
|
|
udp.stop();
|
|
}
|
|
}
|
|
|
|
bool TimeManager::getTime(unsigned long tickMillis) {
|
|
// Check WiFi Connection
|
|
if (!isWiFiConnected()) {
|
|
//ESP_LOGI(TAG_TIME,"TimeManager - getTime called while not connected");
|
|
if (udpInitialized) udpInitialized = false;
|
|
return false;
|
|
}
|
|
|
|
// Check if 30 minutes have passed since last NTP request
|
|
if (udpInitialized &&
|
|
((tickMillis - lastNTPRequestMillis >= NTP_REQUEST_INTERVAL) ||
|
|
!bHasNTPTime && (tickMillis - lastNTPRequestMillis >= NTP_FAILED_INTERNAL))) {
|
|
sendNTPRequest();
|
|
lastNTPRequestMillis = tickMillis;
|
|
}
|
|
|
|
// Check if there is an NTP response, and if so, update the system clock
|
|
return checkNTPResponse();
|
|
}
|
|
|
|
MY_IRAM_ATTR void TimeManager::sendNTPRequest() {
|
|
byte ntpPacket[48] = {0};
|
|
ntpPacket[0] = 0b11100011; // LI, Version, Mode
|
|
ntpPacket[1] = 0; // Stratum, or type of clock
|
|
ntpPacket[2] = 6; // Polling Interval
|
|
ntpPacket[3] = 0xEC; // Peer Clock Precision
|
|
|
|
udp.beginPacket(ntpServer, 123); // NTP requests are sent to port 123
|
|
udp.write(ntpPacket, 48);
|
|
udp.endPacket();
|
|
}
|
|
|
|
MY_IRAM_ATTR bool TimeManager::checkNTPResponse() {
|
|
if (udp.parsePacket() == 0) {
|
|
// No response yet
|
|
return false;
|
|
}
|
|
|
|
byte ntpBuffer[48];
|
|
udp.read(ntpBuffer, 48);
|
|
|
|
// Extract and set the time if response is valid
|
|
unsigned long epochTime = (unsigned long)ntpBuffer[40] << 24 |
|
|
(unsigned long)ntpBuffer[41] << 16 |
|
|
(unsigned long)ntpBuffer[42] << 8 |
|
|
(unsigned long)ntpBuffer[43];
|
|
epochTime -= 2208988800UL; // Convert from NTP to Unix time
|
|
// epochTime += (9 * 3600); // GMT+9
|
|
if (!bHasNTPTime) {
|
|
bHasNTPTime = true;
|
|
firstNTPTime = epochTime;
|
|
config.m_nEpochTime = epochTime;
|
|
}
|
|
setSystemClock(epochTime);
|
|
// ESP_LOGI(TAG_TIME,printTime());
|
|
return true;
|
|
}
|
|
|
|
|
|
void TimeManager::setSystemClock(unsigned long epochTime) {
|
|
struct timeval now;
|
|
now.tv_sec = epochTime;
|
|
now.tv_usec = 0;
|
|
settimeofday(&now, NULL);
|
|
}
|