Files
kedia/main/boards/zhengchen-cam/mcp_controller.cc
2026-06-17 15:02:16 +08:00

214 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cJSON.h>
#include <esp_log.h>
#include <sdkconfig.h>
#include <cstring>
#include "application.h"
#include "board.h"
#include "config.h"
#include "mcp_server.h"
#include "sdkconfig.h"
#include "settings.h"
#include "display.h"
#define TAG "MCPController"
namespace {
constexpr bool kDefaultFatigueEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_OFF)
false;
#else
true;
#endif
constexpr bool kDefaultFatigueCameraEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_CAMERA) || defined(CONFIG_FATIGUE_DETECTION_MODE_BOTH)
true;
#else
false;
#endif
constexpr bool kDefaultFatigueSilenceEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_SILENCE) || defined(CONFIG_FATIGUE_DETECTION_MODE_BOTH)
true;
#else
false;
#endif
constexpr bool kDefaultFatigueCameraDebugPreview =
#if defined(CONFIG_FATIGUE_CAMERA_DEBUG_PREVIEW_DEFAULT)
true;
#else
false;
#endif
std::string GetFatigueDetectionMode(bool enabled, bool camera_enabled, bool silence_enabled) {
if (!enabled) {
return "off";
}
if (camera_enabled && silence_enabled) {
return "both";
}
if (camera_enabled) {
return "camera";
}
if (silence_enabled) {
return "silence";
}
return "off";
}
} // namespace
class MCPController {
public:
MCPController() {
RegisterMcpTools();
ESP_LOGI(TAG, "注册MCP工具");
}
void RegisterMcpTools() {
auto& mcp_server = McpServer::GetInstance();
ESP_LOGI(TAG, "开始注册MCP工具...");
mcp_server.AddTool(
"self.AEC.set_mode",
"设置AEC对话打断模式。当用户意图切换对话打断模式时或者用户觉得ai对话容易被打断时或者用户觉得无法实现对话打断时都使用此工具。\n"
"参数:\n"
" `mode`: 对话打断模式,可选值只有`kAecOff`(关闭)和`kAecOnDeviceSide`(开启)\n"
"返回值:\n"
" 反馈状态信息,不需要确认,立即播报相关数据\n",
PropertyList({
Property("mode", kPropertyTypeString)
}),
[](const PropertyList& properties) -> ReturnValue {
auto mode = properties["mode"].value<std::string>();
auto& app = Application::GetInstance();
vTaskDelay(pdMS_TO_TICKS(2000));
if (mode == "kAecOff") {
app.SetAecMode(kAecOff);
return "{\"success\": true, \"message\": \"AEC对话打断模式已关闭\"}";
}else {
app.SetAecMode(kAecOnDeviceSide);
return "{\"success\": true, \"message\": \"AEC对话打断模式已开启\"}";
}
}
);
mcp_server.AddTool(
"self.AEC.get_mode",
"获取AEC对话打断模式状态。当用户意图获取对话打断模式状态时使用此工具。\n"
"返回值:\n"
" 反馈状态信息,不需要确认,立即播报相关数据\n",
PropertyList(),
[](const PropertyList&) -> ReturnValue {
auto& app = Application::GetInstance();
const bool is_currently_off = (app.GetAecMode() == kAecOff);
if (is_currently_off) {
return "{\"success\": true, \"message\": \"AEC对话打断模式处于关闭状态\"}";
}else {
return "{\"success\": true, \"message\": \"AEC对话打断模式处于开启状态\"}";
}
}
);
mcp_server.AddTool(
"self.res.esp_restart",
"重启设备。当用户意图重启设备时使用此工具。\n",
PropertyList(),
[](const PropertyList&) -> ReturnValue {
vTaskDelay(pdMS_TO_TICKS(1000));
// Reboot the device
esp_restart();
return true;
}
);
mcp_server.AddTool(
"self.fatigue.set_detection_mode",
"切换疲劳提醒检测模式。当用户想切换打瞌睡检测、眨眼检测、不讲话检测、关闭疲劳提醒或查看摄像头取样画面时使用此工具。\n"
"参数:\n"
" `mode`: 检测模式,可选值只有 `camera`(只用摄像头眨眼/闭眼检测)、`silence`(只用不讲话/静默检测)、`both`(两个都开)、`off`(关闭疲劳提醒)\n"
" `debug_preview`: 是否显示摄像头调试预览。默认 false只有用户明确想看摄像头拍到什么时才设为 true\n"
"返回值:\n"
" 反馈当前疲劳检测模式,不需要确认,立即播报相关数据\n",
PropertyList({
Property("mode", kPropertyTypeString),
Property("debug_preview", kPropertyTypeBoolean, false),
}),
[](const PropertyList& properties) -> ReturnValue {
auto mode = properties["mode"].value<std::string>();
bool debug_preview = properties["debug_preview"].value<bool>();
bool enabled = true;
bool camera_enabled = false;
bool silence_enabled = false;
std::string message;
if (mode == "camera") {
camera_enabled = true;
message = "已切换为摄像头眨眼检测模式";
} else if (mode == "silence") {
silence_enabled = true;
message = "已切换为不讲话静默检测模式";
} else if (mode == "both") {
camera_enabled = true;
silence_enabled = true;
message = "已切换为摄像头加静默双检测模式";
} else if (mode == "off") {
enabled = false;
message = "疲劳提醒检测已关闭";
} else {
return "{\"success\": false, \"message\": \"检测模式无效,只能使用 camera、silence、both 或 off\"}";
}
Settings settings("fatigue", true);
settings.SetBool("enabled", enabled);
settings.SetBool("camera_enabled", camera_enabled);
settings.SetBool("silence_enabled", silence_enabled);
settings.SetBool("camera_debug_preview", debug_preview);
return std::string("{\"success\": true, \"mode\": \"") + mode +
"\", \"debug_preview\": " + (debug_preview ? "true" : "false") +
", \"message\": \"" + message + "\"}";
}
);
mcp_server.AddTool(
"self.fatigue.get_detection_mode",
"获取当前疲劳提醒检测模式。当用户询问现在使用哪种打瞌睡检测模式时使用此工具。\n"
"返回值:\n"
" 当前检测模式和摄像头预览状态\n",
PropertyList(),
[](const PropertyList&) -> ReturnValue {
Settings settings("fatigue", false);
bool enabled = settings.GetBool("enabled", kDefaultFatigueEnabled);
bool camera_enabled = settings.GetBool("camera_enabled", kDefaultFatigueCameraEnabled);
bool silence_enabled =
settings.GetBool("silence_enabled", kDefaultFatigueSilenceEnabled);
bool debug_preview =
settings.GetBool("camera_debug_preview", kDefaultFatigueCameraDebugPreview);
auto mode = GetFatigueDetectionMode(enabled, camera_enabled, silence_enabled);
return std::string("{\"success\": true, \"mode\": \"") + mode +
"\", \"camera_enabled\": " + (camera_enabled ? "true" : "false") +
", \"silence_enabled\": " + (silence_enabled ? "true" : "false") +
", \"debug_preview\": " + (debug_preview ? "true" : "false") + "}";
}
);
ESP_LOGI(TAG, "MCP工具注册完成");
}
};
static MCPController* g_mcp_controller = nullptr;
void InitializeMCPController() {
if (g_mcp_controller == nullptr) {
g_mcp_controller = new MCPController();
ESP_LOGI(TAG, "注册MCP工具");
}
}