Files
Smart-granary-code/components/sntp_time/sntp_time.c
Wang Beihong a1566f3dc6 功能:添加 Wi-Fi 连接管理组件
在 wifi-connect.c 中实现了新的 Wi-Fi 连接管理模块,负责配网、连接及状态上报。

添加了用于 Wi-Fi 配置和状态显示的 HTML 界面。

集成了 NVS 用于存储 Wi-Fi 凭证。

更新了 CMakeLists.txt 以包含新模块的依赖项。

修改了 main.c 以初始化 Wi-Fi 连接管理并等待连接成功。
2026-04-20 13:11:50 +08:00

158 lines
3.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "sntp_time.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_idf_version.h"
#include "esp_sntp.h"
#include "esp_netif_sntp.h"
#include "sys/time.h"
#include "esp_timer.h"
static const char *TAG = "sntp_timp";
#define SNTP_TIME_VALID_UNIX_TS 1700000000
#define SNTP_WAIT_POLL_MS 200
#define SNTP_REFRESH_PERIOD_MS 1000
extern void set_var_sntp_time(const char *value) __attribute__((weak));
static TaskHandle_t s_time_refresh_task = NULL;
static time_t get_current_time(void);
static void publish_sntp_time_var(const char *value)
{
if (set_var_sntp_time != NULL) {
set_var_sntp_time(value);
}
}
static void format_current_time(char *buffer, size_t buffer_size)
{
time_t now = get_current_time();
struct tm timeinfo;
localtime_r(&now, &timeinfo);
strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", &timeinfo);
}
static void sntp_time_refresh_task(void *arg)
{
(void)arg;
char time_text[32];
for (;;) {
format_current_time(time_text, sizeof(time_text));
publish_sntp_time_var(time_text);
vTaskDelay(pdMS_TO_TICKS(SNTP_REFRESH_PERIOD_MS));
}
}
// =========================== 时间相关函数 ===========================
static void set_timezone(void)
{
// 设置中国标准时间(北京时间)
setenv("TZ", "CST-8", 1);
tzset();
ESP_LOGI(TAG, "时区设置为北京时间 (CST-8)");
}
static time_t get_current_time(void)
{
// 使用POSIX函数获取时间
return time(NULL);
}
static void print_current_time(void)
{
char buffer[64];
format_current_time(buffer, sizeof(buffer));
ESP_LOGI(TAG, "当前时间: %s", buffer);
}
static esp_err_t start_time_refresh_task_if_needed(void)
{
if (s_time_refresh_task != NULL) {
return ESP_OK;
}
BaseType_t ok = xTaskCreate(sntp_time_refresh_task,
"sntp_time",
3072,
NULL,
3,
&s_time_refresh_task);
return (ok == pdPASS) ? ESP_OK : ESP_ERR_NO_MEM;
}
static void configure_sntp_servers(void)
{
ESP_LOGI(TAG, "初始化SNTP服务");
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, "cn.pool.ntp.org"); // 中国 NTP 服务器
esp_sntp_setservername(1, "ntp1.aliyun.com"); // 阿里云 NTP 服务器
#else
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "cn.pool.ntp.org");
sntp_setservername(1, "cn.pool.ntp.org");
sntp_setservername(2, "ntp1.aliyun.com");
#endif
}
static esp_err_t wait_for_time_sync(uint32_t timeout_ms)
{
int64_t start_ms = esp_timer_get_time() / 1000;
for (;;) {
time_t now = get_current_time();
if (now >= SNTP_TIME_VALID_UNIX_TS) {
return ESP_OK;
}
int64_t elapsed_ms = (esp_timer_get_time() / 1000) - start_ms;
if (elapsed_ms >= (int64_t)timeout_ms) {
return ESP_ERR_TIMEOUT;
}
vTaskDelay(pdMS_TO_TICKS(SNTP_WAIT_POLL_MS));
}
}
esp_err_t sntp_timp_sync_time(uint32_t timeout_ms)
{
if (timeout_ms == 0) {
timeout_ms = 10000;
}
set_timezone();
if (esp_sntp_enabled()) {
esp_sntp_stop();
}
configure_sntp_servers();
esp_sntp_init();
esp_err_t ret = wait_for_time_sync(timeout_ms);
if (ret == ESP_OK) {
print_current_time();
char time_text[32];
format_current_time(time_text, sizeof(time_text));
publish_sntp_time_var(time_text);
esp_err_t task_ret = start_time_refresh_task_if_needed();
if (task_ret != ESP_OK) {
ESP_LOGW(TAG, "创建时间刷新任务失败: %s", esp_err_to_name(task_ret));
}
} else {
ESP_LOGW(TAG, "SNTP 对时超时(%lu ms", (unsigned long)timeout_ms);
}
return ret;
}