HCesp/TimeManager.cpp

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);
}