feat: 添加时区设置功能,默认时区改为 CST-8
- 新增 set_timezone LLM 工具,支持通过对话设置时区 - 新增 set_timezone / timezone_show CLI 命令 - 默认时区从 PST 改为 CST-8(中国标准时间 UTC+8) - 支持 POSIX 格式和 18 个城市名映射(Asia/Shanghai 等) - 时区通过 NVS 持久化存储(system_config namespace) - config_show 中显示当前时区配置 - 更新 changelog.md 和 taolun.md 文档
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_console.h"
|
||||
@@ -654,6 +656,11 @@ static int cmd_config_show(int argc, char **argv)
|
||||
print_config_u16("Proxy Port", MIMI_NVS_PROXY, MIMI_NVS_KEY_PROXY_PORT, MIMI_SECRET_PROXY_PORT);
|
||||
print_config("Search Key", MIMI_NVS_SEARCH, MIMI_NVS_KEY_API_KEY, MIMI_SECRET_SEARCH_KEY, true);
|
||||
print_config("Tavily Key", MIMI_NVS_SEARCH, MIMI_NVS_KEY_TAVILY_KEY, MIMI_SECRET_TAVILY_KEY, true);
|
||||
|
||||
/* System configs */
|
||||
printf(" --- System configs ---\n");
|
||||
print_config("Timezone", "system_config", MIMI_NVS_KEY_TIMEZONE, MIMI_TIMEZONE, false);
|
||||
|
||||
printf("=============================\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -676,6 +683,87 @@ static int cmd_config_reset(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- set_timezone command --- */
|
||||
static struct {
|
||||
struct arg_str *tz;
|
||||
struct arg_end *end;
|
||||
} timezone_args;
|
||||
|
||||
static int cmd_set_timezone(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **)&timezone_args);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, timezone_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *tz_str = timezone_args.tz->sval[0];
|
||||
nvs_handle_t nvs;
|
||||
esp_err_t err = nvs_open("system_config", NVS_READWRITE, &nvs);
|
||||
if (err != ESP_OK) {
|
||||
printf("Failed to open NVS: %s\n", esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = nvs_set_str(nvs, MIMI_NVS_KEY_TIMEZONE, tz_str);
|
||||
if (err != ESP_OK) {
|
||||
printf("Failed to save timezone: %s\n", esp_err_to_name(err));
|
||||
nvs_close(nvs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = nvs_commit(nvs);
|
||||
nvs_close(nvs);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
printf("Failed to commit NVS: %s\n", esp_err_to_name(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
setenv("TZ", tz_str, 1);
|
||||
tzset();
|
||||
|
||||
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);
|
||||
|
||||
printf("Timezone set to '%s'. Current time: %s. Restart to apply permanently.\n", tz_str, time_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- timezone_show command --- */
|
||||
static int cmd_timezone_show(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
char nvs_val[64] = {0};
|
||||
const char *source = "build";
|
||||
const char *display = MIMI_TIMEZONE;
|
||||
|
||||
nvs_handle_t nvs;
|
||||
if (nvs_open("system_config", NVS_READONLY, &nvs) == ESP_OK) {
|
||||
size_t len = sizeof(nvs_val);
|
||||
if (nvs_get_str(nvs, MIMI_NVS_KEY_TIMEZONE, nvs_val, &len) == ESP_OK && nvs_val[0]) {
|
||||
source = "NVS";
|
||||
display = nvs_val;
|
||||
}
|
||||
nvs_close(nvs);
|
||||
}
|
||||
|
||||
printf("Current timezone: %s [%s]\n", display, source);
|
||||
|
||||
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 (%A)", &tm_now);
|
||||
printf("Local time: %s\n", time_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- heartbeat_trigger command --- */
|
||||
static int cmd_heartbeat_trigger(int argc, char **argv)
|
||||
{
|
||||
@@ -736,13 +824,22 @@ typedef struct {
|
||||
size_t output_size;
|
||||
esp_err_t err;
|
||||
SemaphoreHandle_t done;
|
||||
bool timed_out;
|
||||
} web_search_task_ctx_t;
|
||||
|
||||
static void web_search_task(void *arg)
|
||||
{
|
||||
web_search_task_ctx_t *task_ctx = (web_search_task_ctx_t *)arg;
|
||||
task_ctx->err = tool_web_search_execute(task_ctx->input_json, task_ctx->output, task_ctx->output_size);
|
||||
xSemaphoreGive(task_ctx->done);
|
||||
if (!task_ctx->timed_out) {
|
||||
xSemaphoreGive(task_ctx->done);
|
||||
} else {
|
||||
/* Main thread timed out and freed ctx, so we must clean up ourselves */
|
||||
free((void *)task_ctx->input_json);
|
||||
free(task_ctx->output);
|
||||
vSemaphoreDelete(task_ctx->done);
|
||||
free(task_ctx);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
@@ -838,10 +935,8 @@ static int cmd_web_search(int argc, char **argv)
|
||||
|
||||
if (xSemaphoreTake(ctx->done, pdMS_TO_TICKS(45000)) != pdTRUE) {
|
||||
printf("web_search status: timeout\n");
|
||||
vSemaphoreDelete(ctx->done);
|
||||
free(input_copy);
|
||||
free(ctx);
|
||||
free(output);
|
||||
ctx->timed_out = true;
|
||||
/* Task will clean up ctx, input_copy, output, and done on its own */
|
||||
return 1;
|
||||
}
|
||||
esp_err_t err = ctx->err;
|
||||
@@ -1163,6 +1258,25 @@ esp_err_t serial_cli_init(void)
|
||||
};
|
||||
esp_console_cmd_register(&config_reset_cmd);
|
||||
|
||||
/* set_timezone */
|
||||
timezone_args.tz = arg_str1(NULL, NULL, "<timezone>", "Timezone (e.g. CST-8, Asia/Shanghai)");
|
||||
timezone_args.end = arg_end(1);
|
||||
esp_console_cmd_t set_timezone_cmd = {
|
||||
.command = "set_timezone",
|
||||
.help = "Set system timezone (e.g. set_timezone CST-8)",
|
||||
.func = &cmd_set_timezone,
|
||||
.argtable = &timezone_args,
|
||||
};
|
||||
esp_console_cmd_register(&set_timezone_cmd);
|
||||
|
||||
/* timezone_show */
|
||||
esp_console_cmd_t timezone_show_cmd = {
|
||||
.command = "timezone_show",
|
||||
.help = "Show current timezone and local time",
|
||||
.func = &cmd_timezone_show,
|
||||
};
|
||||
esp_console_cmd_register(&timezone_show_cmd);
|
||||
|
||||
/* heartbeat_trigger */
|
||||
esp_console_cmd_t heartbeat_cmd = {
|
||||
.command = "heartbeat_trigger",
|
||||
|
||||
Reference in New Issue
Block a user