Files
mimiclaw/main/time_sync/time_sync.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;
}