This commit is contained in:
Yuri Trikoz
2020-06-27 01:21:58 +03:00
parent b51ec4d0e2
commit 00fd9f9bb9
14 changed files with 371 additions and 266 deletions

View File

@@ -4,6 +4,7 @@
#include "Utils/PrintMessage.h"
#include "TZ.h"
#include "sntp.h"
class Clock {
const char* MODULE = "Clock";
@@ -11,6 +12,27 @@ class Clock {
public:
Clock() : _timezone{0}, _hasSynced{false}, _configured{false} {}
void loop() {
unsigned long passed = millis_since(_uptime);
if (passed < ONE_SECOND_ms) {
return;
}
_uptime += passed;
// world time
time_t now = getSystemTime();
time_t estimated = _epoch + (passed / ONE_SECOND_ms);
double drift = difftime(now, estimated);
if (drift > 1) {
// Обработать ситуации c дрифтом времени на значительные величины
}
// TODO сохранять время на флеше
_epoch = now;
breakEpochToTime(_epoch, _time);
}
bool hasSync() {
if (!_hasSynced) {
startSync();
@@ -19,18 +41,26 @@ class Clock {
}
void setNtpPool(String ntp) {
_ntp = ntp;
if (!_ntp.equals(ntp)) {
_ntp = ntp;
_configured = false;
}
}
void setTimezone(int timezone) {
_timezone = timezone;
if (_timezone != timezone) {
_timezone = timezone;
_configured = false;
}
}
void startSync() {
if (!_configured) {
pm.info("sync to: " + _ntp + " time zone: " + String(_timezone));
pm.info("sync to: " + _ntp + " timezone: " + String(_timezone));
setupSntp();
_configured = true;
// лучше не ждать, проверим в следующий раз
return;
}
_hasSynced = hasTimeSynced();
if (_hasSynced) {
@@ -41,42 +71,70 @@ class Clock {
}
void setupSntp() {
int tzs = getOffsetInSeconds(_timezone);
int tzh = tzs / 3600;
tzs -= tzh * 3600;
int tzm = tzs / 60;
tzs -= tzm * 60;
char tzstr[64];
snprintf(tzstr, sizeof tzstr, "ESPUSER<%+d:%02d:%02d>", tzh, tzm, tzs);
pm.info(String(tzstr));
configTime(tzstr, _ntp.c_str());
}
// #ifdef ESP32
// uint8_t i = 0;
// struct tm timeinfo;
// while (!getLocalTime(&timeinfo) && i <= 4) {
// Serial.print(".");
// i++;
// delay(1000);
// }
// #endifr
bool hasTimeSynced() {
return getSystemTime() > 30000;
sntp_setservername(0, _ntp.c_str());
sntp_setservername(1, "ru.pool.ntp.org");
sntp_setservername(2, "pool.ntp.org");
sntp_stop();
sntp_set_timezone(0); // UTC time
sntp_init();
}
time_t getSystemTime() {
bool hasTimeSynced() const {
return _epoch > MIN_DATETIME;
}
time_t getSystemTime() const {
timeval tv{0, 0};
timezone tz = timezone{getOffsetInMinutes(_timezone), 0};
timezone tz = timezone{0, 0};
time_t epoch = 0;
if (gettimeofday(&tv, &tz) != -1) {
_epoch = tv.tv_sec;
epoch = tv.tv_sec;
}
return _epoch;
return epoch;
}
const String getTimeUnix() {
return String(_epoch);
}
/*
* Локальное время "дд.ММ.гг"
*/
const String getDateDigitalFormated() {
char buf[16];
sprintf(buf, "%02d.%02d.%02d", _time.day_of_month, _time.month, _time.year);
return String(buf);
}
/*
* Локальное время "чч:мм:cc"
*/
const String getTime() {
char buf[16];
sprintf(buf, "%02d:%02d:%02d", _time.hour, _time.minute, _time.second);
return String(buf);
}
/*
* Локальное время "чч:мм"
*/
const String getTimeWOsec() {
char buf[16];
sprintf(buf, "%02d:%02d", _time.hour, _time.minute);
return String(buf);
}
/*
* Время с момента запуска "чч:мм" далее "дд чч:мм"
*/
const String getUptime() {
return prettyMillis(_uptime);
}
private:
time_t _epoch;
Time_t _time;
unsigned long _uptime;
unsigned long _epoch;
int _timezone;
String _ntp;
bool _hasSynced;

View File

@@ -1,5 +1,18 @@
#pragma once
struct Time_t {
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t day_of_week; // sunday is day 1
uint8_t day_of_month;
uint8_t month;
uint16_t day_of_year;
uint16_t year;
unsigned long days;
unsigned long valid;
};
enum TimerTask_t { WIFI_SCAN,
WIFI_MQTT_CONNECTION_CHECK,
SENSORS,

View File

@@ -14,7 +14,6 @@
#include "Bus/BusScanner.h"
#include "Errors.h"
#include "GyverFilters.h"
#include "UptimeInterval.h"
#include "Upgrade.h"
#include "Clock.h"
@@ -46,7 +45,7 @@ extern AsyncWebSocket ws;
//extern AsyncEventSource events;
#endif
extern Clock* rtc;
extern Clock* timeNow;
extern TickerScheduler ts;

View File

@@ -1,32 +0,0 @@
#pragma once
#include <Arduino.h>
class UptimeInterval {
public:
UptimeInterval(unsigned long interval, boolean postpone = true) : _next{0}, _interval{interval} {
reset(postpone);
}
boolean check() {
if (_next <= get()) {
_next += _interval;
return true;
}
return false;
}
void reset(bool postpone = true) {
_next = (postpone ? _uptime_seconds + _interval : _uptime_seconds);
}
static unsigned long get() {
unsigned long _uptime_seconds = millis() / 1000;
return _uptime_seconds;
};
static unsigned long _uptime_seconds;
private:
unsigned long _next, _interval;
};

View File

@@ -24,7 +24,7 @@ class PrintMessage {
private:
void print(const ErrorLevel_t level, const String& str) {
Serial.printf("%s [%s] [%s] %s\n", prettyMillis().c_str(), getErrorLevelStr(level).c_str(), _module, str.c_str());
Serial.printf("%s [%s] [%s] %s\n", prettyMillis(millis()).c_str(), getErrorLevelStr(level).c_str(), _module, str.c_str());
}
private:

View File

@@ -1,37 +1,15 @@
#pragma once
#ifdef ESP8266
#include <time.h>
#endif
#include <Arduino.h>
/*
* Получение текущего времени
*/
String getTime();
#include "CommonTypes.h"
/*
* Получаем время в формате linux gmt
*/
String getTimeUnix();
/*
* Параметр время
* @result результат
*/
boolean getUnixTimeStr(String&);
String getTimeWOsec();
/*
* Получение даты
*/
String getDate();
String getDateDigitalFormated();
int timeToMin(String Time);
const String prettyMillis(unsigned long time_ms = millis());
#define ONE_MINUTE_s 60
#define ONE_HOUR_m 60
#define ONE_HOUR_s 60 * ONE_MINUTE_s
#define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
#define MIN_DATETIME 1575158400
#define ONE_SECOND_ms 1000
/*
* Время (мс) прошедщее с @since
@@ -43,6 +21,31 @@ unsigned long millis_since(unsigned long sinse);
*/
unsigned long millis_passed(unsigned long start, unsigned long finish);
/*
* Форматиронное время интервала (мс)
* "чч:мм:cc",
* "дд чч:мм", если > 24 часов
*/
const String prettyMillis(unsigned long time_ms = millis());
/*
* Форматиронное время интервала (c)
* "чч:мм:cc",
* "дд чч:мм", если > 24 часов
*/
const String prettySeconds(unsigned long time_s);
/*
* Тайм зона в секундах
*/
int getOffsetInSeconds(int timezone);
/*
* Тайм зона в минутах
*/
int getOffsetInMinutes(int timezone);
/*
* Разбивает время на составляющие
*/
void breakEpochToTime(unsigned long epoch, Time_t& tm);