diff --git a/main/Application.cc b/main/Application.cc index 0a3d9e54..a085260e 100644 --- a/main/Application.cc +++ b/main/Application.cc @@ -1,6 +1,5 @@ #include "Application.h" #include "BuiltinLed.h" -#include "WifiStation.h" #include #include "esp_log.h" #include "model_path.h" @@ -31,6 +30,8 @@ Application::Application() { if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) { opus_resampler_.Configure(opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE); } + + firmware_upgrade_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL); } Application::~Application() { @@ -67,6 +68,24 @@ Application::~Application() { vEventGroupDelete(event_group_); } +void Application::CheckNewVersion() { + // Check if there is a new firmware version available + firmware_upgrade_.CheckVersion(); + if (firmware_upgrade_.HasNewVersion()) { + // Wait for the chat state to be idle + while (chat_state_ != kChatStateIdle) { + vTaskDelay(100); + } + SetChatState(kChatStateUpgrading); + firmware_upgrade_.StartUpgrade(); + // If upgrade success, the device will reboot and never reach here + ESP_LOGI(TAG, "Firmware upgrade failed..."); + SetChatState(kChatStateIdle); + } else { + firmware_upgrade_.MarkValid(); + } +} + void Application::Start() { // Initialize the audio device audio_device_.Start(CONFIG_AUDIO_INPUT_SAMPLE_RATE, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE); @@ -96,31 +115,21 @@ void Application::Start() { app->AudioDecodeTask(); }, "opus_decode", opus_stack_size, this, 1, audio_decode_task_stack_, &audio_decode_task_buffer_); - auto& builtin_led = BuiltinLed::GetInstance(); - // Blink the LED to indicate the device is connecting - builtin_led.SetBlue(); - builtin_led.BlinkOnce(); - WifiStation::GetInstance().Start(); - - // Check if there is a new firmware version available - firmware_upgrade_.CheckVersion(); - if (firmware_upgrade_.HasNewVersion()) { - builtin_led.TurnOn(); - firmware_upgrade_.StartUpgrade(); - // If upgrade success, the device will reboot and never reach here - ESP_LOGI(TAG, "Firmware upgrade failed..."); - builtin_led.TurnOff(); - } else { - firmware_upgrade_.MarkValid(); - } - StartCommunication(); StartDetection(); // Blink the LED to indicate the device is running + auto& builtin_led = BuiltinLed::GetInstance(); builtin_led.SetGreen(); builtin_led.BlinkOnce(); xEventGroupSetBits(event_group_, DETECTION_RUNNING); + + // Launch a task to check for new firmware version + xTaskCreate([](void* arg) { + Application* app = (Application*)arg; + app->CheckNewVersion(); + vTaskDelete(NULL); + }, "check_new_version", 4096 * 2, this, 1, NULL); } void Application::SetChatState(ChatState state) { @@ -156,6 +165,11 @@ void Application::SetChatState(ChatState state) { builtin_led.SetRed(); builtin_led.TurnOn(); break; + case kChatStateUpgrading: + ESP_LOGI(TAG, "Chat state: upgrading"); + builtin_led.SetGreen(); + builtin_led.StartContinuousBlink(100); + break; } const char* state_str[] = { "idle", "connecting", "listening", "speaking", "wake_word_detected", "testing", "unknown" }; @@ -175,7 +189,7 @@ void Application::StartCommunication() { afe_config_t afe_config = { .aec_init = false, .se_init = true, - .vad_init = false, + .vad_init = true, .wakenet_init = false, .voice_communication_init = true, .voice_communication_agc_init = true, @@ -406,7 +420,7 @@ void Application::AudioDetectionTask() { continue; } - if (res->wakeup_state == WAKENET_DETECTED) { + if (chat_state_ == kChatStateIdle && res->wakeup_state == WAKENET_DETECTED) { xEventGroupClearBits(event_group_, DETECTION_RUNNING); SetChatState(kChatStateConnecting); diff --git a/main/Application.h b/main/Application.h index 213b2537..c7f778e4 100644 --- a/main/Application.h +++ b/main/Application.h @@ -28,7 +28,8 @@ enum ChatState { kChatStateListening, kChatStateSpeaking, kChatStateWakeWordDetected, - kChatStateTesting + kChatStateTesting, + kChatStateUpgrading }; class Application { @@ -96,6 +97,7 @@ private: void SendWakeWordData(); void CheckTestButton(); void PlayTestAudio(); + void CheckNewVersion(); void AudioFeedTask(); void AudioDetectionTask(); diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 59fadb88..d459b449 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -1,14 +1,20 @@ menu "Xiaozhi Assistant" +config OTA_VERSION_URL + string "OTA Version URL" + default "https://api.tenclass.net/xiaozhi/ota/" + help + The application will access this URL to check for updates. + config WEBSOCKET_URL string "Websocket URL" - default "wss://" + default "wss://api.tenclass.net/xiaozhi/v1/" help Communication with the server through websocket after wake up. config WEBSOCKET_ACCESS_TOKEN string "Websocket Access Token" - default "" + default "test-token" help Access token for websocket communication. diff --git a/main/idf_component.yml b/main/idf_component.yml index 69ff7ff0..61364426 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,8 +1,8 @@ ## IDF Component Manager Manifest File dependencies: - 78/esp-builtin-led: "^1.0.0" - 78/esp-wifi-connect: "^1.0.0" - 78/esp-ota: "^1.0.0" + 78/esp-builtin-led: "^1.0.1" + 78/esp-wifi-connect: "^1.0.1" + 78/esp-ota: "^1.0.1" 78/esp-websocket: "^1.0.0" 78/esp-opus-encoder: "^1.0.1" espressif/esp-sr: "^1.9.0" diff --git a/main/main.cc b/main/main.cc index 0e481e2e..1fa6de35 100755 --- a/main/main.cc +++ b/main/main.cc @@ -11,6 +11,7 @@ #include "SystemInfo.h" #include "SystemReset.h" #include "BuiltinLed.h" +#include "WifiStation.h" #define TAG "main" #define STATS_TICKS pdMS_TO_TICKS(1000) @@ -32,21 +33,19 @@ extern "C" void app_main(void) } ESP_ERROR_CHECK(ret); - // Get the WiFi configuration - nvs_handle_t nvs_handle; - ret = nvs_open("wifi", NVS_READONLY, &nvs_handle); - - // If the WiFi configuration is not found, launch the WiFi configuration AP - if (ret != ESP_OK) { - auto& builtin_led = BuiltinLed::GetInstance(); + // Try to connect to WiFi, if failed, launch the WiFi configuration AP + auto& builtin_led = BuiltinLed::GetInstance(); + auto& wifi_station = WifiStation::GetInstance(); + builtin_led.SetBlue(); + builtin_led.StartContinuousBlink(100); + wifi_station.Start(); + if (!wifi_station.IsConnected()) { builtin_led.SetBlue(); builtin_led.Blink(1000, 500); - WifiConfigurationAp::GetInstance().Start("Xiaozhi"); return; } - nvs_close(nvs_handle); - + // Otherwise, launch the application Application::GetInstance().Start();