diff --git a/README.md b/README.md
index 9026ec9fe1..f2c04c0ec1 100644
--- a/README.md
+++ b/README.md
@@ -1,73 +1,73 @@
# An MCP-based Chatbot
-(中文 | [English](README_en.md) | [日本語](README_ja.md))
+([中文](README.md) | English | [日本語](README_ja.md)| [Português](README_pt.md))
-## 介绍
+## Introduction
-👉 [人类:给 AI 装摄像头 vs AI:当场发现主人三天没洗头【bilibili】](https://www.bilibili.com/video/BV1bpjgzKEhd/)
+👉 [Human: Give AI a camera vs AI: Instantly finds out the owner hasn't washed hair for three days【bilibili】](https://www.bilibili.com/video/BV1bpjgzKEhd/)
-👉 [手工打造你的 AI 女友,新手入门教程【bilibili】](https://www.bilibili.com/video/BV1XnmFYLEJN/)
+👉 [Handcraft your AI girlfriend, beginner's guide【bilibili】](https://www.bilibili.com/video/BV1XnmFYLEJN/)
-小智 AI 聊天机器人作为一个语音交互入口,利用 Qwen / DeepSeek 等大模型的 AI 能力,通过 MCP 协议实现多端控制。
+As a voice interaction entry, the XiaoZhi AI chatbot leverages the AI capabilities of large models like Qwen / DeepSeek, and achieves multi-terminal control via the MCP protocol.
-
+
-### 版本说明
+## Version Notes
-当前 v2 版本与 v1 版本分区表不兼容,所以无法从 v1 版本通过 OTA 升级到 v2 版本。分区表说明参见 [partitions/v2/README.md](partitions/v2/README.md)。
+The current v2 version is incompatible with the v1 partition table, so it is not possible to upgrade from v1 to v2 via OTA. For partition table details, see [partitions/v2/README.md](partitions/v2/README.md).
-使用 v1 版本的所有硬件,可以通过手动烧录固件来升级到 v2 版本。
+All hardware running v1 can be upgraded to v2 by manually flashing the firmware.
-v1 的稳定版本为 1.9.2,可以通过 `git checkout v1` 来切换到 v1 版本,该分支会持续维护到 2026 年 2 月。
+The stable version of v1 is 1.9.2. You can switch to v1 by running `git checkout v1`. The v1 branch will be maintained until February 2026.
-### 已实现功能
+### Features Implemented
- Wi-Fi / ML307 Cat.1 4G
-- 离线语音唤醒 [ESP-SR](https://github.com/espressif/esp-sr)
-- 支持两种通信协议([Websocket](docs/websocket.md) 或 MQTT+UDP)
-- 采用 OPUS 音频编解码
-- 基于流式 ASR + LLM + TTS 架构的语音交互
-- 声纹识别,识别当前说话人的身份 [3D Speaker](https://github.com/modelscope/3D-Speaker)
-- OLED / LCD 显示屏,支持表情显示
-- 电量显示与电源管理
-- 支持多语言(中文、英文、日文)
-- 支持 ESP32-C3、ESP32-S3、ESP32-P4 芯片平台
-- 通过设备端 MCP 实现设备控制(音量、灯光、电机、GPIO 等)
-- 通过云端 MCP 扩展大模型能力(智能家居控制、PC桌面操作、知识搜索、邮件收发等)
-- 自定义唤醒词、字体、表情与聊天背景,支持网页端在线修改 ([自定义Assets生成器](https://github.com/78/xiaozhi-assets-generator))
+- Offline voice wake-up [ESP-SR](https://github.com/espressif/esp-sr)
+- Supports two communication protocols ([Websocket](docs/websocket.md) or MQTT+UDP)
+- Uses OPUS audio codec
+- Voice interaction based on streaming ASR + LLM + TTS architecture
+- Speaker recognition, identifies the current speaker [3D Speaker](https://github.com/modelscope/3D-Speaker)
+- OLED / LCD display, supports emoji display
+- Battery display and power management
+- Multi-language support (Chinese, English, Japanese)
+- Supports ESP32-C3, ESP32-S3, ESP32-P4 chip platforms
+- Device-side MCP for device control (Speaker, LED, Servo, GPIO, etc.)
+- Cloud-side MCP to extend large model capabilities (smart home control, PC desktop operation, knowledge search, email, etc.)
+- Customizable wake words, fonts, emojis, and chat backgrounds with online web-based editing ([Custom Assets Generator](https://github.com/78/xiaozhi-assets-generator))
-## 硬件
+## Hardware
-### 面包板手工制作实践
+### Breadboard DIY Practice
-详见飞书文档教程:
+See the Feishu document tutorial:
-👉 [《小智 AI 聊天机器人百科全书》](https://ccnphfhqs21z.feishu.cn/wiki/F5krwD16viZoF0kKkvDcrZNYnhb?from=from_copylink)
+👉 ["XiaoZhi AI Chatbot Encyclopedia"](https://ccnphfhqs21z.feishu.cn/wiki/F5krwD16viZoF0kKkvDcrZNYnhb?from=from_copylink)
-面包板效果图如下:
+Breadboard demo:
-
+
-### 支持 70 多个开源硬件(仅展示部分)
+### Supports 70+ Open Source Hardware (Partial List)
-- 立创·实战派 ESP32-S3 开发板
-- 乐鑫 ESP32-S3-BOX3
+- LiChuang ESP32-S3 Development Board
+- Espressif ESP32-S3-BOX3
- M5Stack CoreS3
- M5Stack AtomS3R + Echo Base
-- 神奇按钮 2.4
-- 微雪电子 ESP32-S3-Touch-AMOLED-1.8
+- Magic Button 2.4
+- Waveshare ESP32-S3-Touch-AMOLED-1.8
- LILYGO T-Circle-S3
-- 虾哥 Mini C3
-- 璀璨·AI 吊坠
-- 无名科技 Nologo-星智-1.54TFT
+- XiaGe Mini C3
+- CuiCan AI Pendant
+- WMnologo-Xingzhi-1.54TFT
- SenseCAP Watcher
-- ESP-HI 超低成本机器狗
+- ESP-HI Low Cost Robot Dog
-## 软件
+## Software
-### 固件烧录
+### Firmware Flashing
-新手第一次操作建议先不要搭建开发环境,直接使用免开发环境烧录的固件。
+For beginners, it is recommended to use the firmware that can be flashed without setting up a development environment.
-固件默认接入 [xiaozhi.me](https://xiaozhi.me) 官方服务器,个人用户注册账号可以免费使用 Qwen 实时模型。
+The firmware connects to the official [xiaozhi.me](https://xiaozhi.me) server by default. Personal users can register an account to use the Qwen real-time model for free.
-👉 [新手烧录固件教程](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)
+👉 [Beginner's Firmware Flashing Guide](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)
-### 开发环境
+### Development Environment
-- Cursor 或 VSCode
-- 安装 ESP-IDF 插件,选择 SDK 版本 5.4 或以上
-- Linux 比 Windows 更好,编译速度快,也免去驱动问题的困扰
-- 本项目使用 Google C++ 代码风格,提交代码时请确保符合规范
+- Cursor or VSCode
+- Install ESP-IDF plugin, select SDK version 5.4 or above
+- Linux is better than Windows for faster compilation and fewer driver issues
+- This project uses Google C++ code style, please ensure compliance when submitting code
-### 开发者文档
+### Developer Documentation
-- [自定义开发板指南](docs/custom-board.md) - 学习如何为小智 AI 创建自定义开发板
-- [MCP 协议物联网控制用法说明](docs/mcp-usage.md) - 了解如何通过 MCP 协议控制物联网设备
-- [MCP 协议交互流程](docs/mcp-protocol.md) - 设备端 MCP 协议的实现方式
-- [MQTT + UDP 混合通信协议文档](docs/mqtt-udp.md)
-- [一份详细的 WebSocket 通信协议文档](docs/websocket.md)
+- [Custom Board Guide](docs/custom-board_en.md) - Learn how to create custom boards for XiaoZhi AI
+- [MCP Protocol IoT Control Usage](docs/mcp-usage_en.md) - Learn how to control IoT devices via MCP protocol
+- [MCP Protocol Interaction Flow](docs/mcp-protocol_en.md) - Device-side MCP protocol implementation
+- [MQTT + UDP Hybrid Communication Protocol Document](docs/mqtt-udp_en.md)
+- [A detailed WebSocket communication protocol document](docs/websocket_en.md)
-## 大模型配置
+## Large Model Configuration
-如果你已经拥有一个小智 AI 聊天机器人设备,并且已接入官方服务器,可以登录 [xiaozhi.me](https://xiaozhi.me) 控制台进行配置。
+If you already have a XiaoZhi AI chatbot device and have connected to the official server, you can log in to the [xiaozhi.me](https://xiaozhi.me) console for configuration.
-👉 [后台操作视频教程(旧版界面)](https://www.bilibili.com/video/BV1jUCUY2EKM/)
+👉 [Backend Operation Video Tutorial (Old Interface)](https://www.bilibili.com/video/BV1jUCUY2EKM/)
-## 相关开源项目
+## Related Open Source Projects
-在个人电脑上部署服务器,可以参考以下第三方开源的项目:
+For server deployment on personal computers, refer to the following open-source projects:
-- [xinnan-tech/xiaozhi-esp32-server](https://github.com/xinnan-tech/xiaozhi-esp32-server) Python 服务器
-- [joey-zhou/xiaozhi-esp32-server-java](https://github.com/joey-zhou/xiaozhi-esp32-server-java) Java 服务器
-- [AnimeAIChat/xiaozhi-server-go](https://github.com/AnimeAIChat/xiaozhi-server-go) Golang 服务器
+- [xinnan-tech/xiaozhi-esp32-server](https://github.com/xinnan-tech/xiaozhi-esp32-server) Python server
+- [joey-zhou/xiaozhi-esp32-server-java](https://github.com/joey-zhou/xiaozhi-esp32-server-java) Java server
+- [AnimeAIChat/xiaozhi-server-go](https://github.com/AnimeAIChat/xiaozhi-server-go) Golang server
-使用小智通信协议的第三方客户端项目:
+Other client projects using the XiaoZhi communication protocol:
-- [huangjunsen0406/py-xiaozhi](https://github.com/huangjunsen0406/py-xiaozhi) Python 客户端
-- [TOM88812/xiaozhi-android-client](https://github.com/TOM88812/xiaozhi-android-client) Android 客户端
-- [100askTeam/xiaozhi-linux](http://github.com/100askTeam/xiaozhi-linux) 百问科技提供的 Linux 客户端
-- [78/xiaozhi-sf32](https://github.com/78/xiaozhi-sf32) 思澈科技的蓝牙芯片固件
-- [QuecPython/solution-xiaozhiAI](https://github.com/QuecPython/solution-xiaozhiAI) 移远提供的 QuecPython 固件
+- [huangjunsen0406/py-xiaozhi](https://github.com/huangjunsen0406/py-xiaozhi) Python client
+- [TOM88812/xiaozhi-android-client](https://github.com/TOM88812/xiaozhi-android-client) Android client
+- [100askTeam/xiaozhi-linux](http://github.com/100askTeam/xiaozhi-linux) Linux client by 100ask
+- [78/xiaozhi-sf32](https://github.com/78/xiaozhi-sf32) Bluetooth chip firmware by Sichuan
+- [QuecPython/solution-xiaozhiAI](https://github.com/QuecPython/solution-xiaozhiAI) QuecPython firmware by Quectel
-## 关于项目
+Custom Assets Tools:
-这是一个由虾哥开源的 ESP32 项目,以 MIT 许可证发布,允许任何人免费使用,修改或用于商业用途。
+- [78/xiaozhi-assets-generator](https://github.com/78/xiaozhi-assets-generator) Custom Assets Generator (Wake words, fonts, emojis, backgrounds)
-我们希望通过这个项目,能够帮助大家了解 AI 硬件开发,将当下飞速发展的大语言模型应用到实际的硬件设备中。
+## About the Project
-如果你有任何想法或建议,请随时提出 Issues 或加入 QQ 群:1011329060
+This is an open-source ESP32 project, released under the MIT license, allowing anyone to use it for free, including for commercial purposes.
+
+We hope this project helps everyone understand AI hardware development and apply rapidly evolving large language models to real hardware devices.
+
+If you have any ideas or suggestions, please feel free to raise Issues or join the QQ group: 1011329060
## Star History
@@ -165,4 +169,4 @@ v1 的稳定版本为 1.9.2,可以通过 `git checkout v1` 来切换到 v1 版
-
+
diff --git a/README_cn.md b/README_cn.md
new file mode 100644
index 0000000000..0b53f642e4
--- /dev/null
+++ b/README_cn.md
@@ -0,0 +1,168 @@
+# An MCP-based Chatbot
+
+([中文](README_cn.md) | [English](README.md) | [日本語](README_ja.md)| [Português](README_pt.md))
+
+## 介绍
+
+👉 [人类:给 AI 装摄像头 vs AI:当场发现主人三天没洗头【bilibili】](https://www.bilibili.com/video/BV1bpjgzKEhd/)
+
+👉 [手工打造你的 AI 女友,新手入门教程【bilibili】](https://www.bilibili.com/video/BV1XnmFYLEJN/)
+
+小智 AI 聊天机器人作为一个语音交互入口,利用 Qwen / DeepSeek 等大模型的 AI 能力,通过 MCP 协议实现多端控制。
+
+
+
+### 版本说明
+
+当前 v2 版本与 v1 版本分区表不兼容,所以无法从 v1 版本通过 OTA 升级到 v2 版本。分区表说明参见 [partitions/v2/README.md](partitions/v2/README.md)。
+
+使用 v1 版本的所有硬件,可以通过手动烧录固件来升级到 v2 版本。
+
+v1 的稳定版本为 1.9.2,可以通过 `git checkout v1` 来切换到 v1 版本,该分支会持续维护到 2026 年 2 月。
+
+### 已实现功能
+
+- Wi-Fi / ML307 Cat.1 4G
+- 离线语音唤醒 [ESP-SR](https://github.com/espressif/esp-sr)
+- 支持两种通信协议([Websocket](docs/websocket.md) 或 MQTT+UDP)
+- 采用 OPUS 音频编解码
+- 基于流式 ASR + LLM + TTS 架构的语音交互
+- 声纹识别,识别当前说话人的身份 [3D Speaker](https://github.com/modelscope/3D-Speaker)
+- OLED / LCD 显示屏,支持表情显示
+- 电量显示与电源管理
+- 支持多语言(中文、英文、日文)
+- 支持 ESP32-C3、ESP32-S3、ESP32-P4 芯片平台
+- 通过设备端 MCP 实现设备控制(音量、灯光、电机、GPIO 等)
+- 通过云端 MCP 扩展大模型能力(智能家居控制、PC桌面操作、知识搜索、邮件收发等)
+- 自定义唤醒词、字体、表情与聊天背景,支持网页端在线修改 ([自定义Assets生成器](https://github.com/78/xiaozhi-assets-generator))
+
+## 硬件
+
+### 面包板手工制作实践
+
+详见飞书文档教程:
+
+👉 [《小智 AI 聊天机器人百科全书》](https://ccnphfhqs21z.feishu.cn/wiki/F5krwD16viZoF0kKkvDcrZNYnhb?from=from_copylink)
+
+面包板效果图如下:
+
+
+
+### 支持 70 多个开源硬件(仅展示部分)
+
+- 立创·实战派 ESP32-S3 开发板
+- 乐鑫 ESP32-S3-BOX3
+- M5Stack CoreS3
+- M5Stack AtomS3R + Echo Base
+- 神奇按钮 2.4
+- 微雪电子 ESP32-S3-Touch-AMOLED-1.8
+- LILYGO T-Circle-S3
+- 虾哥 Mini C3
+- 璀璨·AI 吊坠
+- 无名科技 Nologo-星智-1.54TFT
+- SenseCAP Watcher
+- ESP-HI 超低成本机器狗
+
+
-
-## Software
-
-### Firmware Flashing
-
-For beginners, it is recommended to use the firmware that can be flashed without setting up a development environment.
-
-The firmware connects to the official [xiaozhi.me](https://xiaozhi.me) server by default. Personal users can register an account to use the Qwen real-time model for free.
-
-👉 [Beginner's Firmware Flashing Guide](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)
-
-### Development Environment
-
-- Cursor or VSCode
-- Install ESP-IDF plugin, select SDK version 5.4 or above
-- Linux is better than Windows for faster compilation and fewer driver issues
-- This project uses Google C++ code style, please ensure compliance when submitting code
-
-### Developer Documentation
-
-- [Custom Board Guide](docs/custom-board.md) - Learn how to create custom boards for XiaoZhi AI
-- [MCP Protocol IoT Control Usage](docs/mcp-usage.md) - Learn how to control IoT devices via MCP protocol
-- [MCP Protocol Interaction Flow](docs/mcp-protocol.md) - Device-side MCP protocol implementation
-- [MQTT + UDP Hybrid Communication Protocol Document](docs/mqtt-udp.md)
-- [A detailed WebSocket communication protocol document](docs/websocket.md)
-
-## Large Model Configuration
-
-If you already have a XiaoZhi AI chatbot device and have connected to the official server, you can log in to the [xiaozhi.me](https://xiaozhi.me) console for configuration.
-
-👉 [Backend Operation Video Tutorial (Old Interface)](https://www.bilibili.com/video/BV1jUCUY2EKM/)
-
-## Related Open Source Projects
-
-For server deployment on personal computers, refer to the following open-source projects:
-
-- [xinnan-tech/xiaozhi-esp32-server](https://github.com/xinnan-tech/xiaozhi-esp32-server) Python server
-- [joey-zhou/xiaozhi-esp32-server-java](https://github.com/joey-zhou/xiaozhi-esp32-server-java) Java server
-- [AnimeAIChat/xiaozhi-server-go](https://github.com/AnimeAIChat/xiaozhi-server-go) Golang server
-
-Other client projects using the XiaoZhi communication protocol:
-
-- [huangjunsen0406/py-xiaozhi](https://github.com/huangjunsen0406/py-xiaozhi) Python client
-- [TOM88812/xiaozhi-android-client](https://github.com/TOM88812/xiaozhi-android-client) Android client
-- [100askTeam/xiaozhi-linux](http://github.com/100askTeam/xiaozhi-linux) Linux client by 100ask
-- [78/xiaozhi-sf32](https://github.com/78/xiaozhi-sf32) Bluetooth chip firmware by Sichuan
-- [QuecPython/solution-xiaozhiAI](https://github.com/QuecPython/solution-xiaozhiAI) QuecPython firmware by Quectel
-
-Custom Assets Tools:
-
-- [78/xiaozhi-assets-generator](https://github.com/78/xiaozhi-assets-generator) Custom Assets Generator (Wake words, fonts, emojis, backgrounds)
-
-## About the Project
-
-This is an open-source ESP32 project, released under the MIT license, allowing anyone to use it for free, including for commercial purposes.
-
-We hope this project helps everyone understand AI hardware development and apply rapidly evolving large language models to real hardware devices.
-
-If you have any ideas or suggestions, please feel free to raise Issues or join the QQ group: 1011329060
-
-## Star History
-
-
-
-
-
-
-
-
diff --git a/README_ja.md b/README_ja.md
index c7dd029e6e..88f7c52a9c 100644
--- a/README_ja.md
+++ b/README_ja.md
@@ -1,6 +1,6 @@
# MCP ベースのチャットボット
-(日本語 | [中文](README.md) | [English](README_en.md))
+([中文](README_cn.md) | [English](README.md) | [日本語](README_ja.md)| [Português](README_pt.md))
## はじめに
diff --git a/README_pt.md b/README_pt.md
new file mode 100644
index 0000000000..5b741a6c90
--- /dev/null
+++ b/README_pt.md
@@ -0,0 +1,168 @@
+# Um Chatbot baseado em MCP
+
+([中文](README_cn.md) | [English](README.md) | [日本語](README_ja.md)| [Português](README_pt.md))
+
+## Introdução
+
+👉 [Humano: Instale uma câmera para IA vs IA: foi descoberto no local que o proprietário não lavava o cabelo há três dias [bilibili]](https://www.bilibili.com/video/BV1bpjgzKEhd/)
+
+👉 [Crie sua namorada IA manualmente, tutorial introdutório para iniciantes [bilibili]](https://www.bilibili.com/video/BV1XnmFYLEJN/)
+
+Como um portal de interação por voz, o chatbot Xiaozhi AI usa os recursos de IA de grandes modelos como Qwen/DeepSeek para obter controle multiterminal por meio do protocolo MCP.
+
+
+
+### Notas de versão
+
+A versão v2 atual é incompatível com a tabela de partição da versão v1, portanto a atualização OTA de v1 para v2 não pode ser executada. Para obter uma descrição da tabela de partições, consulte [partitions/v2/README.md](partitions/v2/README.md).
+
+Todo o hardware que usa v1 pode ser atualizado para v2 atualizando manualmente o firmware.
+
+A versão estável da v1 é 1.9.2. Você pode mudar para a versão v1 através do `git checkout v1`. Esta agência continuará a ser mantida até fevereiro de 2026.
+
+### Função implementada
+
+- Wi-Fi / ML307 Cat.1 4G
+- Ativação por voz offline [ESP-SR](https://github.com/espressif/esp-sr)
+- Suporta dois protocolos de comunicação ([Websocket](docs/websocket.md) ou MQTT+UDP)
+- Usando o codec de áudio OPUS
+- Interação de voz baseada em arquitetura de streaming ASR + LLM + TTS
+- Reconhecimento de impressão de voz, identificando a identidade do locutor atual [3D Speaker](https://github.com/modelscope/3D-Speaker)
+- Tela OLED/LCD, suporta exibição de expressão
+- Exibição da bateria e gerenciamento de energia
+- Suporta vários idiomas (chinês, inglês, japonês)
+- Suporta plataformas de chips ESP32-C3, ESP32-S3, ESP32-P4
+- Controle de dispositivos (volume, iluminação, motor, GPIO, etc.) através do MCP do lado do dispositivo
+- Expanda os recursos de modelos grandes (controle doméstico inteligente, operação de desktop de PC, pesquisa de conhecimento, envio e recebimento de e-mails, etc.) por meio do MCP na nuvem
+- Personalize palavras de ativação, fontes, emoticons e planos de fundo de bate-papo, suporte para modificação on-line na web ([Gerador de ativos personalizados](https://github.com/78/xiaozhi-assets-generator))
+
+## Hardware
+
+### Prática artesanal de tábua de pão
+
+Para obter detalhes, consulte o tutorial de documentação do Feishu:
+
+👉 ["Enciclopédia Xiaozhi AI Chatbot"](https://ccnphfhqs21z.feishu.cn/wiki/F5krwD16viZoF0kKkvDcrZNYnhb?from=from_copylink)
+
+A renderização da placa de ensaio é a seguinte:
+
+
+
+### Suporta mais de 70 hardwares de código aberto (apenas parte mostrada)
+
+- Placa de desenvolvimento Lichuang·Jianzhanpai ESP32-S3
+- Espressif Systems ESP32-S3-BOX3
+- M5Stack CoreS3
+- M5Stack AtomS3R + Echo Base
+- 神奇按钮 2.4
+- Weixue Electronics ESP32-S3-Touch-AMOLED-1.8
+- LILYGO T-Circle-S3
+- Xia Ge Mini C3
+- Pingente de IA brilhante
+- 无名科技 Nologo-Xingzhi-1.54TFT
+- SenseCAP Watcher
+- Cão-robô de custo ultrabaixo ESP-HI
+
+
+
+## Software
+
+### Queima de firmware
+
+Recomenda-se que os novatos não configurem um ambiente de desenvolvimento pela primeira vez, mas usem diretamente o firmware que não precisa ser gravado em um ambiente de desenvolvimento.
+
+O firmware está conectado ao servidor oficial [xiaozhi.me](https://xiaozhi.me) por padrão. Usuários individuais que registram uma conta podem usar modelos em tempo real Qwen gratuitamente.
+
+👉 [Tutorial de gravação de firmware para iniciantes](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)
+
+### Ambiente de desenvolvimento
+
+- Cursor ou VSCode
+- Instale o plug-in ESP-IDF e selecione SDK versão 5.4 ou superior
+- Linux é melhor que Windows, a velocidade de compilação é rápida e evita problemas de driver
+- Este projeto usa o estilo de codificação Google C++, certifique-se de que ele esteja em conformidade com as especificações ao enviar o código
+
+### Documentação do desenvolvedor
+
+- [Guia da placa de desenvolvimento personalizada](docs/custom-board_pt.md) - Aprenda como criar uma placa de desenvolvimento personalizada para Xiaozhi AI
+- [Instruções de uso de controle de IoT do protocolo MCP](docs/mcp-usage_pt.md) - Aprenda como controlar dispositivos IoT por meio do protocolo MCP
+- [Processo de interação do protocolo MCP](docs/mcp-protocol_pt.md) - Método de implementação do protocolo MCP do lado do dispositivo
+- [documento do protocolo de comunicação híbrida MQTT + UDP](docs/mqtt-udp_pt.md)
+- [Um documento detalhado do protocolo de comunicação WebSocket](docs/websocket_pt.md)
+
+## Configuração de modelo grande
+
+Se você já possui um dispositivo chatbot Xiaozhi AI e se conectou ao servidor oficial, você pode fazer login no console [xiaozhi.me](https://xiaozhi.me) para configurá-lo.
+
+👉 [Tutorial em vídeo de operação de back-end (interface da versão antiga)](https://www.bilibili.com/video/BV1jUCUY2EKM/)
+
+## Projetos de código aberto relacionados
+
+Para implantar um servidor em um computador pessoal, você pode consultar os seguintes projetos de código aberto de terceiros:
+
+- [xinnan-tech/xiaozhi-esp32-server](https://github.com/xinnan-tech/xiaozhi-esp32-server) Servidor Python
+- [joey-zhou/xiaozhi-esp32-server-java](https://github.com/joey-zhou/xiaozhi-esp32-server-java) Servidor Java
+- [AnimeAIChat/xiaozhi-server-go](https://github.com/AnimeAIChat/xiaozhi-server-go) Servidor Golang
+
+Projetos de clientes de terceiros usando protocolo de comunicação Xiaozhi:
+
+- [huangjunsen0406/py-xiaozhi](https://github.com/huangjunsen0406/py-xiaozhi) Cliente Python
+- [TOM88812/xiaozhi-android-client](https://github.com/TOM88812/xiaozhi-android-client) Cliente Android
+- [100askTeam/xiaozhi-linux](http://github.com/100askTeam/xiaozhi-linux) Cliente Linux fornecido pela Baiwen Technology
+- [78/xiaozhi-sf32](https://github.com/78/xiaozhi-sf32) Firmware do chip Bluetooth da Sich Technology
+- [QuecPython/solution-xiaozhiAI](https://github.com/QuecPython/solution-xiaozhiAI) Firmware QuecPython fornecido pela Quectel
+
+## Sobre o projeto
+
+Este é um projeto ESP32 de código aberto do Brother Xi, lançado sob a licença do MIT, permitindo que qualquer pessoa o use, modifique ou use para fins comerciais gratuitamente.
+
+Esperamos que, por meio deste projeto, possamos ajudar todos a compreender o desenvolvimento de hardware de IA e aplicar os grandes modelos de linguagem em rápido desenvolvimento a dispositivos de hardware reais.
+
+Se você tiver alguma idéia ou sugestão, sinta-se à vontade para levantar questões ou junte-se ao grupo QQ: 1011329060
+
+## Star History
+
+
+
+
+
+
+
+
diff --git a/docs/custom-board_en.md b/docs/custom-board_en.md
new file mode 100644
index 0000000000..7ec246e061
--- /dev/null
+++ b/docs/custom-board_en.md
@@ -0,0 +1,452 @@
+# Custom development board guide
+
+This guide describes how to customize a new development board initialization program for the Xiaozhi AI voice chat robot project. Xiaozhi AI supports more than 70 ESP32 series development boards, and the initialization code of each development board is placed in the corresponding directory.
+
+## IMPORTANT NOTE
+
+> **Warning**: For custom development boards, when the IO configuration is different from the original development board, do not directly overwrite the configuration of the original development board to compile firmware. A new development board type must be created, or distinguished by different name and sdkconfig macro definitions through the builds configuration in the config.json file. Use `python scripts/release.py [development board directory name]` to compile and package the firmware.
+>
+> If you directly overwrite the original configuration, your custom firmware may be overwritten by the standard firmware of the original development board during future OTA upgrades, causing your device to not work properly. Each development board has a unique identification and corresponding firmware upgrade channel. It is very important to maintain the uniqueness of the development board identification.
+
+## Directory structure
+
+The directory structure of each development board usually contains the following files:
+
+- `xxx_board.cc` - The main board-level initialization code, which implements board-related initialization and functions
+- `config.h` - board-level configuration file, which defines hardware pin mapping and other configuration items
+- `config.json` - Compilation configuration, specifying the target chip and special compilation options
+- `README.md` - development board related documentation
+
+## Customized development board steps
+
+### 1. Create a new development board directory
+
+First, create a new directory under the `boards/` directory. The naming method should be in the form of `[brand name]-[development board type]`, for example `m5stack-tab5`:
+
+```bash
+mkdir main/boards/my-custom-board
+```
+
+### 2. Create configuration file
+
+#### config.h
+
+Define all hardware configurations in `config.h`, including:
+
+- Audio sample rate and I2S pin configuration
+- Audio codec chip address and I2C pin configuration
+- Button and LED pin configuration
+- Display parameters and pin configuration
+
+Reference example (from lichuang-c3-dev):
+
+```c
+#ifndef _BOARD_CONFIG_H_
+#define _BOARD_CONFIG_H_
+
+#include
+
+//Audio configuration
+#define AUDIO_INPUT_SAMPLE_RATE 24000
+#define AUDIO_OUTPUT_SAMPLE_RATE 24000
+
+#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_10
+#define AUDIO_I2S_GPIO_WS GPIO_NUM_12
+#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_8
+#define AUDIO_I2S_GPIO_DIN GPIO_NUM_7
+#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_11
+
+#define AUDIO_CODEC_PA_PIN GPIO_NUM_13
+#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_0
+#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_1
+#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
+
+//Button configuration
+#define BOOT_BUTTON_GPIO GPIO_NUM_9
+
+//Display configuration
+#define DISPLAY_SPI_SCK_PIN GPIO_NUM_3
+#define DISPLAY_SPI_MOSI_PIN GPIO_NUM_5
+#define DISPLAY_DC_PIN GPIO_NUM_6
+#define DISPLAY_SPI_CS_PIN GPIO_NUM_4
+
+#define DISPLAY_WIDTH 320
+#define DISPLAY_HEIGHT 240
+#define DISPLAY_MIRROR_X true
+#define DISPLAY_MIRROR_Y false
+#define DISPLAY_SWAP_XY true
+
+#define DISPLAY_OFFSET_X 0
+#define DISPLAY_OFFSET_Y 0
+
+#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_2
+#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true
+
+#endif // _BOARD_CONFIG_H_
+```
+
+#### config.json
+
+Define compilation configuration in `config.json`. This file is used for `scripts/release.py` script automatic compilation:
+
+```json
+{
+ "target": "esp32s3", // Target chip model: esp32, esp32s3, esp32c3, esp32c6, esp32p4, etc.
+ "builds": [
+ {
+ "name": "my-custom-board", // Development board name, used to generate firmware packages
+ "sdkconfig_append": [
+ //Special Flash size configuration
+ "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
+ //Special partition table configuration
+ "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
+ ]
+ }
+ ]
+}
+```
+
+**Configuration item description:**
+- `target`: target chip model, must match the hardware
+- `name`: The name of the compiled firmware package, it is recommended to be consistent with the directory name
+- `sdkconfig_append`: additional sdkconfig configuration item array, which will be appended to the default configuration
+
+**Commonly used sdkconfig_append configuration:**
+```json
+// Flash size
+"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y" // 4MB Flash
+"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y" // 8MB Flash
+"CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y" // 16MB Flash
+
+//Partition table
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/4m.csv\"" // 4MB partition table
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" // 8MB partition table
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/16m.csv\"" // 16MB partition table
+
+// language configuration
+"CONFIG_LANGUAGE_EN_US=y" // English
+"CONFIG_LANGUAGE_ZH_CN=y" // Simplified Chinese
+
+// Wake word configuration
+"CONFIG_USE_DEVICE_AEC=y" // Enable device-side AEC
+"CONFIG_WAKE_WORD_DISABLED=y" // Disable wake words
+```
+
+### 3. Write board-level initialization code
+
+Create a `my_custom_board.cc` file to implement all the initialization logic of the development board.
+
+A basic development board class definition contains the following parts:
+
+1. **Class definition**: Inherited from `WifiBoard` or `Ml307Board`
+2. **Initialization function**: including initialization of I2C, display, buttons, IoT and other components
+3. **Virtual function rewriting**: such as `GetAudioCodec()`, `GetDisplay()`, `GetBacklight()`, etc.
+4. **Register Development Board**: Use `DECLARE_BOARD` macro to register development board
+
+```cpp
+#include "wifi_board.h"
+#include "codecs/es8311_audio_codec.h"
+#include "display/lcd_display.h"
+#include "application.h"
+#include "button.h"
+#include "config.h"
+#include "mcp_server.h"
+
+#include
+#include
+#include
+
+#define TAG "MyCustomBoard"
+
+class MyCustomBoard : public WifiBoard {
+private:
+ i2c_master_bus_handle_t codec_i2c_bus_;
+ Button boot_button_;
+ LcdDisplay* display_;
+
+ //I2C initialization
+ void InitializeI2c() {
+ i2c_master_bus_config_t i2c_bus_cfg = {
+ .i2c_port = I2C_NUM_0,
+ .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
+ .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
+ .clk_source = I2C_CLK_SRC_DEFAULT,
+ .glitch_ignore_cnt = 7,
+ .intr_priority = 0,
+ .trans_queue_depth = 0,
+ .flags = {
+ .enable_internal_pullup = 1,
+ },
+ };
+ ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_));
+ }
+
+ // SPI initialization (for display)
+ void InitializeSpi() {
+ spi_bus_config_t buscfg = {};
+ buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN;
+ buscfg.miso_io_num = GPIO_NUM_NC;
+ buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN;
+ buscfg.quadwp_io_num = GPIO_NUM_NC;
+ buscfg.quadhd_io_num = GPIO_NUM_NC;
+ buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
+ ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
+ }
+
+ //Button initialization
+ void InitializeButtons() {
+ boot_button_.OnClick([this]() {
+ auto& app = Application::GetInstance();
+ if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
+ ResetWifiConfiguration();
+ }
+ app.ToggleChatState();
+ });
+ }
+
+ //Display initialization (take ST7789 as an example)
+ void InitializeDisplay() {
+ esp_lcd_panel_io_handle_t panel_io = nullptr;
+ esp_lcd_panel_handle_t panel = nullptr;
+
+ esp_lcd_panel_io_spi_config_t io_config = {};
+ io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN;
+ io_config.dc_gpio_num = DISPLAY_DC_PIN;
+ io_config.spi_mode = 2;
+ io_config.pclk_hz = 80 * 1000 * 1000;
+ io_config.trans_queue_depth = 10;
+ io_config.lcd_cmd_bits = 8;
+ io_config.lcd_param_bits = 8;
+ ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io));
+
+ esp_lcd_panel_dev_config_t panel_config = {};
+ panel_config.reset_gpio_num = GPIO_NUM_NC;
+ panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
+ panel_config.bits_per_pixel = 16;
+ ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
+
+ esp_lcd_panel_reset(panel);
+ esp_lcd_panel_init(panel);
+ esp_lcd_panel_invert_color(panel, true);
+ esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
+ esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
+
+ //Create display object
+ display_ = new SpiLcdDisplay(panel_io, panel,
+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
+ DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,
+ DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
+ }
+
+ // MCP Tools initialization
+ void InitializeTools() {
+ // Refer to MCP documentation
+ }
+
+public:
+ //Constructor
+ MyCustomBoard() : boot_button_(BOOT_BUTTON_GPIO) {
+ InitializeI2c();
+ InitializeSpi();
+ InitializeDisplay();
+ InitializeButtons();
+ InitializeTools();
+ GetBacklight()->SetBrightness(100);
+ }
+
+ // Get the audio codec
+ virtual AudioCodec* GetAudioCodec() override {
+ static Es8311AudioCodec audio_codec(
+ codec_i2c_bus_,
+ I2C_NUM_0,
+ AUDIO_INPUT_SAMPLE_RATE,
+ AUDIO_OUTPUT_SAMPLE_RATE,
+ AUDIO_I2S_GPIO_MCLK,
+ AUDIO_I2S_GPIO_BCLK,
+ AUDIO_I2S_GPIO_WS,
+ AUDIO_I2S_GPIO_DOUT,
+ AUDIO_I2S_GPIO_DIN,
+ AUDIO_CODEC_PA_PIN,
+ AUDIO_CODEC_ES8311_ADDR);
+ return &audio_codec;
+ }
+
+ // Get the display screen
+ virtual Display* GetDisplay() override {
+ return display_;
+ }
+
+ // Get backlight control
+ virtual Backlight* GetBacklight() override {
+ static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
+ return &backlight;
+ }
+};
+
+//Register development board
+DECLARE_BOARD(MyCustomBoard);
+```
+
+### 4. Add build system configuration
+
+#### Add development board options in Kconfig.projbuild
+
+Open the `main/Kconfig.projbuild` file and add a new development board configuration item in the `choice BOARD_TYPE` section:
+
+```kconfig
+choice BOARD_TYPE
+ prompt "Board Type"
+ default BOARD_TYPE_BREAD_COMPACT_WIFI
+ help
+ Board type. Development board type
+
+ # ...other board options ...
+
+ config BOARD_TYPE_MY_CUSTOM_BOARD
+ bool "My Custom Board (my custom development board)"
+ depends on IDF_TARGET_ESP32S3 # Modify according to your target chip
+endchoice
+```
+
+**Note:**
+- `BOARD_TYPE_MY_CUSTOM_BOARD` is the name of the configuration item. It needs to be in all uppercase letters and separated by underscores.
+- `depends on` specifies the target chip type (such as `IDF_TARGET_ESP32S3`, `IDF_TARGET_ESP32C3`, etc.)
+- The description text can be in Chinese and English
+
+#### Add development board configuration in CMakeLists.txt
+
+Open the `main/CMakeLists.txt` file and add new configuration in the development board type judgment section:
+
+```cmake
+# Add your development board configuration in the elseif chain
+elseif(CONFIG_BOARD_TYPE_MY_CUSTOM_BOARD)
+ set(BOARD_TYPE "my-custom-board") # Same as the directory name
+ set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) #Choose the appropriate font according to the screen size
+ set(BUILTIN_ICON_FONT font_awesome_20_4)
+ set(DEFAULT_EMOJI_COLLECTION twemoji_64) # Optional, if emoticon display is required
+endif()
+```
+
+**Font and emoticon configuration instructions:**
+
+Choose the appropriate font size based on your screen resolution:
+- Small screen (128x64 OLED): `font_puhui_basic_14_1` / `font_awesome_14_1`
+- Small and medium screens (240x240): `font_puhui_basic_16_4` / `font_awesome_16_4`
+- Medium screen (240x320): `font_puhui_basic_20_4` / `font_awesome_20_4`
+- Large screen (480x320+): `font_puhui_basic_30_4` / `font_awesome_30_4`
+
+Emoticon collection options:
+- `twemoji_32` - 32x32 pixel emoticon (small screen)
+- `twemoji_64` - 64x64 pixel emoji (large screen)
+
+### 5. Configuration and compilation
+
+#### Method 1: Manual configuration using idf.py
+
+1. **Set the target chip** (when configuring or replacing the chip for the first time):
+ ```bash
+ # For ESP32-S3
+ idf.py set-target esp32s3
+
+ # For ESP32-C3
+ idf.py set-target esp32c3
+
+ # For ESP32
+ idf.py set-target esp32
+ ```
+
+2. **Clean up old configuration**:
+ ```bash
+ idf.py fullclean
+ ```
+
+3. **Enter configuration menu**:
+ ```bash
+ idf.py menuconfig
+ ```
+
+ Navigate to: `Xiaozhi Assistant` -> `Board Type` in the menu and select your custom development board.
+
+4. **Compile and Burn**:
+ ```bash
+ idf.py build
+ idf.py flash monitor
+ ```
+
+#### Method 2: Use the release.py script (recommended)
+
+If you have a `config.json` file in your development board directory, you can use this script to automatically complete configuration and compilation:
+
+```bash
+python scripts/release.py my-custom-board
+```
+
+This script automatically:
+- Read the `target` configuration in `config.json` and set the target chip
+- Apply compilation options in `sdkconfig_append`
+- Compile and package firmware
+
+### 6. Create README.md
+
+The characteristics, hardware requirements, compilation and burning steps of the development board are described in README.md:
+
+
+## Common development board components
+
+### 1. Display
+
+The project supports a variety of display drivers, including:
+- ST7789 (SPI)
+- ILI9341 (SPI)
+- SH8601 (QSPI)
+- wait...
+
+### 2. Audio codec
+
+Supported codecs include:
+- ES8311 (commonly used)
+- ES7210 (microphone array)
+- AW88298 (power amplifier)
+- wait...
+
+### 3. Power management
+
+Some development boards use power management chips:
+- AXP2101
+- Other PMICs available
+
+### 4. MCP device control
+
+Various MCP tools can be added to enable the AI to use:
+- Speaker (speaker control)
+- Screen (screen brightness adjustment)
+- Battery (battery level reading)
+- Light (light control)
+- wait...
+
+## Development board class inheritance relationship
+
+- `Board` - basic board level class
+ - `WifiBoard` - Wi-Fi connected development board
+ - `Ml307Board` - Development board using 4G module
+ - `DualNetworkBoard` - Development board that supports Wi-Fi and 4G network switching
+
+## Development skills
+
+1. **Refer to similar development boards**: If your new development board is similar to the existing development board, you can refer to the existing implementation
+2. **Step-by-step debugging**: First implement basic functions (such as display), and then add more complex functions (such as audio)
+3. **Pin Mapping**: Make sure all pin mappings are configured correctly in config.h
+4. **Check Hardware Compatibility**: Confirm compatibility of all chips and drivers
+
+## Possible problems
+
+1. **Display is abnormal**: Check SPI configuration, mirroring settings and color inversion settings
+2. **No audio output**: Check I2S configuration, PA enable pin and codec address
+3. **Unable to connect to network**: Check Wi-Fi credentials and network configuration
+4. **Unable to communicate with server**: Check MQTT or WebSocket configuration
+
+## References
+
+- ESP-IDF documentation: https://docs.espressif.com/projects/esp-idf/
+- LVGL documentation: https://docs.lvgl.io/
+- ESP-SR documentation: https://github.com/espressif/esp-sr
\ No newline at end of file
diff --git a/docs/custom-board_pt.md b/docs/custom-board_pt.md
new file mode 100644
index 0000000000..c443fec98e
--- /dev/null
+++ b/docs/custom-board_pt.md
@@ -0,0 +1,452 @@
+# Guia da placa de desenvolvimento personalizado
+
+Este guia descreve como personalizar um novo programa de inicialização da placa de desenvolvimento para o projeto do robô de bate-papo por voz Xiaozhi AI. Xiaozhi AI suporta mais de 70 placas de desenvolvimento da série ESP32, e o código de inicialização de cada placa de desenvolvimento é colocado no diretório correspondente.
+
+## NOTA IMPORTANTE
+
+> **Aviso**: Para placas de desenvolvimento personalizadas, quando a configuração IO for diferente da placa de desenvolvimento original, não substitua diretamente a configuração da placa de desenvolvimento original para compilar o firmware. Um novo tipo de placa de desenvolvimento deve ser criado ou diferenciado por nomes diferentes e definições de macro sdkconfig por meio da configuração de builds no arquivo config.json. Use `python scripts/release.py [nome do diretório da placa de desenvolvimento]` para compilar e empacotar o firmware.
+>
+> Se você substituir diretamente a configuração original, seu firmware personalizado poderá ser substituído pelo firmware padrão da placa de desenvolvimento original durante futuras atualizações OTA, fazendo com que seu dispositivo não funcione corretamente. Cada placa de desenvolvimento possui uma identificação exclusiva e um canal de atualização de firmware correspondente. É muito importante manter a singularidade da identificação da placa de desenvolvimento.
+
+## Estrutura de diretório
+
+A estrutura de diretórios de cada placa de desenvolvimento geralmente contém os seguintes arquivos:
+
+- `xxx_board.cc` - O código principal de inicialização em nível de placa, que implementa inicialização e funções relacionadas à placa
+- `config.h` - arquivo de configuração em nível de placa, que define o mapeamento de pinos de hardware e outros itens de configuração
+- `config.json` - Configuração de compilação, especificando o chip de destino e opções especiais de compilação
+- `README.md` - documentação relacionada à placa de desenvolvimento
+
+## Etapas do quadro de desenvolvimento personalizado
+
+### 1. Crie um novo diretório da placa de desenvolvimento
+
+Primeiro, crie um novo diretório no diretório `boards/`. O método de nomenclatura deve estar no formato `[nome da marca]-[tipo de placa de desenvolvimento]`, por exemplo `m5stack-tab5`:
+
+```bash
+mkdir main/boards/my-custom-board
+```
+
+### 2. Criar arquivo de configuração
+
+#### config.h
+
+Defina todas as configurações de hardware em `config.h`, incluindo:
+
+- Taxa de amostragem de áudio e configuração de pinos I2S
+- Endereço do chip do codec de áudio e configuração do pino I2C
+- Configuração de botões e pinos de LED
+- Exibir parâmetros e configuração de pinos
+
+Exemplo de referência (de lichuang-c3-dev):
+
+```c
+#ifndef _BOARD_CONFIG_H_
+#define _BOARD_CONFIG_H_
+
+#include
+
+//Configuração de áudio
+#define AUDIO_INPUT_SAMPLE_RATE 24000
+#define AUDIO_OUTPUT_SAMPLE_RATE 24000
+
+#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_10
+#define AUDIO_I2S_GPIO_WS GPIO_NUM_12
+#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_8
+#define AUDIO_I2S_GPIO_DIN GPIO_NUM_7
+#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_11
+
+#define AUDIO_CODEC_PA_PIN GPIO_NUM_13
+#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_0
+#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_1
+#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
+
+//Configuração do botão
+#define BOOT_BUTTON_GPIO GPIO_NUM_9
+
+//Configuração de exibição
+#define DISPLAY_SPI_SCK_PIN GPIO_NUM_3
+#define DISPLAY_SPI_MOSI_PIN GPIO_NUM_5
+#define DISPLAY_DC_PIN GPIO_NUM_6
+#define DISPLAY_SPI_CS_PIN GPIO_NUM_4
+
+#define DISPLAY_WIDTH 320
+#define DISPLAY_HEIGHT 240
+#define DISPLAY_MIRROR_X true
+#define DISPLAY_MIRROR_Y false
+#define DISPLAY_SWAP_XY true
+
+#define DISPLAY_OFFSET_X 0
+#define DISPLAY_OFFSET_Y 0
+
+#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_2
+#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true
+
+#endif // _BOARD_CONFIG_H_
+```
+
+#### config.json
+
+Defina a configuração de compilação em `config.json`. Este arquivo é usado para compilação automática do script `scripts/release.py`:
+
+```json
+{
+ "target": "esp32s3", // Modelo de chip alvo: esp32, esp32s3, esp32c3, esp32c6, esp32p4, etc.
+ "builds": [
+ {
+ "name": "my-custom-board", // Nome da placa de desenvolvimento, usada para gerar pacotes de firmware
+ "sdkconfig_append": [
+ //Configuração especial do tamanho do Flash
+ "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
+ //Configuração especial da tabela de partições
+ "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
+ ]
+ }
+ ]
+}
+```
+
+**Descrição do item de configuração:**
+- `target`: modelo do chip alvo, deve corresponder ao hardware
+- `name`: O nome do pacote de firmware compilado, é recomendado que seja consistente com o nome do diretório
+- `sdkconfig_append`: array adicional de itens de configuração sdkconfig, que será anexado à configuração padrão
+
+**Configuração sdkconfig_append comumente usada:**
+```json
+//Tamanho do Flash
+"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y" // 4MB Flash
+"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y" // 8MB Flash
+"CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y" // 16MB Flash
+
+//Tabela de partição
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/4m.csv\"" // tabela de partições de 4 MB
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" // tabela de partições de 8 MB
+"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/16m.csv\"" // tabela de partição de 16 MB
+
+//configuração de idioma
+"CONFIG_LANGUAGE_EN_US=y" // Inglês
+"CONFIG_LANGUAGE_ZH_CN=y" // Chinês simplificado
+
+//Configuração da palavra de ativação
+"CONFIG_USE_DEVICE_AEC=y" // Habilita AEC do lado do dispositivo
+"CONFIG_WAKE_WORD_DISABLED=y" // Desativa palavras de ativação
+```
+
+### 3. Escreva o código de inicialização no nível da placa
+
+Crie um arquivo `my_custom_board.cc` para implementar toda a lógica de inicialização da placa de desenvolvimento.
+
+Uma definição básica de classe de placa de desenvolvimento contém as seguintes partes:
+
+1. **Definição de classe**: Herdado de `WifiBoard` ou `Ml307Board`
+2. **Função de inicialização**: incluindo inicialização de I2C, display, botões, IoT e outros componentes
+3. **Reescrita de função virtual**: como `GetAudioCodec()`, `GetDisplay()`, `GetBacklight()`, etc.
+4. **Registrar placa de desenvolvimento**: Use a macro `DECLARE_BOARD` para registrar a placa de desenvolvimento
+
+```cpp
+#include "wifi_board.h"
+#include "codecs/es8311_audio_codec.h"
+#include "display/lcd_display.h"
+#include "application.h"
+#include "button.h"
+#include "config.h"
+#include "mcp_server.h"
+
+#include
+#include
+#include
+
+#define TAG "MyCustomBoard"
+
+class MyCustomBoard : public WifiBoard {
+private:
+ i2c_master_bus_handle_t codec_i2c_bus_;
+ Button boot_button_;
+ LcdDisplay* display_;
+
+ //Inicialização I2C
+ void InitializeI2c() {
+ i2c_master_bus_config_t i2c_bus_cfg = {
+ .i2c_port = I2C_NUM_0,
+ .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
+ .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
+ .clk_source = I2C_CLK_SRC_DEFAULT,
+ .glitch_ignore_cnt = 7,
+ .intr_priority = 0,
+ .trans_queue_depth = 0,
+ .flags = {
+ .enable_internal_pullup = 1,
+ },
+ };
+ ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_));
+ }
+
+ // inicialização SPI (para exibição)
+ void InitializeSpi() {
+ spi_bus_config_t buscfg = {};
+ buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN;
+ buscfg.miso_io_num = GPIO_NUM_NC;
+ buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN;
+ buscfg.quadwp_io_num = GPIO_NUM_NC;
+ buscfg.quadhd_io_num = GPIO_NUM_NC;
+ buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
+ ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
+ }
+
+ //Inicialização do botão
+ void InitializeButtons() {
+ boot_button_.OnClick([this]() {
+ auto& app = Application::GetInstance();
+ if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
+ ResetWifiConfiguration();
+ }
+ app.ToggleChatState();
+ });
+ }
+
+ //Inicialização do display (tome ST7789 como exemplo)
+ void InitializeDisplay() {
+ esp_lcd_panel_io_handle_t panel_io = nullptr;
+ esp_lcd_panel_handle_t panel = nullptr;
+
+ esp_lcd_panel_io_spi_config_t io_config = {};
+ io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN;
+ io_config.dc_gpio_num = DISPLAY_DC_PIN;
+ io_config.spi_mode = 2;
+ io_config.pclk_hz = 80 * 1000 * 1000;
+ io_config.trans_queue_depth = 10;
+ io_config.lcd_cmd_bits = 8;
+ io_config.lcd_param_bits = 8;
+ ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io));
+
+ esp_lcd_panel_dev_config_t panel_config = {};
+ panel_config.reset_gpio_num = GPIO_NUM_NC;
+ panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
+ panel_config.bits_per_pixel = 16;
+ ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
+
+ esp_lcd_panel_reset(panel);
+ esp_lcd_panel_init(panel);
+ esp_lcd_panel_invert_color(panel, true);
+ esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
+ esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
+
+ //Cria objeto de exibição
+ display_ = new SpiLcdDisplay(panel_io, panel,
+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
+ DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,
+ DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
+ }
+
+ // Inicialização das ferramentas MCP
+ void InitializeTools() {
+ // Consulte a documentação do MCP
+ }
+
+public:
+ //Construtor
+ MyCustomBoard() : boot_button_(BOOT_BUTTON_GPIO) {
+ InitializeI2c();
+ InitializeSpi();
+ InitializeDisplay();
+ InitializeButtons();
+ InitializeTools();
+ GetBacklight()->SetBrightness(100);
+ }
+
+ //Obtém o codec de áudio
+ virtual AudioCodec* GetAudioCodec() override {
+ static Es8311AudioCodec audio_codec(
+ codec_i2c_bus_,
+ I2C_NUM_0,
+ AUDIO_INPUT_SAMPLE_RATE,
+ AUDIO_OUTPUT_SAMPLE_RATE,
+ AUDIO_I2S_GPIO_MCLK,
+ AUDIO_I2S_GPIO_BCLK,
+ AUDIO_I2S_GPIO_WS,
+ AUDIO_I2S_GPIO_DOUT,
+ AUDIO_I2S_GPIO_DIN,
+ AUDIO_CODEC_PA_PIN,
+ AUDIO_CODEC_ES8311_ADDR);
+ return &audio_codec;
+ }
+
+ // Obtém a tela de exibição
+ virtual Display* GetDisplay() override {
+ return display_;
+ }
+
+ // Obtém o controle da luz de fundo
+ virtual Backlight* GetBacklight() override {
+ static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
+ return &backlight;
+ }
+};
+
+//Registra o quadro de desenvolvimento
+DECLARE_BOARD(MyCustomBoard);
+```
+
+### 4. Adicionar configuração do sistema de compilação
+
+#### Adicione opções de placa de desenvolvimento em Kconfig.projbuild
+
+Abra o arquivo `main/Kconfig.projbuild` e adicione um novo item de configuração da placa de desenvolvimento na seção `choice BOARD_TYPE`:
+
+```kconfig
+choice BOARD_TYPE
+ prompt "Board Type"
+ default BOARD_TYPE_BREAD_COMPACT_WIFI
+ help
+ Tipo de placa. Tipo de placa de desenvolvimento
+
+ # ...outras opções de placa...
+
+ config BOARD_TYPE_MY_CUSTOM_BOARD
+ bool "Meu quadro personalizado (meu quadro de desenvolvimento personalizado)"
+ depende de IDF_TARGET_ESP32S3 # Modifique de acordo com seu chip alvo
+endchoice
+```
+
+**Observação:**
+- `BOARD_TYPE_MY_CUSTOM_BOARD` é o nome do item de configuração. Ele precisa estar em letras maiúsculas e separado por sublinhados.
+- `depends on` especifica o tipo de chip alvo (como `IDF_TARGET_ESP32S3`, `IDF_TARGET_ESP32C3`, etc.)
+- O texto da descrição pode estar em chinês e inglês
+
+#### Adicione a configuração da placa de desenvolvimento em CMakeLists.txt
+
+Abra o arquivo `main/CMakeLists.txt` e adicione uma nova configuração na seção de julgamento do tipo de placa de desenvolvimento:
+
+```cmake
+# Adicione a configuração da sua placa de desenvolvimento na cadeia elseif
+elseif(CONFIG_BOARD_TYPE_MY_CUSTOM_BOARD)
+ set(BOARD_TYPE "my-custom-board") # Igual ao nome do diretório
+ set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) #Escolha a fonte apropriada de acordo com o tamanho da tela
+ set(BUILTIN_ICON_FONT font_awesome_20_4)
+ set(DEFAULT_EMOJI_COLLECTION twemoji_64) # Opcional, se a exibição de emoticons for necessária
+endif()
+```
+
+**Instruções de configuração de fontes e emoticons:**
+
+Escolha o tamanho de fonte apropriado com base na resolução da tela:
+- Tela pequena (128x64 OLED): `font_puhui_basic_14_1` / `font_awesome_14_1`
+- Telas pequenas e médias (240x240): `font_puhui_basic_16_4` / `font_awesome_16_4`
+- Tela média (240x320): `font_puhui_basic_20_4` / `font_awesome_20_4`
+- Tela grande (480x320+): `font_puhui_basic_30_4` / `font_awesome_30_4`
+
+Opções de coleta de emoticons:
+- `twemoji_32` - emoticon de 32x32 pixels (tela pequena)
+- `twemoji_64` - emoji de 64x64 pixels (tela grande)
+
+### 5. Configuração e compilação
+
+#### Método 1: configuração manual usando idf.py
+
+1. **Defina o chip alvo** (ao configurar ou substituir o chip pela primeira vez):
+ ```bash
+ # Para ESP32-S3
+ idf.py set-target esp32s3
+
+ # Para ESP32-C3
+ idf.py set-target esp32c3
+
+ #Para ESP32
+ idf.py set-target esp32
+ ```
+
+2. **Limpar configuração antiga**:
+ ```bash
+ idf.py fullclean
+ ```
+
+3. **Entre no menu de configuração**:
+ ```bash
+ idf.py menuconfig
+ ```
+
+ Navegue até: `Xiaozhi Assistant` -> `Board Type` no menu e selecione sua placa de desenvolvimento personalizada.
+
+4. **Compilar e gravar**:
+ ```bash
+ idf.py build
+ idf.py flash monitor
+ ```
+
+#### Método 2: Use o script release.py (recomendado)
+
+Se você tiver um arquivo `config.json` no diretório da placa de desenvolvimento, você pode usar este script para concluir automaticamente a configuração e compilação:
+
+```bash
+python scripts/release.py my-custom-board
+```
+
+Este script automaticamente:
+- Leia a configuração `target` em `config.json` e defina o chip alvo
+- Aplicar opções de compilação em `sdkconfig_append`
+- Compilar e empacotar firmware
+
+### 6. Crie README.md
+
+As características, requisitos de hardware, etapas de compilação e gravação da placa de desenvolvimento estão descritas em README.md:
+
+
+## Componentes comuns da placa de desenvolvimento
+
+### 1. Exibição
+
+O projeto oferece suporte a uma variedade de drivers de vídeo, incluindo:
+- ST7789 (SPI)
+- ILI9341 (SPI)
+- SH8601 (QSPI)
+- espere...
+
+### 2. Codec de áudio
+
+Os codecs suportados incluem:
+- ES8311 (comumente usado)
+- ES7210 (conjunto de microfones)
+- AW88298 (amplificador de potência)
+- espere...
+
+### 3. Gerenciamento de energia
+
+Algumas placas de desenvolvimento usam chips de gerenciamento de energia:
+- AXP2101
+- Outros PMICs disponíveis
+
+### 4. Controle do dispositivo MCP
+
+Várias ferramentas MCP podem ser adicionadas para permitir o uso da IA:
+- Alto-falante (controle de alto-falante)
+- Tela (ajuste de brilho da tela)
+- Bateria (leitura do nível da bateria)
+- Luz (controle de luz)
+- espere...
+
+## Relacionamento de herança de classe da placa de desenvolvimento
+
+- `Board` - classe básica de nível de conselho
+ - `WifiBoard` - placa de desenvolvimento conectada por Wi-Fi
+ - `Ml307Board` - Placa de desenvolvimento usando módulo 4G
+ - `DualNetworkBoard` - Placa de desenvolvimento que suporta comutação de rede Wi-Fi e 4G
+
+## Habilidades de desenvolvimento
+
+1. **Consulte placas de desenvolvimento semelhantes**: Se sua nova placa de desenvolvimento for semelhante à placa de desenvolvimento existente, você pode consultar a implementação existente
+2. **Depuração passo a passo**: primeiro implemente funções básicas (como exibição) e, em seguida, adicione funções mais complexas (como áudio)
+3. **Mapeamento de pinos**: certifique-se de que todos os mapeamentos de pinos estejam configurados corretamente em config.h
+4. **Verifique a compatibilidade de hardware**: Confirme a compatibilidade de todos os chips e drivers
+
+## Possíveis problemas
+
+1. **A exibição está anormal**: Verifique a configuração SPI, configurações de espelhamento e configurações de inversão de cores
+2. **Sem saída de áudio**: Verifique a configuração I2S, o pino de habilitação do PA e o endereço do codec
+3. **Não é possível conectar-se à rede**: verifique as credenciais de Wi-Fi e a configuração da rede
+4. **Não é possível se comunicar com o servidor**: Verifique a configuração do MQTT ou WebSocket
+
+## Referências
+
+- Documentação ESP-IDF: https://docs.espressif.com/projects/esp-idf/
+- Documentação LVGL: https://docs.lvgl.io/
+- Documentação ESP-SR: https://github.com/espressif/esp-sr
\ No newline at end of file
diff --git a/docs/mcp-protocol_en.md b/docs/mcp-protocol_en.md
new file mode 100644
index 0000000000..05c4b8f2c6
--- /dev/null
+++ b/docs/mcp-protocol_en.md
@@ -0,0 +1,269 @@
+#MCP (Model Context Protocol) interaction process
+
+NOTICE: AI-assisted generation, when implementing background services, please refer to the code to confirm the details!!
+
+The MCP protocol in this project is used for communication between the backend API (MCP client) and the ESP32 device (MCP server) so that the backend can discover and call the functions (tools) provided by the device.
+
+## Protocol format
+
+According to the code (`main/protocols/protocol.cc`, `main/mcp_server.cc`), MCP messages are encapsulated in the message body of the underlying communication protocol (such as WebSocket or MQTT). Its internal structure follows the [JSON-RPC 2.0](https://www.jsonrpc.org/specification) specification.
+
+Example of overall message structure:
+
+```json
+{
+ "session_id": "...", // Session ID
+ "type": "mcp", // Message type, fixed to "mcp"
+ "payload": { // JSON-RPC 2.0 payload
+ "jsonrpc": "2.0",
+ "method": "...", // method name (such as "initialize", "tools/list", "tools/call")
+ "params": { ... }, // method parameters (for request)
+ "id": ..., // Request ID (for request and response)
+ "result": { ... }, // Method execution result (for success response)
+ "error": { ... } // Error message (for error response)
+ }
+}
+```
+
+Among them, the `payload` part is a standard JSON-RPC 2.0 message:
+
+- `jsonrpc`: fixed string "2.0".
+- `method`: The name of the method to be called (for Request).
+- `params`: The parameters of the method, a structured value, usually an object (for Request).
+- `id`: The identifier of the request, provided by the client when sending the request, and returned as is when the server responds. Used to match requests and responses.
+- `result`: The result when the method executes successfully (for Success Response).
+- `error`: Error message when method execution fails (for Error Response).
+
+## Interaction process and sending time
+
+The interaction of MCP mainly revolves around the client (backend API) discovering and calling the "tools" on the device.
+
+1. **Connection establishment and capability notification**
+
+ - **Timing:** After the device boots up and successfully connects to the backend API.
+ - **Sender:** Device.
+ - **Message:** The device sends a basic protocol "hello" message to the backend API, which contains a list of capabilities supported by the device, for example by supporting the MCP protocol (`"mcp": true`).
+ - **Example (not MCP payload, but underlying protocol message):**
+ ```json
+ {
+ "type": "hello",
+ "version": ...,
+ "features": {
+ "mcp": true,
+ ...
+ },
+ "transport": "websocket", // or "mqtt"
+ "audio_params": { ... },
+ "session_id": "..." // The device may be set after receiving hello from the server
+ }
+ ```
+
+2. **Initialize MCP session**
+
+ - **Timing:** After the background API receives the device "hello" message and confirms that the device supports MCP, it is usually sent as the first request of the MCP session.
+ - **Sender:** Backend API (Client).
+ - **Method:** `initialize`
+ - **Message (MCP payload):**
+
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "initialize",
+ "params": {
+ "capabilities": {
+ // Client capabilities, optional
+
+ //Camera vision related
+ "vision": {
+ "url": "...", //Camera: Image processing address (must be an http address, not a websocket address)
+ "token": "..." // url token
+ }
+
+ // ...other client capabilities
+ }
+ },
+ "id": 1 // Request ID
+ }
+ ```
+
+ - **Device response timing:** After the device receives and processes the `initialize` request.
+ - **Device response message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 1, // Match request ID
+ "result": {
+ "protocolVersion": "2024-11-05",
+ "capabilities": {
+ "tools": {} // The tools here don't seem to list detailed information, and tools/list is needed
+ },
+ "serverInfo": {
+ "name": "...", // device name (BOARD_NAME)
+ "version": "..." // Device firmware version
+ }
+ }
+ }
+ ```
+
+3. **Discover device tool list**
+
+ - **Timing:** When the background API needs to obtain a list of specific functions (tools) currently supported by the device and their calling methods.
+ - **Sender:** Backend API (Client).
+ - **Method:** `tools/list`
+ - **Message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "tools/list",
+ "params": {
+ "cursor": "" // Used for paging, the first request is an empty string
+ },
+ "id": 2 // Request ID
+ }
+ ```
+ - **Device response timing:** After the device receives the `tools/list` request and generates the tool list.
+ - **Device response message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 2, // Match request ID
+ "result": {
+ "tools": [ // List of tool objects
+ {
+ "name": "self.get_device_status",
+ "description": "...",
+ "inputSchema": { ... } // parameter schema
+ },
+ {
+ "name": "self.audio_speaker.set_volume",
+ "description": "...",
+ "inputSchema": { ... } // parameter schema
+ }
+ // ... more tools
+ ],
+ "nextCursor": "..." // If the list is large and needs paging, the cursor value of the next request will be included here.
+ }
+ }
+ ```
+ - **Paging processing:** If the `nextCursor` field is not empty, the client needs to send the `tools/list` request again and bring this `cursor` value in `params` to get the next page of tools.
+
+4. **Calling device tools**
+
+ - **Timing:** When the background API needs to perform a specific function on the device.
+ - **Sender:** Backend API (Client).
+ - **Method:** `tools/call`
+ - **Message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.audio_speaker.set_volume", // The name of the tool to be called
+ "arguments": {
+ //Tool parameters, object format
+ "volume": 50 // Parameter name and its value
+ }
+ },
+ "id": 3 // Request ID
+ }
+ ```
+ - **Device response timing:** After the device receives the `tools/call` request and executes the corresponding tool function.
+ - **Device successful response message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 3, // Match request ID
+ "result": {
+ "content": [
+ // Tool execution result content
+ { "type": "text", "text": "true" } // Example: set_volume returns bool
+ ],
+ "isError": false // indicates success
+ }
+ }
+ ```
+ - **Device failure response message (MCP payload):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 3, // Match request ID
+ "error": {
+ "code": -32601, // JSON-RPC error code, such as Method not found (-32601)
+ "message": "Unknown tool: self.non_existent_tool" // Error description
+ }
+ }
+ ```
+
+5. **The device actively sends messages (Notifications)**
+ - **Timing:** When an event occurs within the device that needs to be notified to the backend API (for example, a state change, although there is no explicit tool in the code sample to send such a message, the existence of `Application::SendMcpMessage` hints that the device may actively send MCP messages).
+ - **Sender:** Device (Server).
+ - **Method:** It may be a method name starting with `notifications/`, or other custom methods.
+ - **Message (MCP payload):** Follows the JSON-RPC Notification format and has no `id` field.
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "notifications/state_changed", // Example method name
+ "params": {
+ "newState": "idle",
+ "oldState": "connecting"
+ }
+ // No id field
+ }
+ ```
+ - **Background API processing:** After receiving the Notification, the background API performs corresponding processing but does not reply.
+
+## Interaction diagram
+
+The following is a simplified interaction sequence diagram showing the main MCP message flow:
+
+```mermaid
+sequenceDiagram
+ participant Device as ESP32 Device
+ participant BackendAPI as background API (Client)
+
+ Note over Device, BackendAPI: Establish WebSocket / MQTT connection
+
+ Device->>BackendAPI: Hello Message (contains "mcp": true)
+
+ BackendAPI->>Device: MCP Initialize Request
+ Note over BackendAPI: method: initialize
+ Note over BackendAPI: params: { capabilities: ... }
+
+ Device->>BackendAPI: MCP Initialize Response
+ Note over Device: result: { protocolVersion: ..., serverInfo: ... }
+
+ BackendAPI->>Device: MCP Get Tools List Request
+ Note over BackendAPI: method: tools/list
+ Note over BackendAPI: params: { cursor: "" }
+
+ Device->>BackendAPI: MCP Get Tools List Response
+ Note over Device: result: { tools: [...], nextCursor: ... }
+
+ loop Optional Pagination
+ BackendAPI->>Device: MCP Get Tools List Request
+ Note over BackendAPI: method: tools/list
+ Note over BackendAPI: params: { cursor: "..." }
+ Device->>BackendAPI: MCP Get Tools List Response
+ Note over Device: result: { tools: [...], nextCursor: "" }
+ end
+
+ BackendAPI->>Device: MCP Call Tool Request
+ Note over BackendAPI: method: tools/call
+ Note over BackendAPI: params: { name: "...", arguments: { ... } }
+
+ alt Tool Call Successful
+ Device->>BackendAPI: MCP Tool Call Success Response
+ Note over Device: result: { content: [...], isError: false }
+ else Tool Call Failed
+ Device->>BackendAPI: MCP Tool Call Error Response
+ Note over Device: error: { code: ..., message: ... }
+ end
+
+ opt Device Notification
+ Device->>BackendAPI: MCP Notification
+ Note over Device: method: notifications/...
+ Note over Device: params: { ... }
+ end
+```
+
+This document outlines the main interaction flows of the MCP protocol in this project. For specific parameter details and tool functions, please refer to `McpServer::AddCommonTools` in `main/mcp_server.cc` and the implementation of each tool.
diff --git a/docs/mcp-protocol_pt.md b/docs/mcp-protocol_pt.md
new file mode 100644
index 0000000000..3d6a4d4038
--- /dev/null
+++ b/docs/mcp-protocol_pt.md
@@ -0,0 +1,269 @@
+Processo de interação #MCP (Model Context Protocol)
+
+AVISO: Geração assistida por IA, ao implementar serviços em segundo plano, consulte o código para confirmar os detalhes!!
+
+O protocolo MCP neste projeto é usado para comunicação entre a API backend (cliente MCP) e o dispositivo ESP32 (servidor MCP) para que o backend possa descobrir e chamar as funções (ferramentas) fornecidas pelo dispositivo.
+
+## Formato do protocolo
+
+De acordo com o código (`main/protocols/protocol.cc`, `main/mcp_server.cc`), as mensagens MCP são encapsuladas no corpo da mensagem do protocolo de comunicação subjacente (como WebSocket ou MQTT). Sua estrutura interna segue a especificação [JSON-RPC 2.0](https://www.jsonrpc.org/specification).
+
+Exemplo de estrutura geral da mensagem:
+
+```json
+{
+ "session_id": "...", //ID da sessão
+ "type": "mcp", // Tipo de mensagem, fixado em "mcp"
+ "carga útil": { // carga útil JSON-RPC 2.0
+ "jsonrpc": "2.0",
+ "method": "...", // nome do método (como "initialize", "tools/list", "tools/call")
+ "params": { ... }, // parâmetros do método (para solicitação)
+ "id": ..., // ID da solicitação (para solicitação e resposta)
+ "resultado": { ... }, // Resultado da execução do método (para resposta de sucesso)
+ "error": { ... } // Mensagem de erro (para resposta de erro)
+ }
+}
+```
+
+Entre eles, a parte `payload` é uma mensagem JSON-RPC 2.0 padrão:
+
+- `jsonrpc`: string fixa "2.0".
+- `method`: O nome do método a ser chamado (para Request).
+- `params`: Os parâmetros do método, um valor estruturado, geralmente um objeto (para Request).
+- `id`: O identificador da solicitação, fornecido pelo cliente ao enviar a solicitação, e retornado como está quando o servidor responde. Usado para combinar solicitações e respostas.
+- `resultado`: O resultado quando o método é executado com sucesso (para Resposta de Sucesso).
+- `error`: Mensagem de erro quando a execução do método falha (para Error Response).
+
+## Processo de interação e tempo de envio
+
+A interação do MCP gira principalmente em torno do cliente (API backend) descobrindo e chamando as “ferramentas” no dispositivo.
+
+1. **Estabelecimento de conexão e notificação de capacidade**
+
+ - **Tempo:** depois que o dispositivo for inicializado e conectado com êxito à API de back-end.
+ - **Remetente:** Dispositivo.
+ - **Mensagem:** O dispositivo envia uma mensagem de protocolo básico "hello" para a API de back-end, que contém uma lista de recursos suportados pelo dispositivo, por exemplo, suportando o protocolo MCP (`"mcp": true`).
+ - **Exemplo (não carga útil do MCP, mas mensagem de protocolo subjacente):**
+ ```json
+ {
+ "type": "hello",
+ "version": ...,
+ "features": {
+ "mcp": true,
+ ...
+ },
+ "transport": "websocket", // ou "mqtt"
+ "audio_params": { ... },
+ "session_id": "..." // O dispositivo pode ser configurado após receber olá do servidor
+ }
+ ```
+
+2. **Inicializar sessão MCP**
+
+ - **Tempo:** Depois que a API em segundo plano recebe a mensagem "hello" do dispositivo e confirma que o dispositivo suporta MCP, ela geralmente é enviada como a primeira solicitação da sessão MCP.
+ - **Remetente:** API de back-end (cliente).
+ - **Método:** `inicializar`
+ - **Mensagem (carga útil do MCP):**
+
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "initialize",
+ "params": {
+ "capabilities": {
+ // Capacidades do cliente, opcional
+
+ //Relacionado à visão da câmera
+ "vision": {
+ "url": "...", //Câmera: endereço de processamento de imagem (deve ser um endereço http, não um endereço websocket)
+ "token": "..." // url token
+ }
+
+ // ...outras capacidades do cliente
+ }
+ },
+ "id": 1 // ID da solicitação
+ }
+ ```
+
+ - **Tempo de resposta do dispositivo:** Depois que o dispositivo recebe e processa a solicitação `initialize`.
+ - **Mensagem de resposta do dispositivo (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 1, // ID da solicitação de correspondência
+ "result": {
+ "protocolVersion": "2024-11-05",
+ "capabilities": {
+ "tools": {} // As ferramentas aqui não parecem listar informações detalhadas e ferramentas/lista são necessárias
+ },
+ "serverInfo": {
+ "nome": "...", // nome do dispositivo (BOARD_NAME)
+ "version": "..." // Versão do firmware do dispositivo
+ }
+ }
+ }
+ ```
+
+3. **Descubra a lista de ferramentas do dispositivo**
+
+ - **Tempo:** Quando a API de segundo plano precisa obter uma lista de funções específicas (ferramentas) atualmente suportadas pelo dispositivo e seus métodos de chamada.
+ - **Remetente:** API de back-end (cliente).
+ - **Método:** `ferramentas/lista`
+ - **Mensagem (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "tools/list",
+ "params": {
+ "cursor": "" // Usado para paginação, a primeira solicitação é uma string vazia
+ },
+ "id": 2 // ID da solicitação
+ }
+ ```
+ - **Tempo de resposta do dispositivo:** Depois que o dispositivo recebe a solicitação `tools/list` e gera a lista de ferramentas.
+ - **Mensagem de resposta do dispositivo (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 2, // ID da solicitação de correspondência
+ "result": {
+ "tools": [ // Lista de objetos de ferramenta
+ {
+ "name": "self.get_device_status",
+ "description": "...",
+ "inputSchema": { ... } // esquema de parâmetro
+ },
+ {
+ "name": "self.audio_speaker.set_volume",
+ "description": "...",
+ "inputSchema": { ... } // esquema de parâmetro
+ }
+ // ... mais ferramentas
+ ],
+ "nextCursor": "..." // Se a lista for grande e precisar de paginação, o valor do cursor da próxima solicitação será incluído aqui.
+ }
+ }
+ ```
+ - **Processamento de paginação:** Se o campo `nextCursor` não estiver vazio, o cliente precisa enviar a solicitação `tools/list` novamente e trazer esse valor de `cursor` em `params` para obter a próxima página de ferramentas.
+
+4. **Chamando ferramentas do dispositivo**
+
+ - **Tempo:** quando a API em segundo plano precisa executar uma função específica no dispositivo.
+ - **Remetente:** API de back-end (cliente).
+ - **Método:** `ferramentas/chamada`
+ - **Mensagem (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.audio_speaker.set_volume", // O nome da ferramenta a ser chamada
+ "arguments": {
+ //Parâmetros da ferramenta, formato do objeto
+ "volume": 50 // Nome do parâmetro e seu valor
+ }
+ },
+ "id": 3 // ID da solicitação
+ }
+ ```
+ - **Tempo de resposta do dispositivo:** Depois que o dispositivo recebe a solicitação `ferramentas/chamada` e executa a função da ferramenta correspondente.
+ - **Mensagem de resposta bem-sucedida do dispositivo (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 3, // ID da solicitação de correspondência
+ "result": {
+ "content": [
+ // Conteúdo do resultado da execução da ferramenta
+ { "type": "text", "text": "true" } // Exemplo: set_volume retorna bool
+ ],
+ "isError": false // indica sucesso
+ }
+ }
+ ```
+ - **Mensagem de resposta de falha do dispositivo (carga útil do MCP):**
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "id": 3, // ID da solicitação de correspondência
+ "error": {
+ "code": -32601, // Código de erro JSON-RPC, como Método não encontrado (-32601)
+ "message": "Ferramenta desconhecida: self.non_existent_tool" // Descrição do erro
+ }
+ }
+ ```
+
+5. **O dispositivo envia mensagens ativamente (notificações)**
+ - **Tempo:** Quando ocorre um evento no dispositivo que precisa ser notificado à API de back-end (por exemplo, uma mudança de estado, embora não haja nenhuma ferramenta explícita no exemplo de código para enviar tal mensagem, a existência de `Application::SendMcpMessage` indica que o dispositivo pode enviar mensagens MCP ativamente).
+ - **Remetente:** Dispositivo (Servidor).
+ - **Método:** Pode ser um nome de método começando com `notifications/` ou outros métodos personalizados.
+ - **Mensagem (carga útil MCP):** Segue o formato de notificação JSON-RPC e não possui campo `id`.
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "notifications/state_changed", // Exemplo de nome do método
+ "params": {
+ "newState": "idle",
+ "oldState": "connecting"
+ }
+ // Nenhum campo de id
+ }
+ ```
+ - **Processamento da API em segundo plano:** Após receber a Notificação, a API em segundo plano executa o processamento correspondente, mas não responde.
+
+## Diagrama de interação
+
+A seguir está um diagrama de sequência de interação simplificado mostrando o fluxo de mensagens principal do MCP:
+
+```mermaid
+sequenceDiagram
+ participant Device as ESP32 Device
+ participante BackendAPI como API de segundo plano (cliente)
+
+ Nota sobre dispositivo, BackendAPI: Estabelecer conexão WebSocket/MQTT
+
+ Dispositivo->>BackendAPI: Olá Mensagem (contém "mcp": true)
+
+ BackendAPI->>Device: MCP Initialize Request
+ Note over BackendAPI: method: initialize
+ Note over BackendAPI: params: { capabilities: ... }
+
+ Device->>BackendAPI: MCP Initialize Response
+ Note over Device: result: { protocolVersion: ..., serverInfo: ... }
+
+ BackendAPI->>Device: MCP Get Tools List Request
+ Note over BackendAPI: method: tools/list
+ Note over BackendAPI: params: { cursor: "" }
+
+ Device->>BackendAPI: MCP Get Tools List Response
+ Note over Device: result: { tools: [...], nextCursor: ... }
+
+ loop Optional Pagination
+ BackendAPI->>Device: MCP Get Tools List Request
+ Note over BackendAPI: method: tools/list
+ Note over BackendAPI: params: { cursor: "..." }
+ Device->>BackendAPI: MCP Get Tools List Response
+ Note over Device: result: { tools: [...], nextCursor: "" }
+ end
+
+ BackendAPI->>Device: MCP Call Tool Request
+ Note over BackendAPI: method: tools/call
+ Note over BackendAPI: params: { name: "...", arguments: { ... } }
+
+ alt Tool Call Successful
+ Device->>BackendAPI: MCP Tool Call Success Response
+ Note over Device: result: { content: [...], isError: false }
+ else Tool Call Failed
+ Device->>BackendAPI: MCP Tool Call Error Response
+ Note over Device: error: { code: ..., message: ... }
+ end
+
+ opt Device Notification
+ Device->>BackendAPI: MCP Notification
+ Note over Device: method: notifications/...
+ Note over Device: params: { ... }
+ end
+```
+
+Este documento descreve os principais fluxos de interação do protocolo MCP neste projeto. Para detalhes específicos de parâmetros e funções da ferramenta, consulte `McpServer::AddCommonTools` em `main/mcp_server.cc` e a implementação de cada ferramenta.
diff --git a/docs/mcp-usage_en.md b/docs/mcp-usage_en.md
new file mode 100644
index 0000000000..66960e561b
--- /dev/null
+++ b/docs/mcp-usage_en.md
@@ -0,0 +1,115 @@
+# MCP protocol IoT control usage instructions
+
+> This document describes how to implement IoT control of ESP32 devices based on the MCP protocol. For detailed protocol process, please refer to [`mcp-protocol.md`](./mcp-protocol.md).
+
+## Introduction
+
+MCP (Model Context Protocol) is a new generation protocol recommended for IoT control. It discovers and calls "Tools" between the background and the device through the standard JSON-RPC 2.0 format to achieve flexible device control.
+
+## Typical usage process
+
+1. After the device is started, it establishes a connection with the background through basic protocols (such as WebSocket/MQTT).
+2. The background initializes the session through the `initialize` method of the MCP protocol.
+3. The background obtains all tools (functions) and parameter descriptions supported by the device through `tools/list`.
+4. The background calls specific tools through `tools/call` to control the device.
+
+For detailed protocol format and interaction, please see [`mcp-protocol.md`](./mcp-protocol.md).
+
+## Description of device-side tool registration method
+
+The device registers "tools" that can be called in the background through the `McpServer::AddTool` method. Its commonly used function signatures are as follows:
+
+```cpp
+void AddTool(
+ const std::string& name, // Tool name, it is recommended to be unique and hierarchical, such as self.dog.forward
+ const std::string& description, // Tool description, concise description of functions, easy to understand large models
+ const PropertyList& properties, // Input parameter list (can be empty), supported types: Boolean, integer, string
+ std::function callback //Callback implementation when the tool is called
+);
+```
+- name: The unique identifier of the tool. It is recommended to use the "module.function" naming style.
+- description: Natural language description, easy for AI/users to understand.
+- properties: parameter list, supported types are Boolean, integer, string, range and default value can be specified.
+- callback: the actual execution logic when receiving the call request, the return value can be bool/int/string.
+
+## Typical registration example (taking ESP-Hi as an example)
+
+```cpp
+void InitializeTools() {
+ auto& mcp_server = McpServer::GetInstance();
+ //Example 1: No parameters, control the robot to move forward
+ mcp_server.AddTool("self.dog.forward", "Robot moves forward", PropertyList(), [this](const PropertyList&) -> ReturnValue {
+ servo_dog_ctrl_send(DOG_STATE_FORWARD, NULL);
+ return true;
+ });
+ //Example 2: With parameters, set the RGB color of the light
+ mcp_server.AddTool("self.light.set_rgb", "Set RGB color", PropertyList({
+ Property("r", kPropertyTypeInteger, 0, 255),
+ Property("g", kPropertyTypeInteger, 0, 255),
+ Property("b", kPropertyTypeInteger, 0, 255)
+ }), [this](const PropertyList& properties) -> ReturnValue {
+ int r = properties["r"].value();
+ int g = properties["g"].value();
+ int b = properties["b"].value();
+ led_on_ = true;
+ SetLedColor(r, g, b);
+ return true;
+ });
+}
+```
+
+## Common tool call JSON-RPC examples
+
+### 1. Get the tool list
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/list",
+ "params": { "cursor": "" },
+ "id": 1
+}
+```
+
+### 2. Control the chassis to move forward
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.chassis.go_forward",
+ "arguments": {}
+ },
+ "id": 2
+}
+```
+
+### 3. Switch lighting mode
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.chassis.switch_light_mode",
+ "arguments": { "light_mode": 3 }
+ },
+ "id": 3
+}
+```
+
+### 4. Camera flip
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.camera.set_camera_flipped",
+ "arguments": {}
+ },
+ "id": 4
+}
+```
+
+## Remark
+- For the tool name, parameters and return value, please refer to the `AddTool` registration on the device side.
+- It is recommended that all new projects uniformly use the MCP protocol for IoT control.
+- For detailed protocol and advanced usage, please refer to [`mcp-protocol.md`](./mcp-protocol.md).
\ No newline at end of file
diff --git a/docs/mcp-usage_pt.md b/docs/mcp-usage_pt.md
new file mode 100644
index 0000000000..673df704ca
--- /dev/null
+++ b/docs/mcp-usage_pt.md
@@ -0,0 +1,115 @@
+# Instruções de uso de controle de IoT do protocolo MCP
+
+> Este documento descreve como implementar o controle IoT de dispositivos ESP32 baseados no protocolo MCP. Para processo de protocolo detalhado, consulte [`mcp-protocol.md`](./mcp-protocol.md).
+
+## Introdução
+
+MCP (Model Context Protocol) é um protocolo de nova geração recomendado para controle de IoT. Ele descobre e chama "Ferramentas" entre o plano de fundo e o dispositivo por meio do formato padrão JSON-RPC 2.0 para obter controle flexível do dispositivo.
+
+## Processo de uso típico
+
+1. Após o dispositivo ser iniciado, ele estabelece uma conexão com o plano de fundo por meio de protocolos básicos (como WebSocket/MQTT).
+2. O background inicializa a sessão através do método `initialize` do protocolo MCP.
+3. O background obtém todas as ferramentas (funções) e descrições de parâmetros suportadas pelo dispositivo através de `tools/list`.
+4. O plano de fundo chama ferramentas específicas através de `tools/call` para controlar o dispositivo.
+
+Para formato de protocolo detalhado e interação, consulte [`mcp-protocol.md`](./mcp-protocol.md).
+
+## Descrição do método de registro da ferramenta no lado do dispositivo
+
+O dispositivo registra “ferramentas” que podem ser chamadas em segundo plano através do método `McpServer::AddTool`. Suas assinaturas de função comumente usadas são as seguintes:
+
+```cpp
+void AddTool(
+ const std::string& name, // Nome da ferramenta, recomenda-se que seja único e hierárquico, como self.dog.forward
+ const std::string& description, // Descrição da ferramenta, descrição concisa de funções, modelos grandes fáceis de entender
+ const PropertyList& propriedades, // Lista de parâmetros de entrada (pode estar vazia), tipos suportados: Boolean, inteiro, string
+ std::function callback //Implementação de retorno de chamada quando a ferramenta é chamada
+);
+```
+- nome: O identificador exclusivo da ferramenta. Recomenda-se usar o estilo de nomenclatura "module.function".
+- descrição: descrição em linguagem natural, fácil de entender para IA/usuários.
+- propriedades: lista de parâmetros, os tipos suportados são booleanos, inteiro, string, intervalo e valor padrão podem ser especificados.
+- callback: a lógica de execução real ao receber a solicitação de chamada, o valor de retorno pode ser bool/int/string.
+
+## Exemplo típico de registro (tomando ESP-Hi como exemplo)
+
+```cpp
+void InitializeTools() {
+ auto& mcp_server = McpServer::GetInstance();
+ //Exemplo 1: Sem parâmetros, controle o robô para avançar
+ mcp_server.AddTool("self.dog.forward", "Robô avança", PropertyList(), [this](const PropertyList&) -> ReturnValue {
+ servo_dog_ctrl_send(DOG_STATE_FORWARD, NULL);
+ return true;
+ });
+ //Exemplo 2: Com parâmetros, defina a cor RGB da luz
+ mcp_server.AddTool("self.light.set_rgb", "Definir cor RGB", PropertyList({
+ Property("r", kPropertyTypeInteger, 0, 255),
+ Property("g", kPropertyTypeInteger, 0, 255),
+ Property("b", kPropertyTypeInteger, 0, 255)
+ }), [this](const PropertyList& properties) -> ReturnValue {
+ int r = properties["r"].value();
+ int g = properties["g"].value();
+ int b = properties["b"].value();
+ led_on_ = true;
+ SetLedColor(r, g, b);
+ return true;
+ });
+}
+```
+
+## Exemplos comuns de chamada de ferramenta JSON-RPC
+
+### 1. Obtenha a lista de ferramentas
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/list",
+ "params": { "cursor": "" },
+ "id": 1
+}
+```
+
+### 2. Controle o chassi para avançar
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.chassis.go_forward",
+ "arguments": {}
+ },
+ "id": 2
+}
+```
+
+### 3. Alternar modo de iluminação
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.chassis.switch_light_mode",
+ "arguments": { "light_mode": 3 }
+ },
+ "id": 3
+}
+```
+
+### 4. Virar a câmera
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.camera.set_camera_flipped",
+ "arguments": {}
+ },
+ "id": 4
+}
+```
+
+## Observação
+- Para o nome da ferramenta, parâmetros e valor de retorno, consulte o registro `AddTool` no lado do dispositivo.
+- Recomenda-se que todos os novos projetos utilizem uniformemente o protocolo MCP para controle de IoT.
+- Para protocolo detalhado e uso avançado, consulte [`mcp-protocol.md`](./mcp-protocol.md).
\ No newline at end of file
diff --git a/docs/mqtt-udp_en.md b/docs/mqtt-udp_en.md
new file mode 100644
index 0000000000..53a4b51383
--- /dev/null
+++ b/docs/mqtt-udp_en.md
@@ -0,0 +1,393 @@
+# MQTT + UDP hybrid communication protocol documentation
+
+MQTT + UDP hybrid communication protocol document compiled based on code implementation, outlining the interaction between the device and the server on how to transmit control messages through MQTT and transmit audio data through UDP.
+
+---
+
+## 1. Protocol Overview
+
+This agreement uses a mixed transmission method:
+- **MQTT**: used to control messages, status synchronization, and JSON data exchange
+- **UDP**: used for real-time audio data transmission, supports encryption
+
+### 1.1 Protocol Features
+
+- **Dual-channel design**: separation of control and data to ensure real-time performance
+- **Encrypted transmission**: UDP audio data is encrypted using AES-CTR
+- **Sequence Number Protection**: Prevent packet replay and reordering
+- **Automatic reconnect**: Automatically reconnect when MQTT connection is disconnected
+
+---
+
+## 2. Overall process overview
+
+```mermaid
+sequenceDiagram
+ participant Device as ESP32 device
+ participant MQTT as MQTT server
+ participant UDP as UDP server
+
+ Note over Device, UDP: 1. Establish MQTT connection
+ Device->>MQTT: MQTT Connect
+ MQTT->>Device: Connected
+
+ Note over Device, UDP: 2. Request audio channel
+ Device->>MQTT: Hello Message (type: "hello", transport: "udp")
+ MQTT->>Device: Hello Response (UDP connection information + encryption key)
+
+ Note over Device, UDP: 3. Establish UDP connection
+ Device->>UDP: UDP Connect
+ UDP->>Device: Connected
+
+ Note over Device, UDP: 4. Audio data transmission
+ loop audio streaming
+ Device->>UDP: Encrypted audio data (Opus)
+ UDP->>Device: Encrypted audio data (Opus)
+ end
+
+ Note over Device, UDP: 5. Control message exchange
+ par control message
+ Device->>MQTT: Listen/TTS/MCP messages
+ MQTT->>Device: STT/TTS/MCP response
+ end
+
+ Note over Device, UDP: 6. Close the connection
+ Device->>MQTT: Goodbye Message
+ Device->>UDP: Disconnect
+```
+
+---
+
+## 3. MQTT control channel
+
+### 3.1 Connection establishment
+
+The device connects to the server via MQTT, and the connection parameters include:
+- **Endpoint**: MQTT server address and port
+- **Client ID**: Device unique identifier
+- **Username/Password**: Authentication credentials
+- **Keep Alive**: heartbeat interval (default 240 seconds)
+
+### 3.2 Hello message exchange
+
+#### 3.2.1 The device sends Hello
+
+```json
+{
+ "type": "hello",
+ "version": 3,
+ "transport": "udp",
+ "features": {
+ "mcp": true
+ },
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+}
+```
+
+#### 3.2.2 Server responds Hello
+
+```json
+{
+ "type": "hello",
+ "transport": "udp",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 24000,
+ "channels": 1,
+ "frame_duration": 60
+ },
+ "udp": {
+ "server": "192.168.1.100",
+ "port": 8888,
+ "key": "0123456789ABCDEF0123456789ABCDEF",
+ "nonce": "0123456789ABCDEF0123456789ABCDEF"
+ }
+}
+```
+
+**Field description:**
+- `udp.server`: UDP server address
+- `udp.port`: UDP server port
+- `udp.key`: AES encryption key (hex string)
+- `udp.nonce`: AES encrypted nonce (hex string)
+
+### 3.3 JSON message type
+
+#### 3.3.1 Device → Server
+
+1. **Listen message**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "manual"
+ }
+ ```
+
+2. **Abort message**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "abort",
+ "reason": "wake_word_detected"
+ }
+ ```
+
+3. **MCP Message**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {...}
+ }
+ }
+ ```
+
+4. **Goodbye Message**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "goodbye"
+ }
+ ```
+
+#### 3.3.2 Server→Device
+
+The supported message types are consistent with the WebSocket protocol, including:
+- **STT**: Speech recognition results
+- **TTS**: speech synthesis control
+- **LLM**: Emotional Expression Control
+- **MCP**: IoT Control
+- **System**: System control
+- **Custom**: Custom message (optional)
+
+---
+
+## 4. UDP audio channel
+
+### 4.1 Connection establishment
+
+After the device receives the MQTT Hello response, it uses the UDP connection information in it to establish an audio channel:
+1. Resolve UDP server address and port
+2. Parse encryption keys and random numbers
+3. Initialize AES-CTR encryption context
+4. Establish UDP connection
+
+### 4.2 Audio data format
+
+#### 4.2.1 Encrypted audio packet structure
+
+```
+|type 1byte|flags 1byte|payload_len 2bytes|ssrc 4bytes|timestamp 4bytes|sequence 4bytes|
+|payload payload_len bytes|
+```
+
+**Field description:**
+- `type`: packet type, fixed to 0x01
+- `flags`: flag bit, currently unused
+- `payload_len`: payload length (network byte order)
+- `ssrc`: synchronization source identifier
+- `timestamp`: timestamp (network byte order)
+- `sequence`: sequence number (network byte order)
+- `payload`: encrypted Opus audio data
+
+#### 4.2.2 Encryption algorithm
+
+Encrypt using **AES-CTR** mode:
+- **Key**: 128 bits, provided by the server
+- **Random number**: 128 bits, provided by the server
+- **Counter**: Contains timestamp and sequence number information
+
+### 4.3 Serial number management
+
+- **Sender**: `local_sequence_` monotonically increasing
+- **Receiver**: `remote_sequence_` Verify continuity
+- **Anti-replay**: Reject packets with sequence numbers smaller than the expected value
+- **Fault Tolerance**: Allow minor sequence number jumps, log warnings
+
+### 4.4 Error handling
+
+1. **Decryption failed**: error logged, packet discarded
+2. **Sequence number exception**: Log warning, but still process packet
+3. **Data packet format error**: record error and discard the data packet
+
+---
+
+## 5. Status management
+
+### 5.1 Connection status
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> Disconnected
+ Disconnected --> MqttConnecting: StartMqttClient()
+ MqttConnecting --> MqttConnected: MQTT Connected
+ MqttConnecting --> Disconnected: Connect Failed
+ MqttConnected --> RequestingChannel: OpenAudioChannel()
+ RequestingChannel --> ChannelOpened: Hello Exchange Success
+ RequestingChannel --> MqttConnected: Hello Timeout/Failed
+ ChannelOpened --> UdpConnected: UDP Connect Success
+ UdpConnected --> AudioStreaming: Start Audio Transfer
+ AudioStreaming --> UdpConnected: Stop Audio Transfer
+ UdpConnected --> ChannelOpened: UDP Disconnect
+ ChannelOpened --> MqttConnected: CloseAudioChannel()
+ MqttConnected --> Disconnected: MQTT Disconnect
+```
+
+### 5.2 Status Check
+
+The device determines whether the audio channel is available through the following conditions:
+```cpp
+bool IsAudioChannelOpened() const {
+ return udp_ != nullptr && !error_occurred_ && !IsTimeout();
+}
+```
+
+---
+
+## 6. Configuration parameters
+
+### 6.1 MQTT configuration
+
+Configuration items read from settings:
+- `endpoint`: MQTT server address
+- `client_id`: client identifier
+- `username`: username
+- `password`: password
+- `keepalive`: heartbeat interval (default 240 seconds)
+- `publish_topic`: Publish topic
+
+### 6.2 Audio parameters
+
+- **Format**: Opus
+- **Sampling rate**: 16000 Hz (device side) / 24000 Hz (server side)
+- **Number of channels**: 1 (mono)
+- **Frame duration**: 60ms
+
+---
+
+## 7. Error handling and reconnection
+
+### 7.1 MQTT reconnection mechanism
+
+- Automatically retry when connection fails
+- Support error reporting control
+- Trigger the cleanup process when disconnected
+
+### 7.2 UDP connection management
+
+- Does not automatically retry when connection fails
+- Rely on MQTT channel renegotiation
+-Support connection status query
+
+### 7.3 Timeout processing
+
+The base class `Protocol` provides timeout detection:
+- Default timeout: 120 seconds
+- Calculated based on last reception time
+- Automatically marked as unavailable upon timeout
+
+---
+
+## 8. Security considerations
+
+### 8.1 Transmission encryption
+
+- **MQTT**: Supports TLS/SSL encryption (port 8883)
+- **UDP**: Encrypt audio data using AES-CTR
+
+### 8.2 Authentication mechanism
+
+- **MQTT**: username/password authentication
+- **UDP**: Distribute keys via MQTT channel
+
+### 8.3 Anti-replay attacks
+
+- Serial numbers increase monotonically
+- Reject expired packets
+- Timestamp verification
+
+---
+
+## 9. Performance optimization
+
+### 9.1 Concurrency control
+
+Use a mutex to protect a UDP connection:
+```cpp
+std::lock_guard lock(channel_mutex_);
+```
+
+### 9.2 Memory Management
+
+- Dynamically create/destroy network objects
+- Smart pointer to manage audio packets
+- Release encryption context promptly
+
+### 9.3 Network optimization
+
+- UDP connection multiplexing
+- Packet size optimization
+- Serial number continuity check
+
+---
+
+## 10. Comparison with WebSocket protocol
+
+| Features | MQTT + UDP | WebSocket |
+|------|------------|-----------|
+| Control Channel | MQTT | WebSocket |
+| Audio channel | UDP (encrypted) | WebSocket (binary) |
+| Real-time | High (UDP) | Medium |
+| Reliability | Medium | High |
+| Complexity | High | Low |
+| Encryption | AES-CTR | TLS |
+| Firewall friendliness | Low | High |
+
+---
+
+## 11. Deployment recommendations
+
+### 11.1 Network environment
+
+- Make sure the UDP port is reachable
+- Configure firewall rules
+- Consider NAT penetration
+
+### 11.2 Server configuration
+
+- MQTT Broker configuration
+- UDP server deployment
+- Key management system
+
+### 11.3 Monitoring indicators
+
+- Connection success rate
+- Audio transmission delay
+- Packet loss rate
+- Decryption failure rate
+
+---
+
+## 12. Summary
+
+The MQTT + UDP hybrid protocol achieves efficient audio and video communication through the following design:
+
+- **Separated Architecture**: Control and data channels are separated and each performs its own duties
+- **Encryption Protection**: AES-CTR ensures secure transmission of audio data
+- **Serialization Management**: Prevent replay attacks and data disorder
+- **Automatic Recovery**: Supports automatic reconnection after disconnection
+- **Performance Optimization**: UDP transmission ensures the real-time nature of audio data
+
+This protocol is suitable for voice interaction scenarios that require high real-time performance, but requires a trade-off between network complexity and transmission performance.
\ No newline at end of file
diff --git a/docs/mqtt-udp_pt.md b/docs/mqtt-udp_pt.md
new file mode 100644
index 0000000000..e14789d111
--- /dev/null
+++ b/docs/mqtt-udp_pt.md
@@ -0,0 +1,393 @@
+# Documentação do protocolo de comunicação híbrida MQTT + UDP
+
+Documento do protocolo de comunicação híbrida MQTT + UDP compilado com base na implementação de código, descrevendo a interação entre o dispositivo e o servidor sobre como transmitir mensagens de controle por meio de MQTT e transmitir dados de áudio por meio de UDP.
+
+---
+
+## 1. Visão geral do protocolo
+
+Este acordo utiliza um método de transmissão misto:
+- **MQTT**: usado para controlar mensagens, sincronização de status e troca de dados JSON
+- **UDP**: usado para transmissão de dados de áudio em tempo real, suporta criptografia
+
+### 1.1 Recursos do protocolo
+
+- **Design de canal duplo**: separação de controle e dados para garantir desempenho em tempo real
+- **Transmissão criptografada**: os dados de áudio UDP são criptografados usando AES-CTR
+- **Proteção de número de sequência**: evita a repetição e reordenação de pacotes
+- **Reconexão automática**: Reconecte automaticamente quando a conexão MQTT for desconectada
+
+---
+
+## 2. Visão geral do processo
+
+```mermaid
+sequenceDiagram
+ Dispositivo participante como dispositivo ESP32
+ participante MQTT como servidor MQTT
+ participante UDP como servidor UDP
+
+ Nota sobre dispositivo, UDP: 1. Estabeleça conexão MQTT
+ Device->>MQTT: MQTT Connect
+ MQTT->>Device: Connected
+
+ Nota sobre dispositivo, UDP: 2. Solicitar canal de áudio
+ Device->>MQTT: Hello Message (type: "hello", transport: "udp")
+ MQTT->>Dispositivo: Hello Response (informações de conexão UDP + chave de criptografia)
+
+ Nota sobre dispositivo, UDP: 3. Estabeleça conexão UDP
+ Device->>UDP: UDP Connect
+ UDP->>Device: Connected
+
+ Nota sobre dispositivo, UDP: 4. Transmissão de dados de áudio
+ streaming de áudio em loop
+ Dispositivo->>UDP: Dados de áudio criptografados (Opus)
+ UDP->>Dispositivo: Dados de áudio criptografados (Opus)
+ end
+
+ Nota sobre dispositivo, UDP: 5. Controle a troca de mensagens
+ mensagem de controle par
+ Dispositivo->>MQTT: Mensagens de escuta/TTS/MCP
+ MQTT->>Dispositivo: resposta STT/TTS/MCP
+ end
+
+ Nota sobre dispositivo, UDP: 6. Feche a conexão
+ Device->>MQTT: Goodbye Message
+ Device->>UDP: Disconnect
+```
+
+---
+
+## 3. Canal de controle MQTT
+
+### 3.1 Estabelecimento de conexão
+
+O dispositivo se conecta ao servidor via MQTT e os parâmetros de conexão incluem:
+- **Endpoint**: endereço e porta do servidor MQTT
+- **ID do cliente**: identificador exclusivo do dispositivo
+- **Nome de usuário/senha**: credenciais de autenticação
+- **Keep Alive**: intervalo de pulsação (padrão 240 segundos)
+
+### 3.2 Olá troca de mensagens
+
+#### 3.2.1 O dispositivo envia Olá
+
+```json
+{
+ "type": "hello",
+ "version": 3,
+ "transport": "udp",
+ "features": {
+ "mcp": true
+ },
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+}
+```
+
+#### 3.2.2 Servidor responde Olá
+
+```json
+{
+ "type": "hello",
+ "transport": "udp",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 24000,
+ "channels": 1,
+ "frame_duration": 60
+ },
+ "udp": {
+ "server": "192.168.1.100",
+ "port": 8888,
+ "key": "0123456789ABCDEF0123456789ABCDEF",
+ "nonce": "0123456789ABCDEF0123456789ABCDEF"
+ }
+}
+```
+
+**Descrição do campo:**
+- `udp.server`: endereço do servidor UDP
+- `udp.port`: porta do servidor UDP
+- `udp.key`: chave de criptografia AES (string hexadecimal)
+- `udp.nonce`: nonce criptografado AES (string hexadecimal)
+
+### 3.3 Tipo de mensagem JSON
+
+#### 3.3.1 Dispositivo → Servidor
+
+1. **Ouça a mensagem**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "manual"
+ }
+ ```
+
+2. **Abortar mensagem**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "abort",
+ "reason": "wake_word_detected"
+ }
+ ```
+
+3. **Mensagem MCP**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {...}
+ }
+ }
+ ```
+
+4. **Mensagem de adeus**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "goodbye"
+ }
+ ```
+
+#### 3.3.2 Servidor→Dispositivo
+
+Os tipos de mensagens suportados são consistentes com o protocolo WebSocket, incluindo:
+- **STT**: resultados de reconhecimento de fala
+- **TTS**: controle de síntese de fala
+- **LLM**: Controle de Expressão Emocional
+- **MCP**: Controle de IoT
+- **Sistema**: Controle do sistema
+- **Personalizado**: mensagem personalizada (opcional)
+
+---
+
+## 4. Canal de áudio UDP
+
+### 4.1 Estabelecimento de conexão
+
+Depois que o dispositivo recebe a resposta MQTT Hello, ele usa as informações de conexão UDP contidas nela para estabelecer um canal de áudio:
+1. Resolva o endereço e a porta do servidor UDP
+2. Analise chaves de criptografia e números aleatórios
+3. Inicialize o contexto de criptografia AES-CTR
+4. Estabeleça conexão UDP
+
+### 4.2 Formato de dados de áudio
+
+#### 4.2.1 Estrutura de pacote de áudio criptografado
+
+```
+|type 1byte|flags 1byte|payload_len 2bytes|ssrc 4bytes|timestamp 4bytes|sequence 4bytes|
+|payload payload_len bytes|
+```
+
+**Descrição do campo:**
+- `type`: tipo de pacote, fixado em 0x01
+- `flags`: bit de flag, atualmente não utilizado
+- `payload_len`: comprimento da carga útil (ordem de bytes da rede)
+- `ssrc`: identificador da fonte de sincronização
+- `timestamp`: timestamp (ordem de bytes da rede)
+- `sequence`: número de sequência (ordem de bytes da rede)
+- `payload`: dados de áudio criptografados do Opus
+
+#### 4.2.2 Algoritmo de criptografia
+
+Criptografe usando o modo **AES-CTR**:
+- **Chave**: 128 bits, fornecida pelo servidor
+- **Número aleatório**: 128 bits, fornecido pelo servidor
+- **Contador**: contém informações de carimbo de data/hora e número de sequência
+
+### 4.3 Gerenciamento de número de série
+
+- **Remetente**: `local_sequence_` aumentando monotonicamente
+- **Receptor**: `remote_sequence_` Verifique a continuidade
+- **Anti-replay**: rejeita pacotes com números de sequência menores que o valor esperado
+- **Tolerância a falhas**: permite saltos menores de números de sequência, avisos de registro
+
+### 4.4 Tratamento de erros
+
+1. **Falha na descriptografia**: erro registrado, pacote descartado
+2. **Exceção de número de sequência**: Registra aviso, mas ainda processa pacote
+3. **Erro de formato do pacote de dados**: registre o erro e descarte o pacote de dados
+
+---
+
+## 5. Gerenciamento de status
+
+### 5.1 Status da conexão
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> Disconnected
+ Disconnected --> MqttConnecting: StartMqttClient()
+ MqttConnecting --> MqttConnected: MQTT Connected
+ MqttConnecting --> Disconnected: Connect Failed
+ MqttConnected --> RequestingChannel: OpenAudioChannel()
+ RequestingChannel --> ChannelOpened: Hello Exchange Success
+ RequestingChannel --> MqttConnected: Hello Timeout/Failed
+ ChannelOpened --> UdpConnected: UDP Connect Success
+ UdpConnected --> AudioStreaming: Start Audio Transfer
+ AudioStreaming --> UdpConnected: Stop Audio Transfer
+ UdpConnected --> ChannelOpened: UDP Disconnect
+ ChannelOpened --> MqttConnected: CloseAudioChannel()
+ MqttConnected --> Disconnected: MQTT Disconnect
+```
+
+### 5.2 Verificação de status
+
+O dispositivo determina se o canal de áudio está disponível através das seguintes condições:
+```cpp
+bool IsAudioChannelOpened() const {
+ return udp_ != nullptr && !error_occurred_ && !IsTimeout();
+}
+```
+
+---
+
+## 6. Parâmetros de configuração
+
+### 6.1 Configuração MQTT
+
+Itens de configuração lidos nas configurações:
+- `endpoint`: endereço do servidor MQTT
+- `client_id`: identificador do cliente
+- `nome de usuário`: nome de usuário
+- `senha`: senha
+- `keepalive`: intervalo de pulsação (padrão 240 segundos)
+- `publish_topic`: Publicar tópico
+
+### 6.2 Parâmetros de áudio
+
+- **Formato**: Opus
+**Taxa de amostragem**: 16.000 Hz (lado do dispositivo) / 24.000 Hz (lado do servidor)
+- **Número de canais**: 1 (mono)
+- **Duração do quadro**: 60ms
+
+---
+
+## 7. Tratamento de erros e reconexão
+
+### 7.1 Mecanismo de reconexão MQTT
+
+- Tentar novamente automaticamente quando a conexão falhar
+- Suporte ao controle de relatórios de erros
+- Acione o processo de limpeza quando desconectado
+
+### 7.2 Gerenciamento de conexão UDP
+
+- Não tenta novamente automaticamente quando a conexão falha
+- Confie na renegociação do canal MQTT
+-Suporte para consulta de status de conexão
+
+### 7.3 Processamento de tempo limite
+
+A classe base `Protocol` fornece detecção de tempo limite:
+- Tempo limite padrão: 120 segundos
+- Calculado com base no horário da última recepção
+- Marcado automaticamente como indisponível após o tempo limite
+
+---
+
+## 8. Considerações de segurança
+
+### 8.1 Criptografia de transmissão
+
+- **MQTT**: Suporta criptografia TLS/SSL (porta 8883)
+- **UDP**: criptografe dados de áudio usando AES-CTR
+
+### 8.2 Mecanismo de autenticação
+
+- **MQTT**: autenticação de nome de usuário/senha
+- **UDP**: Distribuir chaves via canal MQTT
+
+### 8.3 Ataques anti-repetição
+
+- Os números de série aumentam monotonicamente
+- Rejeitar pacotes expirados
+- Verificação de carimbo de data/hora
+
+---
+
+## 9. Otimização de desempenho
+
+### 9.1 Controle de simultaneidade
+
+Use um mutex para proteger uma conexão UDP:
+```cpp
+std::lock_guard lock(channel_mutex_);
+```
+
+### 9.2 Gerenciamento de memória
+
+- Criar/destruir objetos de rede dinamicamente
+- Ponteiro inteligente para gerenciar pacotes de áudio
+- Libere o contexto de criptografia imediatamente
+
+### 9.3 Otimização de rede
+
+- Multiplexação de conexão UDP
+- Otimização do tamanho do pacote
+- Verificação de continuidade do número de série
+
+---
+
+## 10. Comparação com protocolo WebSocket
+
+| Recursos | MQTT + UDP | WebSocket |
+|------|------------|-----------|
+| Canal de Controle | MQTT | WebSocket |
+| Canal de áudio | UDP (criptografado) | WebSocket (binário) |
+| Em tempo real | Alto (UDP) | Médio |
+| Confiabilidade | Médio | Alto |
+| Complexidade | Alto | Baixo |
+| Criptografia | AES-CTR | TLS |
+| Facilidade de firewall | Baixo | Alto |
+
+---
+
+## 11. Recomendações de implantação
+
+### 11.1 Ambiente de rede
+
+- Certifique-se de que a porta UDP esteja acessível
+- Configurar regras de firewall
+- Considere a penetração do NAT
+
+### 11.2 Configuração do servidor
+
+- Configuração do corretor MQTT
+- Implantação de servidor UDP
+- Sistema de gerenciamento de chaves
+
+### 11.3 Indicadores de monitoramento
+
+- Taxa de sucesso de conexão
+- Atraso na transmissão de áudio
+- Taxa de perda de pacotes
+- Taxa de falha de descriptografia
+
+---
+
+## 12. Resumo
+
+O protocolo híbrido MQTT + UDP alcança comunicação eficiente de áudio e vídeo por meio do seguinte design:
+
+- **Arquitetura Separada**: Os canais de controle e de dados são separados e cada um executa suas próprias funções
+**Proteção de criptografia**: AES CTR garante transmissão segura de dados de áudio
+- **Gerenciamento de serialização**: evita ataques de repetição e desordem de dados
+- **Recuperação Automática**: Suporta reconexão automática após desconexão
+- **Otimização de desempenho**: a transmissão UDP garante a natureza em tempo real dos dados de áudio
+
+Este protocolo é adequado para cenários de interação de voz que exigem alto desempenho em tempo real, mas exige um compromisso entre complexidade da rede e desempenho de transmissão.
\ No newline at end of file
diff --git a/docs/websocket_en.md b/docs/websocket_en.md
new file mode 100644
index 0000000000..5f48bf15c1
--- /dev/null
+++ b/docs/websocket_en.md
@@ -0,0 +1,495 @@
+The following is a WebSocket communication protocol document based on code implementation, outlining how the device and server interact through WebSocket.
+
+This document is only inferred based on the code provided. Actual deployment may require further confirmation or supplementation in conjunction with server-side implementation.
+
+---
+
+## 1. Overall process overview
+
+1. **Device-side initialization**
+ - Power on the device and initialize `Application`:
+ - Initialize audio codecs, displays, LEDs, etc.
+ - Connect to the Internet
+ - Create and initialize a WebSocket protocol instance (`WebsocketProtocol`) that implements the `Protocol` interface
+ - Enter the main loop to wait for events (audio input, audio output, scheduled tasks, etc.).
+
+2. **Establish WebSocket connection**
+ - When the device needs to start a voice session (such as user wake-up, manual key trigger, etc.), call `OpenAudioChannel()`:
+ - Get WebSocket URL based on configuration
+ - Set several request headers (`Authorization`, `Protocol-Version`, `Device-Id`, `Client-Id`)
+ - Call `Connect()` to establish a WebSocket connection with the server
+
+3. **The device sends a "hello" message**
+ - After the connection is successful, the device will send a JSON message. The sample structure is as follows:
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+ - The `features` field is optional, and the content is automatically generated based on the device compilation configuration. For example: `"mcp": true` indicates support for MCP protocol.
+ - The value of `frame_duration` corresponds to `OPUS_FRAME_DURATION_MS` (e.g. 60ms).
+
+4. **The server replies "hello"**
+ - The device waits for the server to return a JSON message containing `"type": "hello"` and checks if `"transport": "websocket"` matches.
+ - The server can optionally send the `session_id` field, and the device will automatically record it after receiving it.
+ - Example:
+ ```json
+ {
+ "type": "hello",
+ "transport": "websocket",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 24000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+ - If there is a match, the server is considered ready and the audio channel is marked as opened successfully.
+ - If a correct reply is not received within the timeout (default 10 seconds), the connection is considered failed and a network error callback is triggered.
+
+5. **Follow-up message interaction**
+ - There are two main types of data that can be sent between the device and server:
+ 1. **Binary audio data** (Opus encoding)
+ 2. **Text JSON message** (used to transmit chat status, TTS/STT events, MCP protocol messages, etc.)
+
+ - In the code, receiving callbacks is mainly divided into:
+ - `OnData(...)`:
+ - When `binary` is `true`, it is considered an audio frame; the device will decode it as Opus data.
+ - When `binary` is `false`, it is considered to be JSON text, which needs to be parsed with cJSON on the device side and processed with corresponding business logic (such as chat, TTS, MCP protocol messages, etc.).
+
+ - When the server or network is disconnected, the callback `OnDisconnected()` is triggered:
+ - The device will call `on_audio_channel_closed_()` and eventually return to the idle state.
+
+6. **Close WebSocket connection**
+ - When the device needs to end the voice session, it will call `CloseAudioChannel()` to actively disconnect and return to the idle state.
+ - Or if the server actively disconnects, the same callback process will also be triggered.
+
+---
+
+## 2. Common request header
+
+When establishing a WebSocket connection, the following request headers are set in the code example:
+
+- `Authorization`: used to store access tokens, in the form of `"Bearer "`
+- `Protocol-Version`: protocol version number, consistent with the `version` field in the hello message body
+- `Device-Id`: device physical network card MAC address
+- `Client-Id`: software-generated UUID (reset by erasing NVS or re-burning full firmware)
+
+These headers will be sent to the server along with the WebSocket handshake, and the server can perform verification, authentication, etc. as needed.
+
+---
+
+## 3. Binary protocol version
+
+The device supports multiple binary protocol versions, specified through the `version` field in the configuration:
+
+### 3.1 version 1 (default)
+Send Opus audio data directly with no additional metadata. The Websocket protocol distinguishes between text and binary.
+
+### 3.2 version 2
+Using the `BinaryProtocol2` structure:
+```c
+struct BinaryProtocol2 {
+ uint16_t version; // protocol version
+ uint16_t type; // Message type (0: OPUS, 1: JSON)
+ uint32_t reserved; // reserved field
+ uint32_t timestamp; // Timestamp (milliseconds, used for server-side AEC)
+ uint32_t payload_size; // Payload size (bytes)
+ uint8_t payload[]; // payload data
+} __attribute__((packed));
+```
+
+### 3.3 version 3
+Using the `BinaryProtocol3` structure:
+```c
+struct BinaryProtocol3 {
+ uint8_t type; // message type
+ uint8_t reserved; // reserved field
+ uint16_t payload_size; // payload size
+ uint8_t payload[]; // payload data
+} __attribute__((packed));
+```
+
+---
+
+## 4. JSON message structure
+
+WebSocket text frames are transmitted in JSON mode. The following are common `"type"` fields and their corresponding business logic. If the message contains fields not listed, they may be optional or implementation-specific.
+
+### 4.1 Device → Server
+
+1. **Hello**
+ - After the connection is successful, it will be sent by the device to inform the server of the basic parameters.
+ - Example:
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+
+2. **Listen**
+ - Indicates that the device starts or stops recording monitoring.
+ - Common fields:
+ - `"session_id"`: Session ID
+ - `"type": "listen"`
+ - `"state"`: `"start"`, `"stop"`, `"detect"` (wakeup detection has been triggered)
+ - `"mode"`: `"auto"`, `"manual"` or `"realtime"`, indicating the recognition mode.
+ - Example: Start monitoring
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "manual"
+ }
+ ```
+
+3. **Abort**
+ - Terminate the current talk (TTS playback) or voice channel.
+ - Example:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "abort",
+ "reason": "wake_word_detected"
+ }
+ ```
+ - `reason` value can be `"wake_word_detected"` or other.
+
+4. **Wake Word Detected**
+ - Used by the device to notify the server that the wake word has been detected.
+ - Before sending the message, the Opus audio data of the wake word can be sent in advance for the server to perform voiceprint detection.
+ - Example:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "detect",
+ "text": "Hello Xiao Ming"
+ }
+ ```
+
+5. **MCP**
+ - Recommended new generation protocol for IoT control. All device capability discovery, tool invocation, etc. are performed through messages of type: "mcp", and the payload is internally standard JSON-RPC 2.0 (see [MCP Protocol Document](./mcp-protocol.md) for details).
+
+ - **Example of device sending result to server:**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "content": [
+ { "type": "text", "text": "true" }
+ ],
+ "isError": false
+ }
+ }
+ }
+ ```
+
+---
+
+### 4.2 Server→Device
+
+1. **Hello**
+ - The handshake confirmation message returned by the server.
+ - Must contain `"type": "hello"` and `"transport": "websocket"`.
+ - May be accompanied by `audio_params`, indicating the audio parameters expected by the server, or configuration aligned with the device side.
+ - The server can optionally send the `session_id` field, and the device will automatically record it after receiving it.
+ - After successful reception, the device will set the event flag to indicate that the WebSocket channel is ready.
+
+2. **STT**
+ - `{"session_id": "xxx", "type": "stt", "text": "..."}`
+ - Indicates that the server has recognized the user's voice. (e.g. speech-to-text results)
+ - The device may display this text on the screen, and then enter the process of answering.
+
+3. **LLM**
+ - `{"session_id": "xxx", "type": "llm", "emotion": "happy", "text": "😀"}`
+ - The server instructs the device to adjust emote animations/UI expressions.
+
+4. **TTS**
+ - `{"session_id": "xxx", "type": "tts", "state": "start"}`: The server is ready to deliver TTS audio, and the device enters the "speaking" playback state.
+ - `{"session_id": "xxx", "type": "tts", "state": "stop"}`: Indicates the end of this TTS.
+ - `{"session_id": "xxx", "type": "tts", "state": "sentence_start", "text": "..."}`
+ - Have the device display the currently played or spoken text segment on the interface (e.g. for display to the user).
+
+5. **MCP**
+ - The server issues IoT-related control instructions or returns the call results through messages of type: "mcp". The payload structure is the same as above.
+
+ - **Example of sending tools/call from server to device:**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.light.set_rgb",
+ "arguments": { "r": 255, "g": 0, "b": 0 }
+ },
+ "id": 1
+ }
+ }
+ ```
+
+6. **System**
+ - System control commands, often used for remote upgrades and updates.
+ - Example:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "system",
+ "command": "reboot"
+ }
+ ```
+ - Supported commands:
+ - `"reboot"`: Restart the device
+
+7. **Custom** (optional)
+ - Custom messages, supported when `CONFIG_RECEIVE_CUSTOM_MESSAGE` is enabled.
+ - Example:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "custom",
+ "payload": {
+ "message": "custom content"
+ }
+ }
+ ```
+
+8. **Audio Data: Binary Frame**
+ - When the server sends audio binary frames (Opus encoded), the device decodes and plays them.
+ - If the device is in "listening" (recording) state, the received audio frames will be ignored or cleared to prevent conflicts.
+
+---
+
+## 5. Audio codec
+
+1. **The device sends recording data**
+ - After the audio input has undergone possible echo cancellation, noise reduction or volume gain, it is packaged into binary frames and sent to the server through Opus encoding.
+ - Depending on the protocol version, it is possible to send Opus data directly (version 1) or use the binary protocol with metadata (version 2/3).
+
+2. **Play the received audio on the device**
+ - When a binary frame is received from the server, it is also considered to be Opus data.
+ - The device will decode it and then play it through the audio output interface.
+ - If the audio sampling rate of the server is inconsistent with the device, resampling will be performed after decoding.
+
+---
+
+## 6. Common status transitions
+
+The following are common device-side key status flows, corresponding to WebSocket messages:
+
+1. **Idle** → **Connecting**
+ - After the user triggers or wakes up, the device calls `OpenAudioChannel()` → establishes a WebSocket connection → sends `"type":"hello"`.
+
+2. **Connecting** → **Listening**
+ - After successfully establishing the connection, if you continue to execute `SendStartListening(...)`, it will enter the recording state. At this time, the device will continue to encode the microphone data and send it to the server.
+
+3. **Listening** → **Speaking**
+ - Server TTS Start message received (`{"type":"tts","state":"start"}`) → Stop recording and play the received audio.
+
+4. **Speaking** → **Idle**
+ - Server TTS Stop (`{"type":"tts","state":"stop"}`) → Audio playback ends. If it does not continue to enter automatic listening, it will return to Idle; if an automatic loop is configured, it will enter Listening again.
+
+5. **Listening** / **Speaking** → **Idle** (encountering exception or active interruption)
+ - Call `SendAbortSpeaking(...)` or `CloseAudioChannel()` → interrupt the session → close WebSocket → return to Idle state.
+
+### Automatic mode status flow chart
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> kDeviceStateUnknown
+ kDeviceStateUnknown --> kDeviceStateStarting: initialization
+ kDeviceStateStarting --> kDeviceStateWifiConfiguring: Configure WiFi
+ kDeviceStateStarting --> kDeviceStateActivating: Activating the device
+ kDeviceStateActivating --> kDeviceStateUpgrading: New version detected
+ kDeviceStateActivating --> kDeviceStateIdle: activation completed
+ kDeviceStateIdle --> kDeviceStateConnecting: Start connecting
+ kDeviceStateConnecting --> kDeviceStateIdle: Connection failed
+ kDeviceStateConnecting --> kDeviceStateListening: Connection successful
+ kDeviceStateListening --> kDeviceStateSpeaking: Start speaking
+ kDeviceStateSpeaking --> kDeviceStateListening: End speaking
+ kDeviceStateListening --> kDeviceStateIdle: Manual termination
+ kDeviceStateSpeaking --> kDeviceStateIdle: Automatic termination
+```
+
+### Manual mode status flow chart
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> kDeviceStateUnknown
+ kDeviceStateUnknown --> kDeviceStateStarting: initialization
+ kDeviceStateStarting --> kDeviceStateWifiConfiguring: Configure WiFi
+ kDeviceStateStarting --> kDeviceStateActivating: Activating the device
+ kDeviceStateActivating --> kDeviceStateUpgrading: New version detected
+ kDeviceStateActivating --> kDeviceStateIdle: activation completed
+ kDeviceStateIdle --> kDeviceStateConnecting: Start connecting
+ kDeviceStateConnecting --> kDeviceStateIdle: Connection failed
+ kDeviceStateConnecting --> kDeviceStateListening: Connection successful
+ kDeviceStateIdle --> kDeviceStateListening: Start listening
+ kDeviceStateListening --> kDeviceStateIdle: Stop listening
+ kDeviceStateIdle --> kDeviceStateSpeaking: Start speaking
+ kDeviceStateSpeaking --> kDeviceStateIdle: end speaking
+```
+
+---
+
+## 7. Error handling
+
+1. **Connection failed**
+ - Trigger the `on_network_error_()` callback if `Connect(url)` returns failure or times out while waiting for the server "hello" message. The device will prompt "Unable to connect to service" or similar error message.
+
+2. **Server disconnected**
+ - If WebSocket is disconnected abnormally, callback `OnDisconnected()`:
+ - Device callback `on_audio_channel_closed_()`
+ - Switch to Idle or other retry logic.
+
+---
+
+## 8. Other matters needing attention
+
+1. **Authentication**
+ - The device provides authentication by setting `Authorization: Bearer `, and the server needs to verify whether it is valid.
+ - If the token expires or is invalid, the server can reject the handshake or disconnect subsequently.
+
+2. **Session Control**
+ - Some messages in the code contain `session_id` to distinguish independent conversations or operations. The server can separate different sessions as needed.
+
+3. **Audio Load**
+ - The code uses Opus format by default, and sets `sample_rate = 16000`, mono. The frame duration is controlled by `OPUS_FRAME_DURATION_MS`, generally 60ms. Adjustments can be made appropriately based on bandwidth or performance. For better music playback, the server downstream audio may use a 24000 sample rate.
+
+4. **Protocol version configuration**
+ - Configure the binary protocol version (1, 2 or 3) via the `version` field in settings
+ - Version 1: Send Opus data directly
+ - Version 2: Uses timestamped binary protocol, suitable for server-side AEC
+ - Version 3: Uses simplified binary protocol
+
+5. **Recommended MCP protocol for IoT control**
+ - It is recommended that IoT capability discovery, status synchronization, control instructions, etc. between devices and servers are all implemented through the MCP protocol (type: "mcp"). The original type: "iot" solution has been deprecated.
+ - The MCP protocol can be transmitted on multiple underlying protocols such as WebSocket and MQTT, and has better scalability and standardization capabilities.
+ - For detailed usage, please refer to [MCP Protocol Document](./mcp-protocol.md) and [MCP IoT Control Usage](./mcp-usage.md).
+
+6. **Error or Exception JSON**
+ - When necessary fields are missing from the JSON, such as `{"type": ...}`, the device will record an error log (`ESP_LOGE(TAG, "Missing message type, data: %s", data);`) and will not perform any business.
+
+---
+
+## 9. Message example
+
+A typical two-way message example is given below (simplified process):
+
+1. **Device → Server** (handshake)
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+
+2. **Server → Device** (handshake response)
+ ```json
+ {
+ "type": "hello",
+ "transport": "websocket",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000
+ }
+ }
+ ```
+
+3. **Device → Server** (start monitoring)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "auto"
+ }
+ ```
+ At the same time, the device starts sending binary frames (Opus data).
+
+4. **Server → Device** (ASR result)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "stt",
+ "text": "What the user said"
+ }
+ ```
+
+5. **Server → Device** (TTS starts)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "tts",
+ "state": "start"
+ }
+ ```
+ Then the server sends binary audio frames to the device for playback.
+
+6. **Server → Device** (TTS ends)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "tts",
+ "state": "stop"
+ }
+ ```
+ The device stops playing audio and returns to the idle state if there are no more instructions.
+
+---
+
+## 10. Summary
+
+This protocol transmits JSON text and binary audio frames on the upper layer of WebSocket, and completes functions including audio stream upload, TTS audio playback, speech recognition and status management, MCP command issuance, etc. Its core features:
+
+- **Handshake phase**: Send `"type":"hello"` and wait for the server to return.
+- **Audio Channel**: Uses Opus-encoded binary frames to transmit voice streams in both directions, supporting multiple protocol versions.
+- **JSON message**: Use `"type"` to identify different business logic for core fields, including TTS, STT, MCP, WakeWord, System, Custom, etc.
+- **Extensibility**: Fields can be added to the JSON message according to actual needs, or additional authentication can be performed in headers.
+
+The server and the device need to agree in advance on the field meanings, timing logic, and error handling rules of various messages to ensure smooth communication. The above information can be used as basic documents to facilitate subsequent docking, development or expansion.
diff --git a/docs/websocket_pt.md b/docs/websocket_pt.md
new file mode 100644
index 0000000000..a89f6baf66
--- /dev/null
+++ b/docs/websocket_pt.md
@@ -0,0 +1,495 @@
+A seguir está um documento do protocolo de comunicação WebSocket baseado na implementação de código, descrevendo como o dispositivo e o servidor interagem por meio do WebSocket.
+
+Este documento é inferido apenas com base no código fornecido. A implantação real pode exigir confirmação ou complementação adicional em conjunto com a implementação no lado do servidor.
+
+---
+
+## 1. Visão geral do processo
+
+1. **Inicialização do lado do dispositivo**
+ - Ligue o dispositivo e inicialize o `Application`:
+ - Inicialize codecs de áudio, displays, LEDs, etc.
+ - Conecte-se à Internet
+ - Criar e inicializar uma instância do protocolo WebSocket (`WebsocketProtocol`) que implementa a interface `Protocol`
+ - Entre no loop principal para aguardar eventos (entrada de áudio, saída de áudio, tarefas agendadas, etc.).
+
+2. **Estabeleça conexão WebSocket**
+ - Quando o dispositivo precisar iniciar uma sessão de voz (como ativação do usuário, acionamento manual de teclas, etc.), chame `OpenAudioChannel()`:
+ - Obtenha URL do WebSocket com base na configuração
+ - Definir vários cabeçalhos de solicitação (`Autorização`, `Protocol-Version`, `Device-Id`, `Client-Id`)
+ - Chame `Connect()` para estabelecer uma conexão WebSocket com o servidor
+
+3. **O dispositivo envia uma mensagem de "olá"**
+ - Após a conexão ser bem-sucedida, o dispositivo enviará uma mensagem JSON. A estrutura da amostra é a seguinte:
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+ - O campo `features` é opcional e o conteúdo é gerado automaticamente com base na configuração de compilação do dispositivo. Por exemplo: `"mcp": true` indica suporte ao protocolo MCP.
+ - O valor de `frame_duration` corresponde a `OPUS_FRAME_DURATION_MS` (por exemplo, 60ms).
+
+4. **O servidor responde "olá"**
+ - O dispositivo espera que o servidor retorne uma mensagem JSON contendo `"type": "hello"` e verifica se `"transport": "websocket"` corresponde.
+ - O servidor pode opcionalmente enviar o campo `session_id`, e o dispositivo irá gravá-lo automaticamente após recebê-lo.
+ - Exemplo:
+ ```json
+ {
+ "type": "hello",
+ "transport": "websocket",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 24000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+ - Se houver correspondência, o servidor é considerado pronto e o canal de áudio é marcado como aberto com sucesso.
+ - Se uma resposta correta não for recebida dentro do tempo limite (padrão 10 segundos), a conexão será considerada falhada e um retorno de chamada de erro de rede será acionado.
+
+5. **Interação com mensagem de acompanhamento**
+ - Existem dois tipos principais de dados que podem ser enviados entre o dispositivo e o servidor:
+ 1. **Dados de áudio binários** (codificação Opus)
+ 2. **Mensagem de texto JSON** (usada para transmitir status de bate-papo, eventos TTS/STT, mensagens de protocolo MCP, etc.)
+
+ - No código, o recebimento de retornos de chamada é dividido principalmente em:
+ - `OnData(...)`:
+ - Quando `binary` é `true`, é considerado um quadro de áudio; o dispositivo irá decodificá-lo como dados Opus.
+ - Quando `binary` é `false`, é considerado texto JSON, que precisa ser analisado com cJSON no lado do dispositivo e processado com a lógica de negócios correspondente (como chat, TTS, mensagens de protocolo MCP, etc.).
+
+ - Quando o servidor ou rede é desconectado, o callback `OnDisconnected()` é acionado:
+ - O dispositivo chamará `on_audio_channel_closed_()` e eventualmente retornará ao estado inativo.
+
+6. **Fechar conexão WebSocket**
+ - Quando o dispositivo precisar encerrar a sessão de voz, ele chamará `CloseAudioChannel()` para desconectar ativamente e retornar ao estado inativo.
+ - Ou se o servidor se desconectar ativamente, o mesmo processo de retorno de chamada também será acionado.
+
+---
+
+## 2. Cabeçalho de solicitação comum
+
+Ao estabelecer uma conexão WebSocket, os seguintes cabeçalhos de solicitação são definidos no exemplo de código:
+
+- `"Autorização`: utilizado para armazenar tokens de acesso, na forma de `"Bearer "`
+- `Protocol-Version`: número da versão do protocolo, consistente com o campo `version` no corpo da mensagem hello
+- `Device-Id`: endereço MAC da placa de rede física do dispositivo
+- `Client-Id`: UUID gerado por software (redefinido apagando o NVS ou regravando o firmware completo)
+
+Esses cabeçalhos serão enviados ao servidor junto com o handshake do WebSocket, e o servidor poderá realizar verificação, autenticação, etc., conforme necessário.
+
+---
+
+## 3. Versão do protocolo binário
+
+O dispositivo suporta múltiplas versões de protocolo binário, especificadas através do campo `versão` na configuração:
+
+### 3.1 versão 1 (padrão)
+Envie dados de áudio Opus diretamente, sem metadados adicionais. O protocolo Websocket distingue entre texto e binário.
+
+### 3.2 versão 2
+Usando a estrutura `BinaryProtocol2`:
+```c
+struct BinaryProtocol2 {
+ versão uint16_t; //versão do protocolo
+ tipo uint16_t; // Tipo de mensagem (0: OPUS, 1: JSON)
+ uint32_t reservado; //campo reservado
+ carimbo de data/hora uint32_t; // Timestamp (milissegundos, usado para AEC do lado do servidor)
+ uint32_t tamanho_da_carga; //Tamanho da carga útil (bytes)
+ carga útil uint8_t[]; //dados de carga útil
+} __attribute__((packed));
+```
+
+### 3.3 versão 3
+Usando a estrutura `BinaryProtocol3`:
+```c
+struct BinaryProtocol3 {
+ tipo uint8_t; //tipo de mensagem
+ uint8_t reservado; //campo reservado
+ uint16_t tamanho_da_carga; //tamanho da carga útil
+ carga útil uint8_t[]; //dados de carga útil
+} __attribute__((packed));
+```
+
+---
+
+## 4. Estrutura da mensagem JSON
+
+Os quadros de texto WebSocket são transmitidos no modo JSON. A seguir estão os campos `"type"` comuns e sua lógica de negócios correspondente. Se a mensagem contiver campos não listados, eles poderão ser opcionais ou específicos da implementação.
+
+### 4.1 Dispositivo → Servidor
+
+1. **Hello**
+ - Após o sucesso da conexão, será enviado pelo dispositivo para informar ao servidor os parâmetros básicos.
+ - Exemplo:
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+
+2. **Listen**
+ - Indica que o dispositivo inicia ou para o monitoramento da gravação.
+ - Campos comuns:
+ - `"session_id"`: ID da sessão
+ - `"type": "listen"`
+ - `"state"`: `"start"`, `"stop"`, `"detect"` (a detecção de ativação foi acionada)
+ - `"mode"`: `"auto"`, `"manual"` ou `"realtime"`, indicando o modo de reconhecimento.
+ - Exemplo: Iniciar monitoramento
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "manual"
+ }
+ ```
+
+3. **Abort**
+ - Encerre a conversa atual (reprodução TTS) ou canal de voz.
+ - Exemplo:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "abort",
+ "reason": "wake_word_detected"
+ }
+ ```
+ - O valor `reason` pode ser `"wake_word_detected"` ou outro.
+
+4. **Wake Word Detected**
+ - Usado pelo dispositivo para notificar o servidor de que a palavra de ativação foi detectada.
+ - Antes de enviar a mensagem, os dados de áudio Opus da wake word podem ser enviados antecipadamente para o servidor realizar a detecção de impressão de voz.
+ - Exemplo:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "detect",
+ "texto": "Olá Xiao Ming"
+ }
+ ```
+
+5. **MCP**
+ - Protocolo de nova geração recomendado para controle de IoT. Todas as descobertas de capacidade do dispositivo, invocação de ferramentas, etc. são realizadas por meio de mensagens do tipo: "mcp", e a carga útil é JSON-RPC 2.0 padrão internamente (consulte [Documento do protocolo MCP](./mcp-protocol.md) para obter detalhes).
+
+ - **Exemplo de dispositivo enviando resultado para servidor:**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "content": [
+ { "type": "text", "text": "true" }
+ ],
+ "isError": false
+ }
+ }
+ }
+ ```
+
+---
+
+### 4.2 Servidor→Dispositivo
+
+1. **Hello**
+ - A mensagem de confirmação do handshake retornada pelo servidor.
+ - Deve conter `"type": "hello"` e `"transport": "websocket"`.
+ - Pode vir acompanhado de `audio_params`, indicando os parâmetros de áudio esperados pelo servidor, ou configuração alinhada ao lado do dispositivo.
+ - O servidor pode opcionalmente enviar o campo `session_id`, e o dispositivo irá gravá-lo automaticamente após recebê-lo.
+ - Após a recepção bem-sucedida, o dispositivo definirá o sinalizador de evento para indicar que o canal WebSocket está pronto.
+
+2. **STT**
+ - `{"session_id": "xxx", "type": "stt", "text": "..."}`
+ - Indica que o servidor reconheceu a voz do usuário. (por exemplo, resultados de fala para texto)
+ - O aparelho pode exibir este texto na tela e depois entrar no processo de atendimento.
+
+3. **LLM**
+ - `{"session_id": "xxx", "type": "llm", "emotion": "happy", "text": "😀"}`
+ - O servidor instrui o dispositivo a ajustar animações de emote/expressões de UI.
+
+4. **TTS**
+ - `{"session_id": "xxx", "type": "tts", "state": "start"}`: O servidor está pronto para entregar áudio TTS e o dispositivo entra no estado de reprodução "falante".
+ - `{"session_id": "xxx", "type": "tts", "state": "stop"}`: Indica o final deste TTS.
+ - `{"session_id": "xxx", "type": "tts", "state": "sentence_start", "text": "..."}`
+ - Faça com que o dispositivo exiba o segmento de texto atualmente reproduzido ou falado na interface (por exemplo, para exibição ao usuário).
+
+5. **MCP**
+ - O servidor emite instruções de controle relacionadas à IoT ou retorna os resultados da chamada através de mensagens do tipo: “mcp”. A estrutura da carga útil é a mesma acima.
+
+ - **Exemplo de envio de ferramentas/chamada do servidor para o dispositivo:**
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "mcp",
+ "payload": {
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "self.light.set_rgb",
+ "arguments": { "r": 255, "g": 0, "b": 0 }
+ },
+ "id": 1
+ }
+ }
+ ```
+
+6. **System**
+ - Comandos de controle do sistema, frequentemente usados para atualizações e atualizações remotas.
+ - Exemplo:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "system",
+ "command": "reboot"
+ }
+ ```
+ - Comandos suportados:
+ - `"reboot"`: Reinicie o dispositivo
+
+7. **Personalizado** (opcional)
+ - Mensagens personalizadas, suportadas quando `CONFIG_RECEIVE_CUSTOM_MESSAGE` está habilitado.
+ - Exemplo:
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "custom",
+ "payload": {
+ "mensagem": "conteúdo personalizado"
+ }
+ }
+ ```
+
+8. **Dados de áudio: quadro binário**
+ - Quando o servidor envia quadros binários de áudio (codificados em Opus), o dispositivo os decodifica e os reproduz.
+ - Se o dispositivo estiver no estado de "escuta" (gravação), os quadros de áudio recebidos serão ignorados ou apagados para evitar conflitos.
+
+---
+
+## 5. Codec de áudio
+
+1. **O dispositivo envia dados de gravação**
+ - Após a entrada de áudio ter sofrido possível cancelamento de eco, redução de ruído ou ganho de volume, ela é empacotada em quadros binários e enviada ao servidor por meio da codificação Opus.
+ - Dependendo da versão do protocolo, é possível enviar dados Opus diretamente (versão 1) ou utilizar o protocolo binário com metadados (versão 2/3).
+
+2. **Reproduza o áudio recebido no dispositivo**
+ - Quando um quadro binário é recebido do servidor, também é considerado dado Opus.
+ - O dispositivo irá decodificá-lo e reproduzi-lo através da interface de saída de áudio.
+ - Se a taxa de amostragem de áudio do servidor for inconsistente com o dispositivo, a reamostragem será realizada após a decodificação.
+
+---
+
+## 6. Transições de status comuns
+
+A seguir estão fluxos comuns de status de chave do lado do dispositivo, correspondentes a mensagens WebSocket:
+
+1. **Idle** → **Connecting**
+ - Depois que o usuário aciona ou acorda, o dispositivo chama `OpenAudioChannel()` → estabelece uma conexão WebSocket → envia `"type":"hello"`.
+
+2. **Connecting** → **Listening**
+ - Após estabelecer a conexão com sucesso, se você continuar a executar `SendStartListening(...)`, ele entrará no estado de gravação. Neste momento, o dispositivo continuará a codificar os dados do microfone e enviá-los ao servidor.
+
+3. **Listening** → **Speaking**
+ - Mensagem de início do TTS do servidor recebida (`{"type":"tts","state":"start"}`) → Pare a gravação e reproduza o áudio recebido.
+
+4. **Speaking** → **Idle**
+ - Parada TTS do servidor (`{"type":"tts","state":"stop"}`) → A reprodução do áudio termina. Caso não continue entrando na escuta automática, retornará para Idle; se um loop automático estiver configurado, ele entrará em escuta novamente.
+
+5. **Ouvir** / **Falar** → **Inativo** (encontrando exceção ou interrupção ativa)
+ - Chame `SendAbortSpeaking(...)` ou `CloseAudioChannel()` → interrompa a sessão → feche o WebSocket → retorne ao estado Idle.
+
+### Fluxograma de status do modo automático
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> kDeviceStateUnknown
+ kDeviceStateUnknown --> kDeviceStateStarting: inicialização
+ kDeviceStateStarting -> kDeviceStateWifiConfigurando: Configurar WiFi
+ kDeviceStateStarting --> kDeviceStateActivating: Ativando o dispositivo
+ kDeviceStateActivating --> kDeviceStateUpgrading: Nova versão detectada
+ kDeviceStateActivating --> kDeviceStateIdle: ativação concluída
+ kDeviceStateIdle -> kDeviceStateConnecting: inicia a conexão
+ kDeviceStateConnecting --> kDeviceStateIdle: Falha na conexão
+ kDeviceStateConnecting -> kDeviceStateListening: Conexão bem-sucedida
+ kDeviceStateListening -> kDeviceStateSpeaking: comece a falar
+ kDeviceStateSpeaking -> kDeviceStateListening: Terminar a fala
+ kDeviceStateListening -> kDeviceStateIdle: encerramento manual
+ kDeviceStateSpeaking --> kDeviceStateIdle: Encerramento automático
+```
+
+### Fluxograma de status do modo manual
+
+```mermaid
+stateDiagram
+ direction TB
+ [*] --> kDeviceStateUnknown
+ kDeviceStateUnknown --> kDeviceStateStarting: inicialização
+ kDeviceStateStarting -> kDeviceStateWifiConfigurando: Configurar WiFi
+ kDeviceStateStarting --> kDeviceStateActivating: Ativando o dispositivo
+ kDeviceStateActivating --> kDeviceStateUpgrading: Nova versão detectada
+ kDeviceStateActivating --> kDeviceStateIdle: ativação concluída
+ kDeviceStateIdle -> kDeviceStateConnecting: inicia a conexão
+ kDeviceStateConnecting --> kDeviceStateIdle: Falha na conexão
+ kDeviceStateConnecting -> kDeviceStateListening: Conexão bem-sucedida
+ kDeviceStateIdle -> kDeviceStateListening: comece a ouvir
+ kDeviceStateListening -> kDeviceStateIdle: parar de ouvir
+ kDeviceStateIdle -> kDeviceStateSpeaking: comece a falar
+ kDeviceStateSpeaking -> kDeviceStateIdle: termina a fala
+```
+
+---
+
+## 7. Tratamento de erros
+
+1. **Falha na conexão**
+ - Acione o retorno de chamada `on_network_error_()` se `Connect(url)` retornar falha ou expirar enquanto espera pela mensagem "hello" do servidor. O dispositivo exibirá a mensagem “Não é possível conectar-se ao serviço” ou uma mensagem de erro semelhante.
+
+2. **Servidor desconectado**
+ - Se o WebSocket for desconectado de forma anormal, retorno de chamada `OnDisconnected()`:
+ - Retorno de chamada do dispositivo `on_audio_channel_closed_()`
+ - Mude para Idle ou outra lógica de nova tentativa.
+
+---
+
+## 8. Outros assuntos que precisam de atenção
+
+1. **Autenticação**
+ - O dispositivo fornece autenticação configurando `Autorização: Bearer `, e o servidor precisa verificar se é válido.
+ - Se o token expirar ou for inválido, o servidor poderá rejeitar o handshake ou desconectar-se posteriormente.
+
+2. **Controle de Sessão**
+ - Algumas mensagens no código contêm `session_id` para distinguir conversas ou operações independentes. O servidor pode separar sessões diferentes conforme necessário.
+
+3. **Carga de áudio**
+ - O código usa o formato Opus por padrão e define `sample_rate = 16000`, mono. A duração do quadro é controlada por `OPUS_FRAME_DURATION_MS`, geralmente 60ms. Os ajustes podem ser feitos adequadamente com base na largura de banda ou no desempenho. Para uma melhor reprodução de música, o áudio downstream do servidor pode usar uma taxa de amostragem de 24.000.
+
+4. **Configuração da versão do protocolo**
+ - Configure a versão do protocolo binário (1, 2 ou 3) através do campo `versão` nas configurações
+ - Versão 1: Envie dados Opus diretamente
+ - Versão 2: usa protocolo binário com carimbo de data e hora, adequado para AEC do lado do servidor
+ - Versão 3: usa protocolo binário simplificado
+
+5. **Protocolo MCP recomendado para controle de IoT**
+ - Recomenda-se que a descoberta de capacidade IoT, sincronização de status, instruções de controle, etc. entre dispositivos e servidores sejam implementadas através do protocolo MCP (tipo: "mcp"). A solução type: "iot" original foi descontinuada.
+ - O protocolo MCP pode ser transmitido em vários protocolos subjacentes, como WebSocket e MQTT, e possui melhores capacidades de escalabilidade e padronização.
+ - Para uso detalhado, consulte [Documento do protocolo MCP](./mcp-protocol.md) e [Uso de controle de IoT do MCP](./mcp-usage.md).
+
+6. **Erro ou exceção JSON**
+ - Quando faltarem campos necessários no JSON, como `{"type": ...}`, o dispositivo registrará um log de erros (`ESP_LOGE(TAG, "Missing message type, data: %s", data);`) e não realizará nenhum negócio.
+
+---
+
+## 9. Exemplo de mensagem
+
+Um exemplo típico de mensagem bidirecional é fornecido abaixo (processo simplificado):
+
+1. **Dispositivo → Servidor** (aperto de mão)
+ ```json
+ {
+ "type": "hello",
+ "version": 1,
+ "features": {
+ "mcp": true
+ },
+ "transport": "websocket",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000,
+ "channels": 1,
+ "frame_duration": 60
+ }
+ }
+ ```
+
+2. **Servidor → Dispositivo** (resposta de handshake)
+ ```json
+ {
+ "type": "hello",
+ "transport": "websocket",
+ "session_id": "xxx",
+ "audio_params": {
+ "format": "opus",
+ "sample_rate": 16000
+ }
+ }
+ ```
+
+3. **Dispositivo → Servidor** (iniciar monitoramento)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "listen",
+ "state": "start",
+ "mode": "auto"
+ }
+ ```
+ Ao mesmo tempo, o dispositivo começa a enviar quadros binários (dados Opus).
+
+4. **Servidor → Dispositivo** (resultado ASR)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "stt",
+ "text": "O que o usuário disse"
+ }
+ ```
+
+5. **Servidor → Dispositivo** (TTS inicia)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "tts",
+ "state": "start"
+ }
+ ```
+ Em seguida, o servidor envia quadros de áudio binários ao dispositivo para reprodução.
+
+6. **Servidor → Dispositivo** (TTS termina)
+ ```json
+ {
+ "session_id": "xxx",
+ "type": "tts",
+ "state": "stop"
+ }
+ ```
+ O dispositivo para de reproduzir áudio e retorna ao estado inativo se não houver mais instruções.
+
+---
+
+## 10. Resumo
+
+Este protocolo transmite texto JSON e quadros de áudio binários na camada superior do WebSocket e completa funções, incluindo upload de fluxo de áudio, reprodução de áudio TTS, reconhecimento de fala e gerenciamento de status, emissão de comando MCP, etc.
+
+- **Fase de handshake**: Envie `"type":"hello"` e aguarde o retorno do servidor.
+- **Canal de Áudio**: usa quadros binários codificados pelo Opus para transmitir fluxos de voz em ambas as direções, suportando múltiplas versões de protocolo.
+- **Mensagem JSON**: Use `"type"` para identificar diferentes lógicas de negócios para campos principais, incluindo TTS, STT, MCP, WakeWord, System, Custom, etc.
+- **Extensibilidade**: Os campos podem ser adicionados à mensagem JSON de acordo com as necessidades reais, ou autenticação adicional pode ser realizada nos cabeçalhos.
+
+O servidor e o dispositivo precisam concordar antecipadamente sobre os significados dos campos, a lógica de temporização e as regras de tratamento de erros de várias mensagens para garantir uma comunicação tranquila. As informações acima podem ser utilizadas como documentos básicos para facilitar posterior ancoragem, desenvolvimento ou expansão.
diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild
index 785412f38a..7fc24910b6 100644
--- a/main/Kconfig.projbuild
+++ b/main/Kconfig.projbuild
@@ -30,7 +30,7 @@ config CUSTOM_ASSETS_FILE
choice
prompt "Default Language"
- default LANGUAGE_ZH_CN
+ default LANGUAGE_PT_PT
help
Select device display language
@@ -114,7 +114,7 @@ endchoice
choice BOARD_TYPE
prompt "Board Type"
- default BOARD_TYPE_BREAD_COMPACT_WIFI
+ default BOARD_TYPE_SEEED_STUDIO_SENSECAP_WATCHER
help
Board type. 开发板类型
config BOARD_TYPE_BREAD_COMPACT_WIFI