From a23a88cc5d2bd3c3db4331c821489f15b0bba18a Mon Sep 17 00:00:00 2001 From: Terrence Date: Mon, 24 Feb 2025 14:41:34 +0800 Subject: [PATCH] Bump to 1.3.0 --- CMakeLists.txt | 2 +- main/application.cc | 44 +++++++++++++++++++++- main/application.h | 6 ++- main/assets/en-US/language.json | 2 +- main/boards/kevin-box-2/kevin_box_board.cc | 2 +- main/boards/tudouzi/kevin_box_board.cc | 2 +- main/display/display.cc | 4 +- main/led/circular_strip.cc | 2 +- main/led/led.cc | 2 +- main/led/single_led.cc | 2 +- main/main.cc | 10 +---- main/ota.cc | 23 +++++++++++ main/ota.h | 2 + main/protocols/mqtt_protocol.cc | 3 ++ 14 files changed, 84 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba9a82f6..897bc4f4 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -set(PROJECT_VER "1.2.2") +set(PROJECT_VER "1.3.0") # Add this line to disable the specific warning add_compile_options(-Wno-missing-field-initializers) diff --git a/main/application.cc b/main/application.cc index c69e2202..98d0818b 100644 --- a/main/application.cc +++ b/main/application.cc @@ -36,9 +36,24 @@ static const char* const STATE_STRINGS[] = { Application::Application() { event_group_ = xEventGroupCreate(); background_task_ = new BackgroundTask(4096 * 8); + + esp_timer_create_args_t clock_timer_args = { + .callback = [](void* arg) { + Application* app = (Application*)arg; + app->OnClockTimer(); + }, + .arg = this, + .dispatch_method = ESP_TIMER_TASK, + .name = "clock_timer" + }; + esp_timer_create(&clock_timer_args, &clock_timer_handle_); } Application::~Application() { + if (clock_timer_handle_ != nullptr) { + esp_timer_stop(clock_timer_handle_); + esp_timer_delete(clock_timer_handle_); + } if (background_task_ != nullptr) { delete background_task_; } @@ -225,7 +240,6 @@ void Application::ToggleChatState() { if (device_state_ == kDeviceStateIdle) { SetDeviceState(kDeviceStateConnecting); if (!protocol_->OpenAudioChannel()) { - Alert(Lang::Strings::ERROR, Lang::Strings::UNABLE_TO_ESTABLISH_AUDIO_CHANNEL, "sad"); SetDeviceState(kDeviceStateIdle); return; } @@ -259,7 +273,6 @@ void Application::StartListening() { SetDeviceState(kDeviceStateConnecting); if (!protocol_->OpenAudioChannel()) { SetDeviceState(kDeviceStateIdle); - Alert(Lang::Strings::ERROR, Lang::Strings::UNABLE_TO_ESTABLISH_AUDIO_CHANNEL, "sad"); return; } } @@ -506,6 +519,33 @@ void Application::Start() { #endif SetDeviceState(kDeviceStateIdle); + esp_timer_start_periodic(clock_timer_handle_, 1000000); +} + +void Application::OnClockTimer() { + static int count = 0; + count++; + + // Print the debug info every 10 seconds + if (count % 10 == 0) { + // SystemInfo::PrintRealTimeStats(pdMS_TO_TICKS(1000)); + int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + int min_free_sram = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL); + ESP_LOGI(TAG, "Free internal: %u minimal internal: %u", free_sram, min_free_sram); + + // If we have synchronized server time, set the status to clock "HH:MM" if the device is idle + if (ota_.HasServerTime()) { + Schedule([this]() { + if (device_state_ == kDeviceStateIdle) { + // Set status to clock "HH:MM" + time_t now = time(NULL); + char time_str[64]; + strftime(time_str, sizeof(time_str), "%H:%M ", localtime(&now)); + Board::GetInstance().GetDisplay()->SetStatus(time_str); + } + }); + } + } } void Application::Schedule(std::function callback) { diff --git a/main/application.h b/main/application.h index 03135d22..359671f5 100644 --- a/main/application.h +++ b/main/application.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -77,7 +78,8 @@ private: std::mutex mutex_; std::list> main_tasks_; std::unique_ptr protocol_; - EventGroupHandle_t event_group_; + EventGroupHandle_t event_group_ = nullptr; + esp_timer_handle_t clock_timer_handle_ = nullptr; volatile DeviceState device_state_ = kDeviceStateUnknown; bool keep_listening_ = false; bool aborted_ = false; @@ -104,7 +106,7 @@ private: void SetDecodeSampleRate(int sample_rate); void CheckNewVersion(); void ShowActivationCode(); - + void OnClockTimer(); void PlayLocalFile(const char* data, size_t size); }; diff --git a/main/assets/en-US/language.json b/main/assets/en-US/language.json index 42dd45c7..bef2eb52 100644 --- a/main/assets/en-US/language.json +++ b/main/assets/en-US/language.json @@ -22,7 +22,7 @@ "LISTENING": "Listening...", "SPEAKING": "Speaking...", - "UNABLE_TO_CONNECT_TO_SERVICE": "Unable to connect to service", + "UNABLE_TO_CONNECT_TO_SERVICE": "Unable to connect to service, please try again later", "WAITING_FOR_RESPONSE_TIMEOUT": "Waiting for response timeout", "SENDING_FAILED_PLEASE_CHECK_THE_NETWORK": "Sending failed, please check the network", diff --git a/main/boards/kevin-box-2/kevin_box_board.cc b/main/boards/kevin-box-2/kevin_box_board.cc index 1ff3dcd3..b5404397 100644 --- a/main/boards/kevin-box-2/kevin_box_board.cc +++ b/main/boards/kevin-box-2/kevin_box_board.cc @@ -37,7 +37,7 @@ private: }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Power Save Timer", + .name = "power_save_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(&power_save_timer_args, &power_save_timer_)); diff --git a/main/boards/tudouzi/kevin_box_board.cc b/main/boards/tudouzi/kevin_box_board.cc index 339c60a0..0744c2a7 100644 --- a/main/boards/tudouzi/kevin_box_board.cc +++ b/main/boards/tudouzi/kevin_box_board.cc @@ -38,7 +38,7 @@ private: }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Power Save Timer", + .name = "power_save_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(&power_save_timer_args, &power_save_timer_)); diff --git a/main/display/display.cc b/main/display/display.cc index 17fd9d0f..b2e3d77c 100644 --- a/main/display/display.cc +++ b/main/display/display.cc @@ -27,7 +27,7 @@ Display::Display() { }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Notification Timer", + .name = "notification_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(¬ification_timer_args, ¬ification_timer_)); @@ -40,7 +40,7 @@ Display::Display() { }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Update Display Timer", + .name = "update_display_timer", .skip_unhandled_events = true, }; ESP_ERROR_CHECK(esp_timer_create(&update_display_timer_args, &update_timer_)); diff --git a/main/led/circular_strip.cc b/main/led/circular_strip.cc index 1712583c..53eafa92 100644 --- a/main/led/circular_strip.cc +++ b/main/led/circular_strip.cc @@ -38,7 +38,7 @@ CircularStrip::CircularStrip(gpio_num_t gpio, uint8_t max_leds) : max_leds_(max_ }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Strip Timer", + .name = "strip_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(&strip_timer_args, &strip_timer_)); diff --git a/main/led/led.cc b/main/led/led.cc index bc86ab1f..718a82c5 100644 --- a/main/led/led.cc +++ b/main/led/led.cc @@ -22,7 +22,7 @@ Led::Led(gpio_num_t gpio, uint8_t max_leds) { }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Led Strip Timer", + .name = "led_strip_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(&led_strip_timer_args, &led_strip_timer_)); diff --git a/main/led/single_led.cc b/main/led/single_led.cc index 20a313cb..f02d5981 100644 --- a/main/led/single_led.cc +++ b/main/led/single_led.cc @@ -34,7 +34,7 @@ SingleLed::SingleLed(gpio_num_t gpio) { }, .arg = this, .dispatch_method = ESP_TIMER_TASK, - .name = "Blink Timer", + .name = "blink_timer", .skip_unhandled_events = false, }; ESP_ERROR_CHECK(esp_timer_create(&blink_timer_args, &blink_timer_)); diff --git a/main/main.cc b/main/main.cc index 6bc176cb..64b122a9 100755 --- a/main/main.cc +++ b/main/main.cc @@ -26,13 +26,5 @@ extern "C" void app_main(void) // Launch the application Application::GetInstance().Start(); - - // Dump CPU usage every 10 second - while (true) { - vTaskDelay(10000 / portTICK_PERIOD_MS); - // SystemInfo::PrintRealTimeStats(pdMS_TO_TICKS(1000)); - int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); - int min_free_sram = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL); - ESP_LOGI(TAG, "Free internal: %u minimal internal: %u", free_sram, min_free_sram); - } + // The main thread will exit and release the stack memory } diff --git a/main/ota.cc b/main/ota.cc index 2b05f4de..d6fa8496 100644 --- a/main/ota.cc +++ b/main/ota.cc @@ -100,6 +100,29 @@ bool Ota::CheckVersion() { has_mqtt_config_ = true; } + has_server_time_ = false; + cJSON *server_time = cJSON_GetObjectItem(root, "server_time"); + if (server_time != NULL) { + cJSON *timestamp = cJSON_GetObjectItem(server_time, "timestamp"); + cJSON *timezone_offset = cJSON_GetObjectItem(server_time, "timezone_offset"); + + if (timestamp != NULL) { + // 设置系统时间 + struct timeval tv; + double ts = timestamp->valuedouble; + + // 如果有时区偏移,计算本地时间 + if (timezone_offset != NULL) { + ts += (timezone_offset->valueint * 60 * 1000); // 转换分钟为毫秒 + } + + tv.tv_sec = (time_t)(ts / 1000); // 转换毫秒为秒 + tv.tv_usec = (suseconds_t)((long long)ts % 1000) * 1000; // 剩余的毫秒转换为微秒 + settimeofday(&tv, NULL); + has_server_time_ = true; + } + } + cJSON *firmware = cJSON_GetObjectItem(root, "firmware"); if (firmware == NULL) { ESP_LOGE(TAG, "Failed to get firmware object"); diff --git a/main/ota.h b/main/ota.h index 96f6aa91..7f7507ae 100644 --- a/main/ota.h +++ b/main/ota.h @@ -17,6 +17,7 @@ public: bool HasNewVersion() { return has_new_version_; } bool HasMqttConfig() { return has_mqtt_config_; } bool HasActivationCode() { return has_activation_code_; } + bool HasServerTime() { return has_server_time_; } void StartUpgrade(std::function callback); void MarkCurrentVersionValid(); @@ -31,6 +32,7 @@ private: std::string activation_code_; bool has_new_version_ = false; bool has_mqtt_config_ = false; + bool has_server_time_ = false; bool has_activation_code_ = false; std::string current_version_; std::string firmware_version_; diff --git a/main/protocols/mqtt_protocol.cc b/main/protocols/mqtt_protocol.cc index caef82db..6d675256 100644 --- a/main/protocols/mqtt_protocol.cc +++ b/main/protocols/mqtt_protocol.cc @@ -46,6 +46,9 @@ bool MqttProtocol::StartMqttClient() { if (endpoint_.empty()) { ESP_LOGE(TAG, "MQTT endpoint is not specified"); + if (on_network_error_ != nullptr) { + on_network_error_(Lang::Strings::UNABLE_TO_CONNECT_TO_SERVICE); + } return false; }