#include "board.h" #include "system_info.h" #include "settings.h" #include "display/display.h" #include "assets/lang_config.h" #include #include #include #include #define TAG "Board" Board::Board() { Settings settings("board", true); uuid_ = settings.GetString("uuid"); if (uuid_.empty()) { uuid_ = GenerateUuid(); settings.SetString("uuid", uuid_); } ESP_LOGI(TAG, "UUID=%s SKU=%s", uuid_.c_str(), BOARD_NAME); } std::string Board::GenerateUuid() { // UUID v4 需要 16 字节的随机数据 uint8_t uuid[16]; // 使用 ESP32 的硬件随机数生成器 esp_fill_random(uuid, sizeof(uuid)); // 设置版本 (版本 4) 和变体位 uuid[6] = (uuid[6] & 0x0F) | 0x40; // 版本 4 uuid[8] = (uuid[8] & 0x3F) | 0x80; // 变体 1 // 将字节转换为标准的 UUID 字符串格式 char uuid_str[37]; snprintf(uuid_str, sizeof(uuid_str), "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); return std::string(uuid_str); } bool Board::GetBatteryLevel(int &level, bool& charging, bool& discharging) { return false; } bool Board::GetTemperature(float& esp32temp){ return false; } Display* Board::GetDisplay() { static NoDisplay display; return &display; } Camera* Board::GetCamera() { return nullptr; } Led* Board::GetLed() { static NoLed led; return &led; } std::string Board::GetJson() { /* { "version": 2, "flash_size": 4194304, "psram_size": 0, "minimum_free_heap_size": 123456, "mac_address": "00:00:00:00:00:00", "uuid": "00000000-0000-0000-0000-000000000000", "chip_model_name": "esp32s3", "chip_info": { "model": 1, "cores": 2, "revision": 0, "features": 0 }, "application": { "name": "my-app", "version": "1.0.0", "compile_time": "2021-01-01T00:00:00Z" "idf_version": "4.2-dev" "elf_sha256": "" }, "partition_table": [ "app": { "label": "app", "type": 1, "subtype": 2, "address": 0x10000, "size": 0x100000 } ], "ota": { "label": "ota_0" }, "board": { ... } } */ std::string json = R"({"version":2,"language":")" + std::string(Lang::CODE) + R"(",)"; json += R"("flash_size":)" + std::to_string(SystemInfo::GetFlashSize()) + R"(,)"; json += R"("minimum_free_heap_size":")" + std::to_string(SystemInfo::GetMinimumFreeHeapSize()) + R"(",)"; json += R"("mac_address":")" + SystemInfo::GetMacAddress() + R"(",)"; json += R"("uuid":")" + uuid_ + R"(",)"; json += R"("chip_model_name":")" + SystemInfo::GetChipModelName() + R"(",)"; esp_chip_info_t chip_info; esp_chip_info(&chip_info); json += R"("chip_info":{)"; json += R"("model":)" + std::to_string(chip_info.model) + R"(,)"; json += R"("cores":)" + std::to_string(chip_info.cores) + R"(,)"; json += R"("revision":)" + std::to_string(chip_info.revision) + R"(,)"; json += R"("features":)" + std::to_string(chip_info.features) + R"(},)"; auto app_desc = esp_app_get_description(); json += R"("application":{)"; json += R"("name":")" + std::string(app_desc->project_name) + R"(",)"; json += R"("version":")" + std::string(app_desc->version) + R"(",)"; json += R"("compile_time":")" + std::string(app_desc->date) + R"(T)" + std::string(app_desc->time) + R"(Z",)"; json += R"("idf_version":")" + std::string(app_desc->idf_ver) + R"(",)"; char sha256_str[65]; for (int i = 0; i < 32; i++) { snprintf(sha256_str + i * 2, sizeof(sha256_str) - i * 2, "%02x", app_desc->app_elf_sha256[i]); } json += R"("elf_sha256":")" + std::string(sha256_str) + R"(")"; json += R"(},)"; json += R"("partition_table": [)"; esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL); while (it) { const esp_partition_t *partition = esp_partition_get(it); json += R"({)"; json += R"("label":")" + std::string(partition->label) + R"(",)"; json += R"("type":)" + std::to_string(partition->type) + R"(,)"; json += R"("subtype":)" + std::to_string(partition->subtype) + R"(,)"; json += R"("address":)" + std::to_string(partition->address) + R"(,)"; json += R"("size":)" + std::to_string(partition->size) + R"(},)";; it = esp_partition_next(it); } json.pop_back(); // Remove the last comma json += R"(],)"; json += R"("ota":{)"; auto ota_partition = esp_ota_get_running_partition(); json += R"("label":")" + std::string(ota_partition->label) + R"(")"; json += R"(},)"; json += R"("board":)" + GetBoardJson(); // Close the JSON object json += R"(})"; return json; } void Board::postAlive() { // 创建HTTP客户端 auto network = Board::GetInstance().GetNetwork(); if (!network) { ESP_LOGE(TAG, "Failed to get network instance"); return; } // 创建 HTTP 客户端 auto http = network->CreateHttp(2); // 使用正确的创建方式 if (!http) { ESP_LOGE(TAG, "Failed to create HTTP client"); return; } std::string json = "{}"; // 获取MAC地址并构建JSON std::string mac = SystemInfo::GetMacAddress(); ESP_LOGI(TAG, "Device MAC: %s", mac.c_str()); http->SetHeader("macAddress", SystemInfo::GetMacAddress().c_str()); http->SetHeader("Content-Type", "application/json"); http->SetContent(std::move(json)); std::string url ="http://36.134.23.41:8004/xiaozhi-app/app/device/getDeviceEnable"; // 发送POST请求 if (!http->Open("POST",url.c_str())) { ESP_LOGE(TAG, "HTTP POST failed to open connection"); return; } // 获取响应状态码 int status = http->GetStatusCode(); ESP_LOGI(TAG, "HTTP response status: %d", status); if (status == 200) { ESP_LOGI(TAG, "POST success"); } else { ESP_LOGW(TAG, "POST received non-200 status: %d", status); } http->Close(); ESP_LOGD(TAG, "postAlive completed"); }