7
7
#include " websocket_protocol.h"
8
8
#include " assets/lang_config.h"
9
9
#include " mcp_server.h"
10
+ #include " assets.h"
11
+ #include " settings.h"
10
12
11
13
#include < cstring>
12
14
#include < esp_log.h>
@@ -67,6 +69,65 @@ Application::~Application() {
67
69
vEventGroupDelete (event_group_);
68
70
}
69
71
72
+ void Application::CheckAssetsVersion () {
73
+ auto & board = Board::GetInstance ();
74
+ auto display = board.GetDisplay ();
75
+ auto assets = board.GetAssets ();
76
+ if (!assets) {
77
+ ESP_LOGE (TAG, " Assets is not set for board %s" , BOARD_NAME);
78
+ return ;
79
+ }
80
+
81
+ if (!assets->partition_valid ()) {
82
+ ESP_LOGE (TAG, " Assets partition is not valid for board %s" , BOARD_NAME);
83
+ return ;
84
+ }
85
+
86
+ Settings settings (" assets" , true );
87
+ // Check if there is a new assets need to be downloaded
88
+ std::string download_url = settings.GetString (" download_url" );
89
+ if (!download_url.empty ()) {
90
+ settings.EraseKey (" download_url" );
91
+ }
92
+ if (download_url.empty () && !assets->checksum_valid ()) {
93
+ download_url = assets->default_assets_url ();
94
+ }
95
+
96
+ if (!download_url.empty ()) {
97
+ char message[256 ];
98
+ snprintf (message, sizeof (message), Lang::Strings::FOUND_NEW_ASSETS, download_url.c_str ());
99
+ Alert (Lang::Strings::LOADING_ASSETS, message, " cloud_arrow_down" , Lang::Sounds::OGG_UPGRADE);
100
+
101
+ // Wait for the audio service to be idle for 3 seconds
102
+ vTaskDelay (pdMS_TO_TICKS (3000 ));
103
+ SetDeviceState (kDeviceStateUpgrading );
104
+ board.SetPowerSaveMode (false );
105
+ display->SetChatMessage (" system" , Lang::Strings::PLEASE_WAIT);
106
+
107
+ bool success = assets->Download (download_url, [display](int progress, size_t speed) -> void {
108
+ std::thread ([display, progress, speed]() {
109
+ char buffer[32 ];
110
+ snprintf (buffer, sizeof (buffer), " %d%% %uKB/s" , progress, speed / 1024 );
111
+ display->SetChatMessage (" system" , buffer);
112
+ }).detach ();
113
+ });
114
+
115
+ board.SetPowerSaveMode (true );
116
+ vTaskDelay (pdMS_TO_TICKS (1000 ));
117
+
118
+ if (!success) {
119
+ Alert (Lang::Strings::ERROR, Lang::Strings::DOWNLOAD_ASSETS_FAILED, " circle_xmark" , Lang::Sounds::OGG_EXCLAMATION);
120
+ vTaskDelay (pdMS_TO_TICKS (2000 ));
121
+ return ;
122
+ }
123
+ }
124
+
125
+ // Apply assets
126
+ assets->Apply ();
127
+ display->SetChatMessage (" system" , " " );
128
+ display->SetEmotion (" microchip_ai" );
129
+ }
130
+
70
131
void Application::CheckNewVersion (Ota& ota) {
71
132
const int MAX_RETRY = 10 ;
72
133
int retry_count = 0 ;
@@ -358,6 +419,9 @@ void Application::Start() {
358
419
// Update the status bar immediately to show the network state
359
420
display->UpdateStatusBar (true );
360
421
422
+ // Check for new assets version
423
+ CheckAssetsVersion ();
424
+
361
425
// Check for new firmware version or get the MQTT broker address
362
426
Ota ota;
363
427
CheckNewVersion (ota);
@@ -366,7 +430,9 @@ void Application::Start() {
366
430
display->SetStatus (Lang::Strings::LOADING_PROTOCOL);
367
431
368
432
// Add MCP common tools before initializing the protocol
369
- McpServer::GetInstance ().AddCommonTools ();
433
+ auto & mcp_server = McpServer::GetInstance ();
434
+ mcp_server.AddCommonTools ();
435
+ mcp_server.AddUserOnlyTools ();
370
436
371
437
if (ota.HasMqttConfig ()) {
372
438
protocol_ = std::make_unique<MqttProtocol>();
@@ -496,7 +562,6 @@ void Application::Start() {
496
562
});
497
563
bool protocol_started = protocol_->Start ();
498
564
499
- // Print heap stats
500
565
SystemInfo::PrintHeapStats ();
501
566
SetDeviceState (kDeviceStateIdle );
502
567
@@ -541,7 +606,7 @@ void Application::MainEventLoop() {
541
606
542
607
if (bits & MAIN_EVENT_SEND_AUDIO) {
543
608
while (auto packet = audio_service_.PopPacketFromSendQueue ()) {
544
- if (!protocol_->SendAudio (std::move (packet))) {
609
+ if (protocol_ && !protocol_->SendAudio (std::move (packet))) {
545
610
break ;
546
611
}
547
612
}
@@ -623,7 +688,9 @@ void Application::OnWakeWordDetected() {
623
688
void Application::AbortSpeaking (AbortReason reason) {
624
689
ESP_LOGI (TAG, " Abort speaking" );
625
690
aborted_ = true ;
626
- protocol_->SendAbortSpeaking (reason);
691
+ if (protocol_) {
692
+ protocol_->SendAbortSpeaking (reason);
693
+ }
627
694
}
628
695
629
696
void Application::SetListeningMode (ListeningMode mode) {
@@ -695,6 +762,12 @@ void Application::SetDeviceState(DeviceState state) {
695
762
696
763
void Application::Reboot () {
697
764
ESP_LOGI (TAG, " Rebooting..." );
765
+ // Disconnect the audio channel
766
+ if (protocol_ && protocol_->IsAudioChannelOpened ()) {
767
+ protocol_->CloseAudioChannel ();
768
+ }
769
+ protocol_.reset ();
770
+ audio_service_.Stop ();
698
771
esp_restart ();
699
772
}
700
773
0 commit comments