在 wifi-connect.c 中实现了新的 Wi-Fi 连接管理模块,负责配网、连接及状态上报。 添加了用于 Wi-Fi 配置和状态显示的 HTML 界面。 集成了 NVS 用于存储 Wi-Fi 凭证。 更新了 CMakeLists.txt 以包含新模块的依赖项。 修改了 main.c 以初始化 Wi-Fi 连接管理并等待连接成功。
158 lines
3.9 KiB
C
158 lines
3.9 KiB
C
#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;
|
||
}
|