forked from xiaozhi/xiaozhi-esp32
fix network error
This commit is contained in:
@@ -51,69 +51,88 @@ void Application::CheckNewVersion() {
|
|||||||
// Check if there is a new firmware version available
|
// Check if there is a new firmware version available
|
||||||
ota_.SetPostData(board.GetJson());
|
ota_.SetPostData(board.GetJson());
|
||||||
|
|
||||||
|
const int MAX_RETRY = 10;
|
||||||
|
int retry_count = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (ota_.CheckVersion()) {
|
if (!ota_.CheckVersion()) {
|
||||||
if (ota_.HasNewVersion()) {
|
retry_count++;
|
||||||
Alert("OTA 升级", "正在升级系统", "happy", std::string_view(p3_upgrade_start, p3_upgrade_end - p3_upgrade_start));
|
if (retry_count >= MAX_RETRY) {
|
||||||
// Wait for the chat state to be idle
|
ESP_LOGE(TAG, "版本检查失败次数过多,退出检查");
|
||||||
do {
|
return;
|
||||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
|
||||||
} while (GetDeviceState() != kDeviceStateIdle);
|
|
||||||
|
|
||||||
// Use main task to do the upgrade, not cancelable
|
|
||||||
Schedule([this, &board, display]() {
|
|
||||||
SetDeviceState(kDeviceStateUpgrading);
|
|
||||||
|
|
||||||
display->SetIcon(FONT_AWESOME_DOWNLOAD);
|
|
||||||
display->SetChatMessage("system", "新版本 " + ota_.GetFirmwareVersion());
|
|
||||||
|
|
||||||
board.SetPowerSaveMode(false);
|
|
||||||
#if CONFIG_USE_AUDIO_PROCESSING
|
|
||||||
wake_word_detect_.StopDetection();
|
|
||||||
#endif
|
|
||||||
// 预先关闭音频输出,避免升级过程有音频操作
|
|
||||||
auto codec = board.GetAudioCodec();
|
|
||||||
codec->EnableInput(false);
|
|
||||||
codec->EnableOutput(false);
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
|
||||||
audio_decode_queue_.clear();
|
|
||||||
}
|
|
||||||
background_task_->WaitForCompletion();
|
|
||||||
delete background_task_;
|
|
||||||
background_task_ = nullptr;
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
|
|
||||||
ota_.StartUpgrade([display](int progress, size_t speed) {
|
|
||||||
char buffer[64];
|
|
||||||
snprintf(buffer, sizeof(buffer), "%d%% %zuKB/s", progress, speed / 1024);
|
|
||||||
display->SetChatMessage("system", buffer);
|
|
||||||
});
|
|
||||||
|
|
||||||
// If upgrade success, the device will reboot and never reach here
|
|
||||||
display->SetStatus("更新失败");
|
|
||||||
ESP_LOGI(TAG, "Firmware upgrade failed...");
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
|
||||||
Reboot();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ota_.MarkCurrentVersionValid();
|
|
||||||
display->ShowNotification("版本 " + ota_.GetCurrentVersion());
|
|
||||||
|
|
||||||
// Check if the activation code is valid
|
|
||||||
if (ota_.HasActivationCode()) {
|
|
||||||
SetDeviceState(kDeviceStateActivating);
|
|
||||||
ShowActivationCode();
|
|
||||||
} else {
|
|
||||||
SetDeviceState(kDeviceStateIdle);
|
|
||||||
display->SetChatMessage("system", "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ESP_LOGW(TAG, "版本检查失败,%d秒后重试 (%d/%d)", 60, retry_count, MAX_RETRY);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(60000));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
retry_count = 0;
|
||||||
|
|
||||||
|
if (ota_.HasNewVersion()) {
|
||||||
|
Alert("OTA 升级", "正在升级系统", "happy", std::string_view(p3_upgrade_start, p3_upgrade_end - p3_upgrade_start));
|
||||||
|
// Wait for the chat state to be idle
|
||||||
|
do {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||||
|
} while (GetDeviceState() != kDeviceStateIdle);
|
||||||
|
|
||||||
|
// Use main task to do the upgrade, not cancelable
|
||||||
|
Schedule([this, display]() {
|
||||||
|
SetDeviceState(kDeviceStateUpgrading);
|
||||||
|
|
||||||
|
display->SetIcon(FONT_AWESOME_DOWNLOAD);
|
||||||
|
display->SetChatMessage("system", "新版本 " + ota_.GetFirmwareVersion());
|
||||||
|
|
||||||
|
auto& board = Board::GetInstance();
|
||||||
|
board.SetPowerSaveMode(false);
|
||||||
|
#if CONFIG_USE_AUDIO_PROCESSING
|
||||||
|
wake_word_detect_.StopDetection();
|
||||||
|
#endif
|
||||||
|
// 预先关闭音频输出,避免升级过程有音频操作
|
||||||
|
auto codec = board.GetAudioCodec();
|
||||||
|
codec->EnableInput(false);
|
||||||
|
codec->EnableOutput(false);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
audio_decode_queue_.clear();
|
||||||
|
}
|
||||||
|
background_task_->WaitForCompletion();
|
||||||
|
delete background_task_;
|
||||||
|
background_task_ = nullptr;
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
ota_.StartUpgrade([display](int progress, size_t speed) {
|
||||||
|
char buffer[64];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d%% %zuKB/s", progress, speed / 1024);
|
||||||
|
display->SetChatMessage("system", buffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If upgrade success, the device will reboot and never reach here
|
||||||
|
display->SetStatus("更新失败");
|
||||||
|
ESP_LOGI(TAG, "Firmware upgrade failed...");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||||
|
Reboot();
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check again in 60 seconds
|
// No new version, mark the current version as valid
|
||||||
vTaskDelay(pdMS_TO_TICKS(60000));
|
ota_.MarkCurrentVersionValid();
|
||||||
|
display->ShowNotification("版本 " + ota_.GetCurrentVersion());
|
||||||
|
|
||||||
|
if (ota_.HasActivationCode()) {
|
||||||
|
// Activation code is valid
|
||||||
|
SetDeviceState(kDeviceStateActivating);
|
||||||
|
ShowActivationCode();
|
||||||
|
// Check again in 60 seconds
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(60000));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDeviceState(kDeviceStateIdle);
|
||||||
|
display->SetChatMessage("system", "");
|
||||||
|
|
||||||
|
// Exit the loop if upgrade or idle
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +218,7 @@ void Application::ToggleChatState() {
|
|||||||
if (device_state_ == kDeviceStateIdle) {
|
if (device_state_ == kDeviceStateIdle) {
|
||||||
SetDeviceState(kDeviceStateConnecting);
|
SetDeviceState(kDeviceStateConnecting);
|
||||||
if (!protocol_->OpenAudioChannel()) {
|
if (!protocol_->OpenAudioChannel()) {
|
||||||
Alert("ERROR", "无法建立音频通道");
|
Alert("ERROR", "无法建立音频通道", "sad");
|
||||||
SetDeviceState(kDeviceStateIdle);
|
SetDeviceState(kDeviceStateIdle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -233,7 +252,7 @@ void Application::StartListening() {
|
|||||||
SetDeviceState(kDeviceStateConnecting);
|
SetDeviceState(kDeviceStateConnecting);
|
||||||
if (!protocol_->OpenAudioChannel()) {
|
if (!protocol_->OpenAudioChannel()) {
|
||||||
SetDeviceState(kDeviceStateIdle);
|
SetDeviceState(kDeviceStateIdle);
|
||||||
Alert("ERROR", "无法建立音频通道");
|
Alert("ERROR", "无法建立音频通道", "sad");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,7 +333,7 @@ void Application::Start() {
|
|||||||
protocol_ = std::make_unique<MqttProtocol>();
|
protocol_ = std::make_unique<MqttProtocol>();
|
||||||
#endif
|
#endif
|
||||||
protocol_->OnNetworkError([this](const std::string& message) {
|
protocol_->OnNetworkError([this](const std::string& message) {
|
||||||
Alert("ERROR", message);
|
Alert("ERROR", message, "sad");
|
||||||
});
|
});
|
||||||
protocol_->OnIncomingAudio([this](std::vector<uint8_t>&& data) {
|
protocol_->OnIncomingAudio([this](std::vector<uint8_t>&& data) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
@@ -401,6 +420,7 @@ void Application::Start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
protocol_->Start();
|
||||||
|
|
||||||
// Check for new firmware version or get the MQTT broker address
|
// Check for new firmware version or get the MQTT broker address
|
||||||
ota_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
ota_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
MqttProtocol::MqttProtocol() {
|
MqttProtocol::MqttProtocol() {
|
||||||
event_group_handle_ = xEventGroupCreate();
|
event_group_handle_ = xEventGroupCreate();
|
||||||
|
|
||||||
StartMqttClient();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttProtocol::~MqttProtocol() {
|
MqttProtocol::~MqttProtocol() {
|
||||||
@@ -28,6 +26,10 @@ MqttProtocol::~MqttProtocol() {
|
|||||||
vEventGroupDelete(event_group_handle_);
|
vEventGroupDelete(event_group_handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MqttProtocol::Start() {
|
||||||
|
StartMqttClient();
|
||||||
|
}
|
||||||
|
|
||||||
bool MqttProtocol::StartMqttClient() {
|
bool MqttProtocol::StartMqttClient() {
|
||||||
if (mqtt_ != nullptr) {
|
if (mqtt_ != nullptr) {
|
||||||
ESP_LOGW(TAG, "Mqtt client already started");
|
ESP_LOGW(TAG, "Mqtt client already started");
|
||||||
@@ -98,7 +100,12 @@ void MqttProtocol::SendText(const std::string& text) {
|
|||||||
if (publish_topic_.empty()) {
|
if (publish_topic_.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mqtt_->Publish(publish_topic_, text);
|
if (!mqtt_->Publish(publish_topic_, text)) {
|
||||||
|
ESP_LOGE(TAG, "Failed to publish message");
|
||||||
|
if (on_network_error_ != nullptr) {
|
||||||
|
on_network_error_("发送失败,请检查网络");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttProtocol::SendAudio(const std::vector<uint8_t>& data) {
|
void MqttProtocol::SendAudio(const std::vector<uint8_t>& data) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public:
|
|||||||
MqttProtocol();
|
MqttProtocol();
|
||||||
~MqttProtocol();
|
~MqttProtocol();
|
||||||
|
|
||||||
|
void Start() override;
|
||||||
void SendAudio(const std::vector<uint8_t>& data) override;
|
void SendAudio(const std::vector<uint8_t>& data) override;
|
||||||
bool OpenAudioChannel() override;
|
bool OpenAudioChannel() override;
|
||||||
void CloseAudioChannel() override;
|
void CloseAudioChannel() override;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public:
|
|||||||
void OnAudioChannelClosed(std::function<void()> callback);
|
void OnAudioChannelClosed(std::function<void()> callback);
|
||||||
void OnNetworkError(std::function<void(const std::string& message)> callback);
|
void OnNetworkError(std::function<void(const std::string& message)> callback);
|
||||||
|
|
||||||
|
virtual void Start() = 0;
|
||||||
virtual bool OpenAudioChannel() = 0;
|
virtual bool OpenAudioChannel() = 0;
|
||||||
virtual void CloseAudioChannel() = 0;
|
virtual void CloseAudioChannel() = 0;
|
||||||
virtual bool IsAudioChannelOpened() const = 0;
|
virtual bool IsAudioChannelOpened() const = 0;
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ WebsocketProtocol::~WebsocketProtocol() {
|
|||||||
vEventGroupDelete(event_group_handle_);
|
vEventGroupDelete(event_group_handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebsocketProtocol::Start() {
|
||||||
|
}
|
||||||
|
|
||||||
void WebsocketProtocol::SendAudio(const std::vector<uint8_t>& data) {
|
void WebsocketProtocol::SendAudio(const std::vector<uint8_t>& data) {
|
||||||
if (websocket_ == nullptr) {
|
if (websocket_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public:
|
|||||||
WebsocketProtocol();
|
WebsocketProtocol();
|
||||||
~WebsocketProtocol();
|
~WebsocketProtocol();
|
||||||
|
|
||||||
|
void Start() override;
|
||||||
void SendAudio(const std::vector<uint8_t>& data) override;
|
void SendAudio(const std::vector<uint8_t>& data) override;
|
||||||
bool OpenAudioChannel() override;
|
bool OpenAudioChannel() override;
|
||||||
void CloseAudioChannel() override;
|
void CloseAudioChannel() override;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ ESP_TASK_WDT_TIMEOUT_S=10
|
|||||||
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
||||||
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
|
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
|
||||||
|
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
|
||||||
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
||||||
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
|
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
|
||||||
CONFIG_ESP_WIFI_IRAM_OPT=n
|
CONFIG_ESP_WIFI_IRAM_OPT=n
|
||||||
|
|||||||
Reference in New Issue
Block a user