Uniot Core
0.8.1
Loading...
Searching...
No Matches
Date.h
Go to the documentation of this file.
1/*
2 * This is a part of the Uniot project.
3 * Copyright (C) 2016-2023 Uniot <contact@uniot.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
26
32
33#pragma once
34
35#if defined(ESP8266)
36#include <ESP8266WiFi.h>
37#include <coredecls.h>
38#elif defined(ESP32)
39#include <WiFi.h>
40#include <esp_sntp.h>
41#endif
42
43#include <DateEvents.h>
44#include <CBORStorage.h>
45#include <EventEmitter.h>
46#include <IExecutor.h>
47#include <SimpleNTP.h>
48#include <Singleton.h>
49#include <time.h>
50
51namespace uniot {
65class Date : public IExecutor, public CBORStorage, public Singleton<Date>, public CoreEventEmitter {
66 friend class Singleton<Date>;
67
68 public:
74 static time_t now() {
75 return getInstance()._now();
76 }
77
83 static String getFormattedTime() {
84 return getInstance()._getFormattedTime();
85 }
86
96 bool store() override {
97 CBORStorage::object().put("epoch", static_cast<int64_t>(this->_now()));
98 return CBORStorage::store();
99 }
100
110 bool restore() override {
111 if (CBORStorage::restore()) {
112 auto currentEpoch = CBORStorage::object().getInt("epoch");
113 _setTime(currentEpoch);
114 return true;
115 }
116 UNIOT_LOG_ERROR("%s", "epoch not restored");
117 return false;
118 }
119
127 virtual void execute(short _) override {
128 if (!this->store()) {
129 UNIOT_LOG_ERROR("failed to store current epoch in CBORStorage");
130 }
131 }
132
139 void forceSync() {
140 _reconfigure();
141 auto epoch = mSNTP.getNtpTime();
142 if (epoch) {
143 _setTime(epoch);
144 }
145 }
146
147 private:
154 Date() : CBORStorage("date.cbor") {
155#if defined(ESP8266)
156 settimeofday_cb([this](bool from_sntp) {
157 Date::getInstance()._timeSyncCallback();
158 UNIOT_LOG_INFO("Time is set from %s", from_sntp ? "SNTP" : "RTC");
159 });
160#elif defined(ESP32)
161 sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);
162 sntp_set_time_sync_notification_cb([](struct timeval *tv) {
163 Date::getInstance()._timeSyncCallback();
164 UNIOT_LOG_INFO("Time is set from SNTP");
165 });
166#endif
167 mSNTP.setSyncTimeCallback([](time_t epoch) {
168 Date::getInstance()._timeSyncCallback();
169 UNIOT_LOG_INFO("Time is forced to synchronize with SNTP");
170 });
171
172 _reconfigure();
173
174 this->restore();
175 }
176
183 void _timeSyncCallback() {
184 execute(0);
186 }
187
197 bool _setTime(time_t epoch) {
198#if defined(ESP8266)
199 tune_timeshift64(epoch * 1000000ULL);
200#elif defined(ESP32)
201 timeval tv = {epoch, 0};
202 if (settimeofday(&tv, nullptr) != 0) {
203 UNIOT_LOG_ERROR("Failed to set system time");
204 return false;
205 }
206#endif
207 return true;
208 }
209
215 void _reconfigure() {
216 configTime(0, 0, SimpleNTP::servers[0], SimpleNTP::servers[1], SimpleNTP::servers[2]);
217 }
218
224 time_t _now() {
225 return time(nullptr);
226 }
227
236 String _getFormattedTime() {
237 tm tm;
238 auto currentEpoc = this->_now();
239 localtime_r(&currentEpoc, &tm);
240
241 char formattedTime[72] = {0};
242 snprintf(formattedTime, sizeof(formattedTime), "%04d-%02d-%02d %02d:%02d:%02d",
243 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
244 tm.tm_hour, tm.tm_min, tm.tm_sec);
245
246 return String(formattedTime);
247 }
248
250 SimpleNTP mSNTP;
251};
252
253} // namespace uniot
Date and time event definitions for the Uniot event system.
long getInt(int key) const
Get an integer value at a specific integer key.
Definition CBORObject.h:399
CBORObject & put(int key, int value)
Put an integer value at a specific integer key.
Definition CBORObject.h:170
Definition CBORStorage.h:39
virtual bool restore() override
Restore the CBOR object from the filesystem.
Definition CBORStorage.h:92
virtual bool store() override
Store the CBOR object to the filesystem.
Definition CBORStorage.h:74
CBORStorage(const String &path)
Constructs a new CBORStorage object.
Definition CBORStorage.h:46
CBORObject & object()
Get access to the underlying CBORObject.
Definition CBORStorage.h:60
Definition Date.h:65
virtual void execute(short _) override
Periodic execution callback.
Definition Date.h:127
bool restore() override
Restores time from persistent storage.
Definition Date.h:110
static String getFormattedTime()
Gets the current time in human-readable format.
Definition Date.h:83
bool store() override
Stores the current time to persistent storage.
Definition Date.h:96
void forceSync()
Forces immediate NTP time synchronization.
Definition Date.h:139
static time_t now()
Returns the current Unix timestamp.
Definition Date.h:74
void emitEvent(unsigned int topic, int msg)
Interface for executing tasks in the scheduler system.
Definition IExecutor.h:31
static constexpr const char * servers[]
Array of NTP server hostnames to try connecting to.
Definition SimpleNTP.h:34
Singleton(const Singleton &)=delete
static Date & getInstance()
Definition Singleton.h:73
EventEmitter< unsigned int, int, Bytes > CoreEventEmitter
A specialized EventEmitter for core system events.
Definition EventEmitter.h:78
#define UNIOT_LOG_INFO(...)
Log an INFO level message Used for general information about system operation. Only compiled if UNIOT...
Definition Logger.h:268
#define UNIOT_LOG_ERROR(...)
Log an ERROR level message Used for critical errors that may prevent normal operation....
Definition Logger.h:226
@ TIME
Time synchronization and date-related operations.
Definition DateEvents.h:61
@ SYNCED
System time has been successfully synchronized with time source.
Definition DateEvents.h:72
Contains all classes and functions related to the Uniot Core.