// // Created by misaki on 2025/9/2. // #include "CppHandle.h" #include "OTAClass.h" #include "PetBaseClass.h" #include "PetDao.h" #include void testPetSystem() { std::cout << "Test point1" << std::endl; // 创建阶段策略 auto stageStrategy = std::make_unique(); stageStrategy->addStage(PetStageType::PET_STAGE_YOUNG, "models/young.obj"); stageStrategy->addStage(PetStageType::PET_STAGE_ADULT, "models/adult.obj"); stageStrategy->addStage(PetStageType::PET_STAGE_OLD, "models/old.obj"); stageStrategy->addStageAudio(PetStageType::PET_STAGE_YOUNG, "audio/young.mp3"); stageStrategy->addStageAudio(PetStageType::PET_STAGE_ADULT, "audio/adult.mp3"); stageStrategy->addStageAudio(PetStageType::PET_STAGE_OLD, "audio/old.mp3"); // 创建动作策略 auto actionStrategy = std::make_unique(); actionStrategy->addAction(PetActionType::PET_ACTION_EAT, "models/eat.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_HAPPY, "models/happy.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_SLEEP, "models/sleep.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_ANGRY, "models/angry.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_SAD, "models/sad.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_EVOLVE, "models/evolve.obj"); actionStrategy->addAction(PetActionType::PET_ACTION_TOUCH, "models/touch.obj"); actionStrategy->addActionAudio(PetActionType::PET_ACTION_EAT, "audio/eat.mp3"); actionStrategy->addActionAudio(PetActionType::PET_ACTION_HAPPY, "audio/happy.mp3"); actionStrategy->addActionAudio(PetActionType::PET_ACTION_SLEEP, "audio/sleep.mp3"); std::cout << "Test point2" << std::endl; // 创建宠物信息 PetBaseInfo info; info.pet_name = "芝士雪豹"; info.pet_hp = 100; info.pet_density = 50; info.pet_identity = "我是顶真"; // 创建宠物 auto pet = std::make_shared(info, std::move(stageStrategy), std::move(actionStrategy)); std::cout << "Test point3" << std::endl; // 创建音频观察者 auto audioStrategy = std::make_shared(); audioStrategy->setAudioCallback([](const std::string& audioPath) { std::cout << "Playing audio: " << audioPath << std::endl; }); audioStrategy->subscribe(pet); std::cout << "Test point4" << std::endl; // 创建渲染器观察者 auto rendererStrategy = std::make_shared( pet->getStageStrategy(), pet->getActionStrategy() ); rendererStrategy->setRenderCallback([](const std::string& modelPath) { std::cout << "Rendering model: " << modelPath << std::endl; }); rendererStrategy->subscribe(pet); std::cout << "Test point5" << std::endl; // 执行一些动作 std::cout << "=== Testing basic actions ===" << std::endl; pet->feed(); pet->play(); pet->touch(); std::cout << "Test point6" << std::endl; // 检查当前状态 std::cout << "Current HP: " << pet->getPetInfo().pet_hp << std::endl; std::cout << "Current density: " << pet->getPetInfo().pet_density << std::endl; std::cout << "Current stage: " << static_cast(pet->getCurrentStage()) << std::endl; std::cout << "Current action: " << static_cast(pet->getCurrentAction()) << std::endl; std::cout << "Test point7" << std::endl; // 测试进化 std::cout << "\n=== Testing evolution ===" << std::endl; // 直接修改亲密度来测试进化 PetBaseInfo newInfo = pet->getPetInfo(); newInfo.pet_density = 100; // 达到进化条件 pet->setPetInfo(newInfo); std::cout << "Test point8" << std::endl; if (pet->checkEvolution()) { std::cout << "Evolution successful!" << std::endl; } else { std::cout << "Evolution failed!" << std::endl; } // 进一步增加亲密度到150,尝试再次进化 newInfo.pet_density = 150; pet->setPetInfo(newInfo); if (pet->checkEvolution()) { std::cout << "Second evolution successful!" << std::endl; } else { std::cout << "Second evolution failed!" << std::endl; } std::cout << "Final stage: " << static_cast(pet->getCurrentStage()) << std::endl; PetDAO petDAO(SDFileManager::getInstance()); petDAO.savePet(pet, "my_pet.json"); // 列出所有宠物文件 auto petFiles = petDAO.listPetFiles(); for (const auto& file : petFiles) { std::cout << "Pet file: " << file << std::endl; } std::cout << SDFileManager::getInstance()->catCommand("/sdcard/pet_data/my_pet.json") << std::endl; } #include "SpeechRecognizer.h" #include #include // 命令回调函数 void commandCallback(int command_id, const std::string& phrase, float probability) { ESP_LOGI("Example", "Received command: ID=%d, Phrase='%s', Probability=%.2f", command_id, phrase.c_str(), probability); // 根据命令执行相应操作 switch (command_id) { case 0: ESP_LOGI("Example", "执行命令0"); // 执行命令0的操作 break; case 1: ESP_LOGI("Example", "执行命令1"); // 执行命令1的操作 break; case 2: ESP_LOGI("Example", "执行命令2"); // 执行命令2的操作 break; default: ESP_LOGI("Example", "未知的命令ID: %d", command_id); break; } } // 状态回调函数 void stateCallback(const std::string& state) { ESP_LOGI("Example", "状态改变到: %s", state.c_str()); } #include "SDFileManager.h" void testMIC() { // 初始化NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); // 初始化SD卡管理器 SDFileManager::getInstance()->tryInitSDCard(); // 获取SpeechRecognizer实例 SpeechRecognizer* recognizer = SpeechRecognizer::getInstance(); // 配置识别器 SpeechRecognizerConfig config; config.enable_vad = true; config.vad_mode = VAD_MODE_3; // 更高的VAD灵敏度 config.model_path = "/sdcard/srmodels"; // 初始化 if (!recognizer->init(config)) { ESP_LOGE("main", "Failed to initialize speech recognizer"); return; } // 添加自定义命令 std::vector> commands = { {0, "kai deng"}, // 开灯 {1, "guan deng"}, // 关灯 {2, "ti gao liang du"}, // 提高亮度 {3, "jiang di liang du"}, // 降低亮度 {4, "bo fang yin yue"}, // 播放音乐 {5, "ting zhi bo fang"} // 停止播放 }; if (!recognizer->addCommands(commands)) { ESP_LOGE("main", "Failed to add some commands"); } // 注册回调函数 recognizer->registerCommandCallback(commandCallback); recognizer->registerStateCallback(stateCallback); // 开始识别 if (!recognizer->start()) { ESP_LOGE("main", "Failed to start speech recognition"); return; } ESP_LOGI("main", "Speech recognition system started successfully"); } #include "ToolsClass.h" #include "WifiConnectors.h" #include "CommClass.h" #include "sys_conf_singleton.h" #include "HttpOtaUpdater.h" using namespace std::chrono; const auto sleep_time = seconds{ 5 }; // OTA相关 HttpOtaUpdater otaUpdater; void setupOtaCallbacks() { // 设置进度回调 otaUpdater.setProgressCallback([](int progress, int total) { ESP_LOGI("OTA", "Progress: %d%%", progress); }); // 设置状态回调 otaUpdater.setStateCallback([](HttpOtaUpdater::OtaState state, const std::string& message) { const char* stateNames[] = { "IDLE", "CONNECTING", "DOWNLOADING", "VERIFYING", "SUCCESS", "FAILED" }; ESP_LOGI("OTA", "State: %s - %s", stateNames[static_cast(state)], message.c_str()); }); // 设置完成回调 otaUpdater.setFinishCallback([](bool success, const std::string& message) { if (success) { ESP_LOGI("OTA", "Completed successfully: %s", message.c_str()); } else { ESP_LOGE("OTA", "Failed: %s", message.c_str()); } }); // 如果需要HTTPS,可以在这里设置证书(保留供后期使用) // otaUpdater.setCACert(my_ca_cert_pem); // otaUpdater.skipCertCommonNameCheck(true); // 仅用于测试 } // JSON 数据回调函数 /** 交互所使用的json内容 { "type": "xxx", // 消息类型 "xxx":"xxx", // 其他数据 ...... } */ void onJsonData(const cppjson::Json& json) { // 打印收到的 JSON ESP_LOGI("JSON_CALLBACK", "收到JSON数据: %s", json.dump().c_str()); // 解析消息类型 const cppjson::Json& type = json["type"]; if (!type.isString()) return; std::string typeStr = type.asString(); if (typeStr == "greeting") { ESP_LOGI("JSON_CALLBACK", "收到服务器问候消息"); } else if (typeStr == "heartbeat") { ESP_LOGI("JSON_CALLBACK", "收到心跳响应"); } else if (typeStr == "response") { ESP_LOGI("JSON_CALLBACK", "收到服务器响应"); } else if (typeStr == "echo") { ESP_LOGI("JSON_CALLBACK", "收到回显消息"); } else if (typeStr == "broadcast") { ESP_LOGI("JSON_CALLBACK", "收到广播消息"); } else if (typeStr == "ota") { ESP_LOGI("JSON_CALLBACK", "收到OTA消息"); // 进一步处理OTA消息 // 获取OTA中的版本信息 const cppjson::Json& version = json["version"]; if (!version.isString()) return; std::string versionStr = version.asString(); // 获取OTA中的HTTP URL const cppjson::Json& url = json["url"]; if (!url.isString()) return; std::string urlStr = url.asString(); // 告诉服务端,升级开始 cppjson::Json response = cppjson::Json::object(); response.set("type", cppjson::Json("ota_start")); WebSocketManager::getInstance()->sendJson(response); otaUpdater.start(urlStr); } } // WebSocket事件回调函数 void onWebSocketEvent(WebSocketEvent event, const std::string& message) { switch (event) { case WebSocketEvent::CONNECTED: ESP_LOGI("EVENT_CALLBACK", "WebSocket已连接: %s", message.c_str()); break; case WebSocketEvent::DISCONNECTED: ESP_LOGI("EVENT_CALLBACK", "WebSocket已断开: %s", message.c_str()); break; case WebSocketEvent::DATA_RECEIVED: ESP_LOGI("EVENT_CALLBACK", "收到原始数据: %s", message.c_str()); break; case WebSocketEvent::ERROR: ESP_LOGE("EVENT_CALLBACK", "WebSocket错误: %s", message.c_str()); break; } } // 发送状态信息函数 void sendStatus() { cppjson::Json status = cppjson::Json::object(); status.set("type", cppjson::Json("status")); cppjson::Json data = cppjson::Json::object(); data.set("free_heap", cppjson::Json(esp_get_free_heap_size())) .set("uptime", cppjson::Json(xTaskGetTickCount() * portTICK_PERIOD_MS / 1000)); status.set("data", data); // 嵌套对象 if (WebSocketManager::getInstance()->sendJson(status)) { ESP_LOGI("SEND", "已发送状态信息"); } else { ESP_LOGE("SEND", "发送状态信息失败"); } } // 发送问候消息函数 void sendGreeting() { cppjson::Json greeting = cppjson::Json::object(); greeting.set("type", cppjson::Json("greeting")) .set("message", cppjson::Json("Hello from ESP32-S3")) .set("timestamp", cppjson::Json(xTaskGetTickCount() * portTICK_PERIOD_MS / 1000)); if (WebSocketManager::getInstance()->sendJson(greeting)) { ESP_LOGI("SEND", "已发送问候消息"); } else { ESP_LOGE("SEND", "发送问候消息失败"); } } void websocket_task() { TickType_t lastStatusTime = 0; TickType_t lastHeartbeatTime = 0; TickType_t lastGreetingTime = 0; while (true) { TickType_t currentTime = xTaskGetTickCount(); // 检查连接状态 if (!WebSocketManager::getInstance()->isConnected()) { ESP_LOGI("APP_TASK", "WebSocket未连接,尝试重新连接..."); // 确保WiFi已连接 if (!WifiConnectors::getInstance()->isWifiConnect()) { ESP_LOGI("APP_TASK", "WiFi未连接,等待WiFi连接..."); vTaskDelay(5000 / portTICK_PERIOD_MS); continue; } if (WebSocketManager::getInstance()->connect()) { ESP_LOGI("APP_TASK", "重新连接成功"); } else { ESP_LOGI("APP_TASK", "重新连接失败"); } vTaskDelay(5000 / portTICK_PERIOD_MS); continue; } // 每10秒发送状态信息 if (currentTime - lastStatusTime > (10000 / portTICK_PERIOD_MS)) { sendStatus(); lastStatusTime = currentTime; } // 每60秒发送问候 if (currentTime - lastGreetingTime > (60000 / portTICK_PERIOD_MS)) { sendGreeting(); lastGreetingTime = currentTime; } vTaskDelay(100 / portTICK_PERIOD_MS); } } void createWebSocket() { // 等待WiFi连接成功后再连接WebSocket ESP_LOGI("APP_TASK", "等待WiFi连接..."); while (!WifiConnectors::getInstance()->isWifiConnect()) { ESP_LOGI("APP_TASK", "WiFi未连接,等待中..."); vTaskDelay(1000 / portTICK_PERIOD_MS); } // 保存SN SysConfJson::getInstance()->saveSN(ToolsClass::GenerateSN(ToolsClass::getChipMAC(), ToolsClass::getChipSerialNumber())); // 读取SN std::string sn = SysConfJson::getInstance()->loadSN(); ESP_LOGI("conf", "loaded sn = %s", sn.c_str()); // 配置WebSocket WebSocketConfig config; config.uri = "ws://" + std::string("192.168.1.11") + ":" + std::to_string(8080) + "/ws"; config.auto_reconnect = true; // 自动重连 config.reconnect_interval = 5000; // 重连间隔(毫秒) config.heartbeat_interval = 30000; // 心跳间隔(毫秒) config.max_reconnect_attempts = 10; // 最大重连尝试次数 // TODO: 此处通信类存在线程重复创建bug,似乎是来自esp-idf的bug,待查证 // 初始化WebSocket管理器 if (!WebSocketManager::getInstance()->initialize(config)) { ESP_LOGE("APP_TASK", "WebSocket管理器初始化失败"); vTaskDelete(NULL); return; } // 设置回调函数 WebSocketManager::getInstance()->setJsonCallback(onJsonData); WebSocketManager::getInstance()->setEventCallback(onWebSocketEvent); // 连接WebSocket服务器 ESP_LOGI("APP_TASK", "正在连接WebSocket服务器: %s", config.uri.c_str()); if (!WebSocketManager::getInstance()->connect()) { ESP_LOGE("APP_TASK", "WebSocket连接失败"); } // 创建WebSocket任务 ThreadConfig websocket_config; websocket_config.core_id = 0; websocket_config.inherit_cfg = true; websocket_config.name = "websocket_task"; websocket_config.priority = 5; websocket_config.stack_size = 4096; std::thread websocket_thread = ThreadManager::createThread(websocket_config, websocket_task); websocket_thread.detach(); } void Cpp_Hand() { // testMIC(); // testPetSystem(); ESP_LOGI("CppHandle::Cpp_Hand", "当前固件版本 %s:", ToolsClass::getDeviceVersion().c_str()); ESP_LOGI("CppHandle::Cpp_Hand", "当前设备MAC地址 %s:", ToolsClass::getChipMAC().c_str()); ESP_LOGI("CppHandle::Cpp_Hand", "当前设备固件序列号 %s:", ToolsClass::getChipSerialNumber().c_str()); // 连接wifi WifiConnectors::getInstance()->connectWifi("Misaki-2.4G", "88888888", 5); // 创建WebSocket createWebSocket(); // 设置OTA回调 setupOtaCallbacks(); while (true) { // 主线程线程循环 // ThreadManager::print_sys_memory(); // 打印系统内存使用情况 // ThreadManager::stats_task(); // 打印任务统计信息 std::this_thread::sleep_for(sleep_time); // 休眠5秒 } }