2022-08-18 14:49:11 +02:00
|
|
|
|
#include "NTP.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "Global.h"
|
2022-10-05 20:53:27 +03:00
|
|
|
|
#include "utils/SerialPrint.h"
|
2022-08-18 14:49:11 +02:00
|
|
|
|
|
|
|
|
|
|
void ntpInit() {
|
|
|
|
|
|
synchTime();
|
|
|
|
|
|
|
|
|
|
|
|
ts.add(
|
|
|
|
|
|
TIME, 1000, [&](void*) {
|
2022-08-24 00:59:44 +02:00
|
|
|
|
unixTime = getSystemTime();
|
2022-08-18 14:49:11 +02:00
|
|
|
|
if (unixTime < MIN_DATETIME) {
|
2022-08-24 00:59:44 +02:00
|
|
|
|
isTimeSynch = false;
|
2022-08-18 14:49:11 +02:00
|
|
|
|
// SerialPrint("E", "NTP", "Time not synched");
|
2022-10-12 03:14:55 +02:00
|
|
|
|
jsonWriteInt(errorsHeapJson, F("tme1"), 1);
|
2022-08-18 14:49:11 +02:00
|
|
|
|
synchTime();
|
2023-02-17 20:26:29 +03:00
|
|
|
|
|
|
|
|
|
|
// проверяем присутствие RTC с батарейкой и получаем время при наличии
|
|
|
|
|
|
if (rtcItem) {
|
|
|
|
|
|
unixTime = rtcItem->getRtcUnixTime();
|
|
|
|
|
|
} else return;
|
2022-08-18 14:49:11 +02:00
|
|
|
|
}
|
2023-02-17 20:26:29 +03:00
|
|
|
|
|
|
|
|
|
|
unixTimeShort = unixTime - START_DATETIME;
|
2022-10-12 03:14:55 +02:00
|
|
|
|
jsonWriteInt(errorsHeapJson, F("tme1"), 0);
|
2022-08-18 19:04:13 +02:00
|
|
|
|
breakEpochToTime(unixTime + jsonReadInt(settingsFlashJson, F("timezone")) * 60 * 60, _time_local);
|
2022-08-18 14:49:11 +02:00
|
|
|
|
breakEpochToTime(unixTime, _time_utc);
|
2022-08-24 00:59:44 +02:00
|
|
|
|
isTimeSynch = true;
|
2022-08-18 14:49:11 +02:00
|
|
|
|
String timenow = getTimeLocal_hhmm();
|
|
|
|
|
|
static String prevTime;
|
|
|
|
|
|
if (prevTime != timenow) {
|
|
|
|
|
|
prevTime = timenow;
|
2022-08-18 15:07:39 +02:00
|
|
|
|
String dateAndTime = getDateTimeDotFormated();
|
2022-08-18 15:19:07 +02:00
|
|
|
|
dateAndTime = deleteToMarkerLast(dateAndTime, ":");
|
2022-08-18 15:07:39 +02:00
|
|
|
|
jsonWriteStr_(errorsHeapJson, F("timenow"), dateAndTime);
|
|
|
|
|
|
SerialPrint("I", F("NTP"), "✔ " + dateAndTime);
|
2022-12-04 21:13:59 +01:00
|
|
|
|
onDayChange();
|
2022-08-18 14:49:11 +02:00
|
|
|
|
}
|
2022-08-24 00:59:44 +02:00
|
|
|
|
_time_isTrust = true; // доверяем значению времени
|
2022-08-18 14:49:11 +02:00
|
|
|
|
},
|
|
|
|
|
|
nullptr, true);
|
|
|
|
|
|
|
|
|
|
|
|
SerialPrint("I", F("NTP"), F("Handle time init"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void synchTime() {
|
2023-04-07 14:26:03 +03:00
|
|
|
|
configTime(0, 0, "pool.ntp.org", "ru.pool.ntp.org", jsonReadStr(settingsFlashJson, F("ntp")).c_str());
|
2022-08-18 14:49:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-04 21:13:59 +01:00
|
|
|
|
//событие смены даты
|
|
|
|
|
|
bool onDayChange() {
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
|
String currentDate = getTodayDateDotFormated();
|
|
|
|
|
|
if (!firstTimeInit) {
|
|
|
|
|
|
if (prevDate != currentDate) {
|
|
|
|
|
|
changed = true;
|
|
|
|
|
|
SerialPrint("i", F("NTP"), F("Change day core event"));
|
|
|
|
|
|
//установим новую дату во всех графиках системы
|
|
|
|
|
|
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
|
|
|
|
|
(*it)->setTodayDate();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
firstTimeInit = false;
|
|
|
|
|
|
prevDate = currentDate;
|
|
|
|
|
|
return changed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-11 01:30:22 +02:00
|
|
|
|
unsigned long gmtTimeToLocal(unsigned long gmtTimestamp) {
|
|
|
|
|
|
return gmtTimestamp + (jsonReadInt(settingsFlashJson, F("timezone")) * 60 * 60);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-18 14:49:11 +02:00
|
|
|
|
time_t getSystemTime() {
|
|
|
|
|
|
timeval tv{0, 0};
|
|
|
|
|
|
timezone tz = timezone{0, 0};
|
|
|
|
|
|
time_t epoch = 0;
|
|
|
|
|
|
if (gettimeofday(&tv, &tz) != -1) {
|
|
|
|
|
|
epoch = tv.tv_sec;
|
|
|
|
|
|
}
|
|
|
|
|
|
return epoch;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void breakEpochToTime(unsigned long epoch, Time_t& tm) {
|
|
|
|
|
|
// break the given time_input into time components
|
|
|
|
|
|
// this is a more compact version of the C library localtime function
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long time = epoch;
|
|
|
|
|
|
tm.second = time % 60;
|
|
|
|
|
|
time /= 60; // now it is minutes
|
|
|
|
|
|
tm.minute = time % 60;
|
|
|
|
|
|
time /= 60; // now it is hours
|
|
|
|
|
|
tm.hour = time % 24;
|
|
|
|
|
|
time /= 24; // now it is days
|
|
|
|
|
|
tm.days = time;
|
|
|
|
|
|
tm.day_of_week = ((time + 4) % 7) + 1; // Sunday is day 1
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t year = 0;
|
|
|
|
|
|
unsigned long days = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
|
|
|
|
|
|
year++;
|
|
|
|
|
|
}
|
|
|
|
|
|
tm.year = year - 30;
|
|
|
|
|
|
|
|
|
|
|
|
days -= LEAP_YEAR(year) ? 366 : 365;
|
|
|
|
|
|
time -= days; // now it is days in this year, starting at 0
|
|
|
|
|
|
tm.day_of_year = time;
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t month;
|
|
|
|
|
|
uint8_t month_length;
|
|
|
|
|
|
for (month = 0; month < 12; month++) {
|
|
|
|
|
|
if (1 == month) { // february
|
|
|
|
|
|
if (LEAP_YEAR(year)) {
|
|
|
|
|
|
month_length = 29;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
month_length = 28;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
month_length = days_in_month[month];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (time >= month_length) {
|
|
|
|
|
|
time -= month_length;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
tm.month = month + 1; // jan is month 1
|
|
|
|
|
|
tm.day_of_month = time + 1; // day of month
|
|
|
|
|
|
tm.valid = (epoch > MIN_DATETIME);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const String getTimeLocal_hhmm() {
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d:%02d", _time_local.hour, _time_local.minute);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const String getTimeLocal_hhmmss() {
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d:%02d:%02d", _time_local.hour, _time_local.minute, _time_local.second);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const String getDateTimeDotFormated() {
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d.%02d.%02d %02d:%02d:%02d", _time_local.day_of_month, _time_local.month, _time_local.year, _time_local.hour, _time_local.minute, _time_local.second);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
2022-08-25 15:15:06 +02:00
|
|
|
|
|
2022-09-18 19:29:46 +02:00
|
|
|
|
const String getTodayDateDotFormated() {
|
2022-09-11 01:30:22 +02:00
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d.%02d.%d", _time_local.day_of_month, _time_local.month, _time_local.year + 2000);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// format 22.02.2022
|
2022-08-25 15:15:06 +02:00
|
|
|
|
unsigned long strDateToUnix(String date) {
|
|
|
|
|
|
int day = selectToMarker(date, ".").toInt();
|
|
|
|
|
|
date = deleteBeforeDelimiter(date, ".");
|
|
|
|
|
|
int month = selectToMarker(date, ".").toInt();
|
|
|
|
|
|
date = deleteBeforeDelimiter(date, ".");
|
|
|
|
|
|
int year = selectToMarker(date, ".").toInt();
|
|
|
|
|
|
int secsInOneDay = 86400;
|
|
|
|
|
|
int daysInOneYear = 365;
|
|
|
|
|
|
int daysInLeepYear = 366;
|
|
|
|
|
|
int numberOfLeepYears = 12;
|
|
|
|
|
|
int totalNormalYears = year - 1970 - numberOfLeepYears;
|
|
|
|
|
|
unsigned int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
2024-03-12 00:16:09 +03:00
|
|
|
|
if (year % 4 == 0) {
|
|
|
|
|
|
if (year % 100 != 0 || year % 400 == 0) {
|
|
|
|
|
|
daysInMonth[1] = 29;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
daysInMonth[1] = 28;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
daysInMonth[1] = 28;
|
|
|
|
|
|
}
|
2022-08-25 15:15:06 +02:00
|
|
|
|
int numberOfDaysInPastMonths = 0;
|
|
|
|
|
|
for (int i = 0; i <= 11; i++) {
|
|
|
|
|
|
if (i <= month - 2) {
|
|
|
|
|
|
numberOfDaysInPastMonths = numberOfDaysInPastMonths + daysInMonth[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return (day * secsInOneDay) + (numberOfDaysInPastMonths * secsInOneDay) + (totalNormalYears * daysInOneYear * secsInOneDay) + (numberOfLeepYears * daysInLeepYear * secsInOneDay);
|
|
|
|
|
|
}
|
2022-09-08 00:27:38 +02:00
|
|
|
|
|
|
|
|
|
|
const String getDateTimeDotFormatedFromUnix(unsigned long unixTime) {
|
|
|
|
|
|
Time_t time;
|
|
|
|
|
|
breakEpochToTime(unixTime, time);
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d.%02d.%02d %02d:%02d:%02d", time.day_of_month, time.month, time.year, time.hour, time.minute, time.second);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
2022-09-16 01:52:04 +02:00
|
|
|
|
|
2023-10-06 00:21:14 +03:00
|
|
|
|
const String getTimeDotFormatedFromUnix(unsigned long unixTime) {
|
|
|
|
|
|
Time_t time;
|
|
|
|
|
|
breakEpochToTime(unixTime, time);
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d:%02d:%02d", time.hour, time.minute, time.second);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-16 01:52:04 +02:00
|
|
|
|
const String getDateDotFormatedFromUnix(unsigned long unixTime) {
|
|
|
|
|
|
Time_t time;
|
|
|
|
|
|
breakEpochToTime(unixTime, time);
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
sprintf(buf, "%02d.%02d.%d", time.day_of_month, time.month, time.year + 2000);
|
|
|
|
|
|
return String(buf);
|
|
|
|
|
|
}
|