feat: 实现时间同步、NVS稳定性修复和ESP-IDF v6.0兼容性改进
This commit is contained in:
153
main/time_sync/time_sync.c
Normal file
153
main/time_sync/time_sync.c
Normal file
@@ -0,0 +1,153 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user