From f33ad70c165dfdb4653e06a169b44a60e5486dea Mon Sep 17 00:00:00 2001 From: chenjintao Date: Tue, 25 Aug 2026 09:55:39 +0800 Subject: [PATCH] fix(time): apply timezone before lcd startup --- .../runtime/app_composition_default_runtime.c | 14 +++++++++++++ .../control_plane/include/control_plane.h | 3 +++ .../control_plane_connectivity_runtime.c | 9 +++++++++ components/domain/include/domain.h | 8 +++++--- .../src/runtime/domain_runtime_adapters.c | 5 +++++ components/platform/include/platform.h | 3 +++ .../platform/src/runtime/platform_time.c | 20 +++++++++++++++++-- 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/components/app_composition/src/runtime/app_composition_default_runtime.c b/components/app_composition/src/runtime/app_composition_default_runtime.c index b07fcca..922707e 100644 --- a/components/app_composition/src/runtime/app_composition_default_runtime.c +++ b/components/app_composition/src/runtime/app_composition_default_runtime.c @@ -31,6 +31,7 @@ static const char *TAG = "app_comp_boot"; typedef enum { APP_COMPOSITION_BOOT_STAGE_POWER_HOLD = 1, APP_COMPOSITION_BOOT_STAGE_STORAGE_PREPARE, + APP_COMPOSITION_BOOT_STAGE_WALL_CLOCK, APP_COMPOSITION_BOOT_STAGE_AUDIO_INIT, APP_COMPOSITION_BOOT_STAGE_BOOT_SOUND, APP_COMPOSITION_BOOT_STAGE_AUDIO_READY, @@ -83,6 +84,19 @@ static esp_err_t app_composition_run_plan_a_boot_sequence(void) return err; } + app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_WALL_CLOCK, + "wall_clock", + "control_plane_prepare_wall_clock"); + esp_err_t wall_clock_err = control_plane_prepare_wall_clock(); + app_composition_log_stage_result(APP_COMPOSITION_BOOT_STAGE_WALL_CLOCK, + "wall_clock", + wall_clock_err); + if (wall_clock_err != ESP_OK) { + ESP_LOGW(TAG, + "Local time zone setup failed, continue boot: %s", + esp_err_to_name(wall_clock_err)); + } + esp_err_t battery_guard_err = control_plane_battery_apply_boot_guard(); if (battery_guard_err != ESP_OK && battery_guard_err != ESP_ERR_NOT_SUPPORTED) { diff --git a/components/control_plane/include/control_plane.h b/components/control_plane/include/control_plane.h index b7d887f..36bb3ea 100644 --- a/components/control_plane/include/control_plane.h +++ b/components/control_plane/include/control_plane.h @@ -145,6 +145,9 @@ esp_err_t control_plane_battery_apply_boot_guard(void); */ esp_err_t control_plane_prepare_runtime_storage(void); +/** Apply the configured local time zone before any local time is rendered. */ +esp_err_t control_plane_prepare_wall_clock(void); + /** * @brief Start the control-plane owned light-standby coordinator. * diff --git a/components/control_plane/src/runtime/control_plane_connectivity_runtime.c b/components/control_plane/src/runtime/control_plane_connectivity_runtime.c index b40b8f3..a4fd794 100644 --- a/components/control_plane/src/runtime/control_plane_connectivity_runtime.c +++ b/components/control_plane/src/runtime/control_plane_connectivity_runtime.c @@ -28,6 +28,10 @@ #define CONFIG_TQ_BOOT_SOUND_FILE "" #endif +#ifndef CONFIG_TQ_TIME_POSIX_TZ +#define CONFIG_TQ_TIME_POSIX_TZ "CST-8" +#endif + #ifndef CONFIG_TQ_MINI_PROGRAM_PROVISIONING_ENABLE #define CONFIG_TQ_MINI_PROGRAM_PROVISIONING_ENABLE 0 #endif @@ -76,6 +80,11 @@ esp_err_t control_plane_prepare_runtime_storage(void) return domain_runtime_prepare_storage(); } +esp_err_t control_plane_prepare_wall_clock(void) +{ + return domain_runtime_time_set_timezone(CONFIG_TQ_TIME_POSIX_TZ); +} + static void control_plane_wifi_set_keep_awake(bool keep_awake) { domain_runtime_behavior_set_keep_awake(keep_awake); diff --git a/components/domain/include/domain.h b/components/domain/include/domain.h index ef5a9ae..90550fd 100644 --- a/components/domain/include/domain.h +++ b/components/domain/include/domain.h @@ -406,10 +406,12 @@ void domain_runtime_register_birth_profile_observer(domain_birth_profile_observe /** * @brief Wall-clock time synchronization, bridged to the platform SNTP - * primitive. `start` is idempotent and sets the process time zone - * (`posix_tz`, e.g. "CST-8"); `is_synced` reports whether the clock has - * been set. Call `start` after the network is up. + * primitive. `set_timezone` applies local-time conversion without + * network access. `start` is idempotent and also applies the process + * time zone (`posix_tz`, e.g. "CST-8"); `is_synced` reports whether the + * clock has been set. Call `start` after the network is up. */ +esp_err_t domain_runtime_time_set_timezone(const char *posix_tz); esp_err_t domain_runtime_time_sync_start(const char *sntp_server, const char *posix_tz); bool domain_runtime_time_is_synced(void); diff --git a/components/domain/src/runtime/domain_runtime_adapters.c b/components/domain/src/runtime/domain_runtime_adapters.c index bf7e7cc..14148a6 100644 --- a/components/domain/src/runtime/domain_runtime_adapters.c +++ b/components/domain/src/runtime/domain_runtime_adapters.c @@ -529,6 +529,11 @@ static esp_err_t domain_wifi_play_prompt_file_adapter(const char *path, void *us return hooks.play_prompt_file(path); } +esp_err_t domain_runtime_time_set_timezone(const char *posix_tz) +{ + return platform_time_set_timezone(posix_tz); +} + esp_err_t domain_runtime_time_sync_start(const char *sntp_server, const char *posix_tz) { return platform_time_sync_start(sntp_server, posix_tz); diff --git a/components/platform/include/platform.h b/components/platform/include/platform.h index 11181a4..2e43bc0 100644 --- a/components/platform/include/platform.h +++ b/components/platform/include/platform.h @@ -237,12 +237,15 @@ esp_err_t platform_storage_erase(const char *ns, const char *key); /** * @brief Wall-clock time synchronization (SNTP) primitives. * + * - `platform_time_set_timezone()` applies the process-local POSIX time zone + * without starting SNTP. Call it during boot before local time is rendered. * - `platform_time_sync_start()` is idempotent: it sets the process time zone * (`posix_tz`, e.g. "CST-8"; ignored when NULL/empty) on every call and * starts the SNTP client once. Must be called after the network is up. * - `platform_time_is_synced()` reports whether the system clock has advanced * past a sane epoch lower bound (i.e. SNTP has set the time at least once). */ +esp_err_t platform_time_set_timezone(const char *posix_tz); esp_err_t platform_time_sync_start(const char *sntp_server, const char *posix_tz); bool platform_time_is_synced(void); diff --git a/components/platform/src/runtime/platform_time.c b/components/platform/src/runtime/platform_time.c index 8882603..1a5d712 100644 --- a/components/platform/src/runtime/platform_time.c +++ b/components/platform/src/runtime/platform_time.c @@ -23,11 +23,27 @@ static const char *TAG = "platform_time"; static bool s_sntp_started; static portMUX_TYPE s_time_lock = portMUX_INITIALIZER_UNLOCKED; +esp_err_t platform_time_set_timezone(const char *posix_tz) +{ + if (posix_tz == NULL || posix_tz[0] == '\0') { + return ESP_ERR_INVALID_ARG; + } + if (setenv("TZ", posix_tz, 1) != 0) { + ESP_LOGE(TAG, "Set time zone failed (tz=%s)", posix_tz); + return ESP_FAIL; + } + tzset(); + ESP_LOGI(TAG, "Local time zone applied (tz=%s)", posix_tz); + return ESP_OK; +} + esp_err_t platform_time_sync_start(const char *sntp_server, const char *posix_tz) { if (posix_tz != NULL && posix_tz[0] != '\0') { - setenv("TZ", posix_tz, 1); - tzset(); + esp_err_t timezone_err = platform_time_set_timezone(posix_tz); + if (timezone_err != ESP_OK) { + return timezone_err; + } } portENTER_CRITICAL(&s_time_lock);