wifi_board.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "wifi_board.h"
  2. #include "display.h"
  3. #include "application.h"
  4. #include "system_info.h"
  5. #include "font_awesome_symbols.h"
  6. #include "settings.h"
  7. #include "assets/lang_config.h"
  8. #include <freertos/FreeRTOS.h>
  9. #include <freertos/task.h>
  10. #include <esp_http.h>
  11. #include <esp_mqtt.h>
  12. #include <esp_udp.h>
  13. #include <tcp_transport.h>
  14. #include <tls_transport.h>
  15. #include <web_socket.h>
  16. #include <esp_log.h>
  17. #include <wifi_station.h>
  18. #include <wifi_configuration_ap.h>
  19. #include <ssid_manager.h>
  20. static const char *TAG = "WifiBoard";
  21. WifiBoard::WifiBoard() {
  22. Settings settings("wifi", true);//用于读取和写入名为 "wifi" 的配置文件。第二个参数 true 表示如果配置文件不存在则创建它。
  23. wifi_config_mode_ = settings.GetInt("force_ap") == 1;
  24. if (wifi_config_mode_) {
  25. ESP_LOGI(TAG, "force_ap is set to 1, reset to 0");
  26. settings.SetInt("force_ap", 0);
  27. }
  28. }
  29. std::string WifiBoard::GetBoardType() {
  30. return "wifi";
  31. }
  32. void WifiBoard::EnterWifiConfigMode() {
  33. auto& application = Application::GetInstance();
  34. application.SetDeviceState(kDeviceStateWifiConfiguring);
  35. auto& wifi_ap = WifiConfigurationAp::GetInstance();
  36. wifi_ap.SetLanguage(Lang::CODE);
  37. wifi_ap.SetSsidPrefix("Command-AI");
  38. wifi_ap.Start();
  39. // 显示 WiFi 配置 AP 的 SSID 和 Web 服务器 URL
  40. std::string hint = Lang::Strings::CONNECT_TO_HOTSPOT;
  41. hint += wifi_ap.GetSsid();
  42. hint += Lang::Strings::ACCESS_VIA_BROWSER;
  43. hint += wifi_ap.GetWebServerUrl();
  44. hint += "\n\n";
  45. // 播报配置 WiFi 的提示
  46. application.Alert(Lang::Strings::WIFI_CONFIG_MODE, hint.c_str(), "", Lang::Sounds::P3_CHANGEWIFI);
  47. // Wait forever until reset after configuration
  48. while (true) {
  49. int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
  50. int min_free_sram = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL);
  51. ESP_LOGI(TAG, "Free internal: %u minimal internal: %u", free_sram, min_free_sram);
  52. vTaskDelay(pdMS_TO_TICKS(10000));
  53. }
  54. }
  55. void WifiBoard::StartNetwork() {
  56. // User can press BOOT button while starting to enter WiFi configuration mode
  57. if (wifi_config_mode_) {
  58. EnterWifiConfigMode();
  59. return;
  60. }
  61. // If no WiFi SSID is configured, enter WiFi configuration mode
  62. auto& ssid_manager = SsidManager::GetInstance();
  63. auto ssid_list = ssid_manager.GetSsidList();
  64. if (ssid_list.empty()) {
  65. wifi_config_mode_ = true;
  66. EnterWifiConfigMode();
  67. return;
  68. }
  69. auto& wifi_station = WifiStation::GetInstance();
  70. wifi_station.OnScanBegin([this]() {
  71. auto display = Board::GetInstance().GetDisplay();
  72. display->ShowNotification(Lang::Strings::SCANNING_WIFI, 30000);
  73. });
  74. wifi_station.OnConnect([this](const std::string& ssid) {
  75. auto display = Board::GetInstance().GetDisplay();
  76. std::string notification = Lang::Strings::CONNECT_TO;
  77. notification += ssid;
  78. notification += "...";
  79. display->ShowNotification(notification.c_str(), 30000);
  80. });
  81. wifi_station.OnConnected([this](const std::string& ssid) {
  82. auto display = Board::GetInstance().GetDisplay();
  83. std::string notification = Lang::Strings::CONNECTED_TO;
  84. notification += ssid;
  85. display->ShowNotification(notification.c_str(), 30000);
  86. });
  87. wifi_station.Start();
  88. // Try to connect to WiFi, if failed, launch the WiFi configuration AP
  89. if (!wifi_station.WaitForConnected(60 * 1000)) {
  90. wifi_station.Stop();
  91. wifi_config_mode_ = true;
  92. EnterWifiConfigMode();
  93. return;
  94. }
  95. }
  96. Http* WifiBoard::CreateHttp() {
  97. return new EspHttp();
  98. }
  99. WebSocket* WifiBoard::CreateWebSocket() {
  100. #ifdef CONFIG_CONNECTION_TYPE_WEBSOCKET
  101. std::string url = CONFIG_WEBSOCKET_URL;
  102. if (url.find("wss://") == 0) {
  103. return new WebSocket(new TlsTransport());
  104. } else {
  105. return new WebSocket(new TcpTransport());
  106. }
  107. #endif
  108. return nullptr;
  109. }
  110. Mqtt* WifiBoard::CreateMqtt() {
  111. return new EspMqtt();
  112. }
  113. Udp* WifiBoard::CreateUdp() {
  114. return new EspUdp();
  115. }
  116. const char* WifiBoard::GetNetworkStateIcon() {
  117. if (wifi_config_mode_) {
  118. return FONT_AWESOME_WIFI;
  119. }
  120. auto& wifi_station = WifiStation::GetInstance();
  121. if (!wifi_station.IsConnected()) {
  122. return FONT_AWESOME_WIFI_OFF;
  123. }
  124. int8_t rssi = wifi_station.GetRssi();
  125. if (rssi >= -60) {
  126. return FONT_AWESOME_WIFI;
  127. } else if (rssi >= -70) {
  128. return FONT_AWESOME_WIFI_FAIR;
  129. } else {
  130. return FONT_AWESOME_WIFI_WEAK;
  131. }
  132. }
  133. std::string WifiBoard::GetBoardJson() {
  134. // Set the board type for OTA
  135. auto& wifi_station = WifiStation::GetInstance();
  136. std::string board_json = std::string("{\"type\":\"" BOARD_TYPE "\",");
  137. board_json += "\"name\":\"" BOARD_NAME "\",";
  138. if (!wifi_config_mode_) {
  139. board_json += "\"ssid\":\"" + wifi_station.GetSsid() + "\",";
  140. board_json += "\"rssi\":" + std::to_string(wifi_station.GetRssi()) + ",";
  141. board_json += "\"channel\":" + std::to_string(wifi_station.GetChannel()) + ",";
  142. board_json += "\"ip\":\"" + wifi_station.GetIpAddress() + "\",";
  143. }
  144. board_json += "\"mac\":\"" + SystemInfo::GetMacAddress() + "\"}";
  145. return board_json;
  146. }
  147. void WifiBoard::SetPowerSaveMode(bool enabled) {
  148. auto& wifi_station = WifiStation::GetInstance();
  149. wifi_station.SetPowerSaveMode(enabled);
  150. }
  151. void WifiBoard::ResetWifiConfiguration() {
  152. // Set a flag and reboot the device to enter the network configuration mode
  153. {
  154. Settings settings("wifi", true);
  155. settings.SetInt("force_ap", 1);
  156. }
  157. GetDisplay()->ShowNotification(Lang::Strings::ENTERING_WIFI_CONFIG_MODE);
  158. vTaskDelay(pdMS_TO_TICKS(1000));
  159. // Reboot the device
  160. esp_restart();
  161. }