154 lines
4.0 KiB
C
154 lines
4.0 KiB
C
#include "time_sync.h"
|
|
#include "mimi_config.h"
|
|
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "esp_log.h"
|
|
#include "esp_sntp.h"
|
|
#include "nvs.h"
|
|
|
|
static const char *TAG = "time_sync";
|
|
static volatile bool s_synced = false;
|
|
static volatile time_t s_last_synced_time = 0;
|
|
static char s_ntp_server[128] = MIMI_DEFAULT_NTP_SERVER;
|
|
|
|
static void sntp_sync_cb(struct timeval *tv)
|
|
{
|
|
(void)tv;
|
|
s_synced = true;
|
|
s_last_synced_time = tv->tv_sec;
|
|
|
|
/* Apply timezone from NVS */
|
|
char tz_str[64] = {0};
|
|
nvs_handle_t nvs;
|
|
if (nvs_open("system_config", NVS_READONLY, &nvs) == ESP_OK) {
|
|
size_t len = sizeof(tz_str);
|
|
if (nvs_get_str(nvs, MIMI_NVS_KEY_TIMEZONE, tz_str, &len) == ESP_OK && tz_str[0]) {
|
|
setenv("TZ", tz_str, 1);
|
|
tzset();
|
|
ESP_LOGI(TAG, "Applied timezone from NVS: %s", tz_str);
|
|
} else {
|
|
setenv("TZ", MIMI_TIMEZONE, 1);
|
|
tzset();
|
|
ESP_LOGI(TAG, "Using build-time timezone: %s", MIMI_TIMEZONE);
|
|
}
|
|
nvs_close(nvs);
|
|
} else {
|
|
setenv("TZ", MIMI_TIMEZONE, 1);
|
|
tzset();
|
|
ESP_LOGI(TAG, "Using build-time timezone: %s", MIMI_TIMEZONE);
|
|
}
|
|
|
|
time_t now = time(NULL);
|
|
struct tm tm_now;
|
|
localtime_r(&now, &tm_now);
|
|
char time_str[64];
|
|
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S %Z", &tm_now);
|
|
ESP_LOGI(TAG, "Time synchronized: %s", time_str);
|
|
}
|
|
|
|
static void load_custom_server(void)
|
|
{
|
|
nvs_handle_t nvs;
|
|
if (nvs_open("system_config", NVS_READONLY, &nvs) == ESP_OK) {
|
|
size_t len = sizeof(s_ntp_server);
|
|
if (nvs_get_str(nvs, MIMI_NVS_KEY_NTP_SERVER, s_ntp_server, &len) == ESP_OK && s_ntp_server[0]) {
|
|
ESP_LOGI(TAG, "Loaded custom NTP server from NVS: %s", s_ntp_server);
|
|
} else {
|
|
strlcpy(s_ntp_server, MIMI_DEFAULT_NTP_SERVER, sizeof(s_ntp_server));
|
|
}
|
|
nvs_close(nvs);
|
|
}
|
|
}
|
|
|
|
static void start_sntp(void)
|
|
{
|
|
esp_sntp_stop();
|
|
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
|
esp_sntp_setservername(0, s_ntp_server);
|
|
esp_sntp_set_time_sync_notification_cb(sntp_sync_cb);
|
|
esp_sntp_init();
|
|
ESP_LOGI(TAG, "SNTP configured with server: %s", s_ntp_server);
|
|
}
|
|
|
|
esp_err_t time_sync_init(void)
|
|
{
|
|
ESP_LOGI(TAG, "Initializing SNTP...");
|
|
|
|
load_custom_server();
|
|
start_sntp();
|
|
s_synced = false;
|
|
s_last_synced_time = 0;
|
|
|
|
ESP_LOGI(TAG, "SNTP started, waiting for sync...");
|
|
return ESP_OK;
|
|
}
|
|
|
|
bool time_sync_is_synced(void)
|
|
{
|
|
return s_synced;
|
|
}
|
|
|
|
const char *time_sync_status_str(void)
|
|
{
|
|
if (s_synced) return "synced";
|
|
if (esp_sntp_getservername(0) != NULL) return "syncing";
|
|
return "not_synced";
|
|
}
|
|
|
|
bool time_sync_get_last_synced(char *out, size_t out_size)
|
|
{
|
|
if (s_last_synced_time == 0) return false;
|
|
|
|
time_t t = (time_t)s_last_synced_time;
|
|
struct tm tm_now;
|
|
localtime_r(&t, &tm_now);
|
|
strftime(out, out_size, "%Y-%m-%d %H:%M:%S", &tm_now);
|
|
return true;
|
|
}
|
|
|
|
const char *time_sync_get_server(void)
|
|
{
|
|
return s_ntp_server;
|
|
}
|
|
|
|
esp_err_t time_sync_set_server(const char *server)
|
|
{
|
|
if (!server || !server[0]) return ESP_ERR_INVALID_ARG;
|
|
|
|
strlcpy(s_ntp_server, server, sizeof(s_ntp_server));
|
|
|
|
nvs_handle_t nvs;
|
|
esp_err_t err = nvs_open("system_config", NVS_READWRITE, &nvs);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to open NVS: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
err = nvs_set_str(nvs, MIMI_NVS_KEY_NTP_SERVER, server);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to save NTP server: %s", esp_err_to_name(err));
|
|
nvs_close(nvs);
|
|
return err;
|
|
}
|
|
|
|
err = nvs_commit(nvs);
|
|
nvs_close(nvs);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to commit NVS: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "NTP server saved to NVS: %s", server);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t time_sync_restart(void)
|
|
{
|
|
ESP_LOGI(TAG, "Restarting SNTP with server: %s", s_ntp_server);
|
|
s_synced = false;
|
|
s_last_synced_time = 0;
|
|
start_sntp();
|
|
return ESP_OK;
|
|
}
|