From db4f02895509e753c35825e94913ae34910026d0 Mon Sep 17 00:00:00 2001
From: hrz <1710360675@qq.com>
Date: Sun, 13 Apr 2025 00:21:13 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=85=A8=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=E9=83=A8=E7=BD=B2=E6=96=87=E6=A1=A3=20(#753)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* update:更新文档
* update:优化文档路径
---
README.md | 47 ++-
README_en.md | 302 --------------
docs/Deployment.md | 52 +--
docs/Deployment_all.md | 443 +++++++++++++++++++++
docs/firmware-build.md | 43 +-
docs/images/deploy.png | Bin 589852 -> 0 bytes
docs/images/deploy1.png | Bin 0 -> 312895 bytes
docs/images/deploy2.png | Bin 0 -> 660012 bytes
main/README.md | 8 +-
main/manager-api/README.md | 77 +---
main/manager-web/README.md | 2 +-
main/xiaozhi-server/docker-compose.yml | 32 +-
main/xiaozhi-server/docker-compose_all.yml | 51 +++
13 files changed, 572 insertions(+), 485 deletions(-)
delete mode 100644 README_en.md
create mode 100644 docs/Deployment_all.md
delete mode 100644 docs/images/deploy.png
create mode 100644 docs/images/deploy1.png
create mode 100644 docs/images/deploy2.png
create mode 100644 main/xiaozhi-server/docker-compose_all.yml
diff --git a/README.md b/README.md
index 810ce514..f5ac9f79 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,10 @@
-English
+English
· 简体中文
· 更新日志
-· 部署文档
+· 部署文档
· 反馈问题
@@ -126,12 +126,6 @@
---
-## 系统要求与部署前提 🖥️
-
-建议 4 核 CPU、8G 内存的电脑。如果开启ASR也使用API,可运行在2核CPU、2G内存的服务器中。[请参考部署架构图](./docs/images/deploy.png)
-
----
-
## 警告 ⚠️
1、本项目为开源软件,本软件与对接的任何第三方API服务商(包括但不限于语音识别、大模型、语音合成等平台)均不存在商业合作关系,不为其服务质量及资金安全提供任何形式的担保。
@@ -155,29 +149,38 @@ server:
[](./docs/Deployment.md)
-### 一、[部署文档](./docs/Deployment.md)
+### 部署文档
-本项目支持以下三种部署方式,您可根据实际需求选择。
+本项目支持`最简化`安装和`全模块`。
-1. [Docker 快速部署](./docs/Deployment.md)
+`最简化`适合在较低资源配置中运行,无需数据库。[请参考-最简化架构图](./docs/images/deploy1.png)
-适合快速体验的普通用户,不需过多环境配置。缺点是,拉取镜像有点慢。视频教程可参考[美女大佬教你Docker部署](https://www.bilibili.com/video/BV1RNQnYDE5t)
+`全模块`适合想体验完整功能,请根据具体需求选择安装方式。[请参考-全模块安装架构图](./docs/images/deploy2.png)
-2. [借助 Docker 环境运行部署](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E5%80%9F%E5%8A%A9docker%E7%8E%AF%E5%A2%83%E8%BF%90%E8%A1%8C%E9%83%A8%E7%BD%B2)
-适用于已安装 Docker 且希望对代码进行自定义修改的软件工程师。
+#### 1、 最简化安装
-3. [本地源码运行](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%89%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C)
+`最简化`安装包含:智能对话、IOT等功能,数据存储在`配置文件`。
-适合熟悉`Conda` 环境或希望从零搭建运行环境的用户。
+##### 1.1. Docker只运行Server
-对于对响应速度要求较高的场景,推荐使用本地源码运行方式以降低额外开销。视频教程可参考[帅哥大佬教你源码部署](https://www.bilibili.com/video/BV1GvQWYZEd2)
+你可以使用编译好的docker镜像安装,[点击Docker只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E5%8F%AA%E8%BF%90%E8%A1%8Cserver)。优点:减少环境配置的烦恼;缺点:版本可能有点旧,镜像文件较大。
-### 二、[固件编译](./docs/firmware-build.md)
+##### 2.2. 本地源码只运行Server
-点这里查看[固件编译](./docs/firmware-build.md)的详细过程。
+你可以以本地源码的方式运行,[点击本地源码只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E5%8F%AA%E8%BF%90%E8%A1%8Cserver)。优点:可以随时更新最新代码;缺点:安装Conda环境较为复杂。
-烧录成功且联网成功后,通过唤醒词唤醒小智,留意server端输出的控制台信息。
+#### 2、 全模块安装
+
+`全模块`安装包含:智能对话、IOT、OTA、智控台,数据存储在`数据库`中。
+
+##### 2.1. Docker运行全模块
+
+你可以使用编译好的docker镜像安装,[点击Docker运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97)。优点:减少环境配置的烦恼;缺点:版本可能有点旧,镜像文件较大。
+
+##### 2.2. 本地源码运行全模块
+
+你可以以本地源码的方式运行,[点击本地源码运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97)。优点:可以随时更新最新代码;缺点:安装Java、Node.js、Conda环境较为复杂。
---
@@ -220,11 +223,13 @@ server:
支持超长记忆、本地总结记忆、无记忆三种模式,满足不同场景需求。
- **IOT功能**
支持管理注册设备IOT功能,支持基于对话上下文语境下的智能物联网控制。
+- **智控台**
+ 提供Web管理界面,支持智能体管理、用户管理、系统配置等功能,方便管理员和用户进行管理。
+
### 正在开发 🚧
- 多种心情模式
-- 智控台webui
想了解具体开发进度,[请点击这里](https://github.com/users/xinnan-tech/projects/3)
diff --git a/README_en.md b/README_en.md
deleted file mode 100644
index 1dd70554..00000000
--- a/README_en.md
+++ /dev/null
@@ -1,302 +0,0 @@
-[](https://github.com/xinnan-tech/xiaozhi-esp32-server)
-
-
-Xiaozhi Backend Server xiaozhi-esp32-server
-
-
-
-This project provides backend services for the open-source smart hardware project
-xiaozhi-esp32
-Implemented in Python according to the Xiaozhi Communication Protocol
-Helping you quickly set up your Xiaozhi server
-
-
-
-简体中文
-· English
-· Changelog
-· Deployment Guide
-· Report Issues
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
----
-
-## Target Users 👥
-
-This project requires ESP32 hardware devices. If you have purchased ESP32-related hardware, successfully connected to Brother Xia's backend service, and wish to set up your own `xiaozhi-esp32` backend service, then this project is perfect for you.
-
-Want to see it in action? Check out these videos 🎥
-
-
-
----
-
-## System Requirements and Prerequisites 🖥️
-
-- **Computer or Server**: Recommended 4-core CPU, 8GB RAM computer. If using ASR with API, can run on a 2-core CPU, 2GB RAM server.
-- **Update Client Interface**: Please update the backend service interface address in the client.
-
----
-
-## Warning ⚠️
-
-1. This is open-source software. This software and any third-party API service providers it interfaces with (including but not limited to speech recognition, large language models, speech synthesis, and other platforms) have no commercial partnership. We do not provide any form of guarantee for their service quality or financial security.
-We recommend users prioritize service providers with relevant business licenses and carefully read their service agreements and privacy policies. This software does not host any account keys, does not participate in fund transfers, and does not bear the risk of recharge fund losses.
-
-2. This project is relatively new and has not yet passed network security testing. Please do not use it in production environments. If you deploy this project for learning purposes in a public network environment, please make sure to enable protection in the `config.yaml` configuration file:
-
-```yaml
-server:
- auth:
- # Enable protection
- enabled: true
-```
-
-After enabling protection, you need to verify the machine's token or MAC address according to actual circumstances. Please refer to the configuration documentation for details.
-
----
-
-## Deployment Methods 🚀
-
-### I. [Deployment Guide](./docs/Deployment.md)
-
-This project supports three deployment methods. You can choose based on your actual needs.
-
-1. [Quick Docker Deployment](./docs/Deployment.md)
-
-Suitable for regular users who want to quickly experience without much environment configuration. The downside is that pulling the image can be slow. Video tutorial available: [Beautiful expert teaches Docker deployment](https://www.bilibili.com/video/BV1RNQnYDE5t)
-
-2. [Deploy Using Docker Environment](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E5%80%9F%E5%8A%A9docker%E7%8E%AF%E5%A2%83%E8%BF%90%E8%A1%8C%E9%83%A8%E7%BD%B2)
-
-For software engineers who have Docker installed and want to make custom code modifications.
-
-3. [Local Source Code Run](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%89%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C)
-
-Suitable for users familiar with `Conda` environment or who want to build the running environment from scratch.
-
-For scenarios requiring higher response speed, we recommend using the local source code run method to reduce additional overhead. Video tutorial available: [Handsome expert teaches source code deployment](https://www.bilibili.com/video/BV1GvQWYZEd2)
-
-### II. [Firmware Compilation](./docs/firmware-build.md)
-
-Click here to view the detailed process of [firmware compilation](./docs/firmware-build.md).
-
-After successful flashing and network connection, wake up Xiaozhi using the wake word and pay attention to the console output on the server side.
-
----
-
-## Common Questions ❓
-
-For issues or product suggestions, please [click here](docs/FAQ.md).
-
----
-
-## Product Ecosystem 👬
-Xiaozhi is an ecosystem. When using this product, you might want to check out other excellent projects in this ecosystem:
-
-- [Xiaozhi Android Client](https://github.com/TOM88812/xiaozhi-android-client)
- A voice dialogue application based on xiaozhi-server for Android and iOS, supporting real-time voice interaction and text dialogue. Now in Flutter version, supporting both iOS and Android.
-- [Xiaozhi PC Client](https://github.com/Huang-junsen/py-xiaozhi)
- This project provides a Python-based Xiaobai AI client, allowing you to experience Xiaozhi AI features through code even without physical hardware. Main features include AI voice interaction, visual multimodal recognition, IoT device integration, online music playback, voice wake-up, automatic dialogue mode, graphical interface, command-line mode, cross-platform support, volume control, session management, encrypted audio transmission, automatic verification code processing, etc.
-- [Xiaozhi Java Server](https://github.com/joey-zhou/xiaozhi-esp32-server-java)
-
- The Xiaozhi open-source backend service Java version is a Java-based open-source project that includes both frontend and backend services, aiming to provide users with a complete backend service solution.
----
-## Feature List ✨
-
-### Implemented ✅
-
-- **Communication Protocol**
- Based on `xiaozhi-esp32` protocol, implementing data interaction through WebSocket.
-- **Dialogue Interaction**
- Supports wake-up dialogue, manual dialogue, and real-time interruption. Automatically sleeps after long periods without dialogue
-- **Intent Recognition**
- Supports LLM intent recognition and function call, reducing hard-coded intent judgment
-- **Multi-language Recognition**
- Supports Mandarin, Cantonese, English, Japanese, Korean (default using FunASR).
-- **LLM Module**
- Supports flexible switching of LLM modules, default using ChatGLMLLM, can also use Alibaba Bailian, DeepSeek, Ollama, and other interfaces.
-- **TTS Module**
- Supports EdgeTTS (default), Volcano Engine Doubao TTS, and other TTS interfaces to meet speech synthesis needs.
-- **Memory Function**
- Supports ultra-long memory, local summary memory, and no memory modes to meet different scenario needs.
-- **IOT Function**
- Supports managing registered device IOT functions, supporting intelligent IoT control based on dialogue context.
-
-### Under Development 🚧
-
-- Multiple mood modes
-- Smart control panel webui
-
-To learn about specific development progress, [click here](https://github.com/users/xinnan-tech/projects/3)
-
-If you are a software developer, here's an [Open Letter to Developers](docs/contributor_open_letter.md), welcome to join!
-
----
-
-## Supported Platforms/Components List 📋
-
-### LLM Language Models
-
-| Usage Method | Supported Platforms | Free Platforms |
-|:---:|:---:|:---:|
-| openai interface call | Alibaba Bailian, Volcano Engine Doubao, DeepSeek, Zhipu ChatGLM, Gemini | Zhipu ChatGLM, Gemini |
-| ollama interface call | Ollama | - |
-| dify interface call | Dify | - |
-| fastgpt interface call | Fastgpt | - |
-| coze interface call | Coze | - |
-
-In fact, any LLM supporting openai interface calls can be integrated.
-
----
-
-### TTS Speech Synthesis
-
-| Usage Method | Supported Platforms | Free Platforms |
-|:---:|:---:|:---:|
-| Interface Call | EdgeTTS, Volcano Engine Doubao TTS, Tencent Cloud, Alibaba Cloud TTS, CosyVoiceSiliconflow, TTS302AI, CozeCnTTS, GizwitsTTS, ACGNTTS, OpenAITTS | EdgeTTS, CosyVoiceSiliconflow(partial) |
-| Local Service | FishSpeech, GPT_SOVITS_V2, GPT_SOVITS_V3, MinimaxTTS | FishSpeech, GPT_SOVITS_V2, GPT_SOVITS_V3, MinimaxTTS |
-
----
-
-### VAD Voice Activity Detection
-
-| Type | Platform Name | Usage Method | Pricing Model | Notes |
-|:---:|:---------:|:----:|:----:|:--:|
-| VAD | SileroVAD | Local Use | Free | |
-
----
-
-### ASR Speech Recognition
-
-| Usage Method | Supported Platforms | Free Platforms |
-|:---:|:---:|:---:|
-| Local Use | FunASR, SherpaASR | FunASR, SherpaASR |
-| Interface Call | DoubaoASR | - |
-
----
-
-### Memory Storage
-
-| Type | Platform Name | Usage Method | Pricing Model | Notes |
-|:------:|:---------------:|:----:|:---------:|:--:|
-| Memory | mem0ai | Interface Call | 1000 times/month quota | |
-| Memory | mem_local_short | Local Summary | Free | |
-
----
-
-### Intent Recognition
-
-| Type | Platform Name | Usage Method | Pricing Model | Notes |
-|:------:|:-------------:|:----:|:-------:|:---------------------:|
-| Intent | intent_llm | Interface Call | Based on LLM pricing | Intent recognition through large models, highly generalizable |
-| Intent | function_call | Interface Call | Based on LLM pricing | Intent completion through large model function calls, fast and effective |
-
----
-
-## Acknowledgments 🙏
-
-- This project was inspired by [Bailing Voice Dialogue Robot](https://github.com/wwbin2017/bailing) and implemented based on it.
-- Thanks to [Tenclass](https://www.tenclass.com/) for providing detailed documentation support for the Xiaozhi communication protocol.
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/Deployment.md b/docs/Deployment.md
index dfac9dcd..0bbe629d 100644
--- a/docs/Deployment.md
+++ b/docs/Deployment.md
@@ -1,6 +1,6 @@
-# 部署方案参考
-
-# 方式一:docker快速部署
+# 部署架构图
+
+# 方式一:Docker只运行Server
docker镜像已支持x86架构、arm64架构的CPU,支持在国产操作系统上运行。
@@ -40,7 +40,7 @@ chmod +x docker-setup.sh
>
> 执行完成后,请按照提示配置 API 密钥。
-当你一切顺利完成以上操作后,继续操作[配置项目文件](#3-配置项目文件)
+当你一切顺利完成以上操作后,继续操作[配置项目文件](#2-配置项目文件)
### 1.2 手动部署
@@ -102,14 +102,14 @@ xiaozhi-server
如果你的文件目录结构也是上面的,就继续往下。如果不是,你就再仔细看看是不是漏操作了什么。
-## 3. 配置项目文件
+## 2. 配置项目文件
接下里,程序还不能直接运行,你需要配置一下,你到底使用的是什么模型。你可以看这个教程:
[跳转到配置项目文件](#配置项目)
配置完项目文件后,回到本教程继续往下。
-## 4. 执行docker命令
+## 3. 执行docker命令
打开命令行工具,使用`终端`或`命令行`工具 进入到你的`xiaozhi-server`,执行以下命令
@@ -142,45 +142,7 @@ docker rmi ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest
5.3、重新按docker方式部署
-# 方式二:借助Docker环境运行部署
-
-开发人员如果不想安装`conda`环境,可以使用这种方法管理好依赖。
-
-## 1.克隆项目
-
-## 2.[跳转到下载语音识别模型文件](#模型文件)
-
-## 3.[跳转到配置项目文件](#配置项目)
-
-## 4.运行docker
-
-修改完配置后,打开命令行工具,`cd`进入到你的`main/xiaozhi-server`下,执行以下命令
-
-```sh
-docker run -it --name xiaozhi-env --restart always --security-opt seccomp:unconfined \
- -p 8000:8000 \
- -p 8002:8002 \
- -v ./:/app \
- kalicyh/python:xiaozhi
-```
-
-然后就和正常开发一样了
-
-## 5.安装依赖
-
-在刚刚的打开的终端运行
-
-```sh
-pip install -r requirements.txt
-```
-
-## 6.运行项目
-
-```sh
-python app.py
-```
-
-# 方式三:本地源码运行
+# 方式二:本地源码只运行Server
## 1.安装基础环境
diff --git a/docs/Deployment_all.md b/docs/Deployment_all.md
new file mode 100644
index 00000000..8c3d1c15
--- /dev/null
+++ b/docs/Deployment_all.md
@@ -0,0 +1,443 @@
+# 部署架构图
+
+# 方式一:Docker运行全模块
+docker镜像已支持x86架构、arm64架构的CPU,支持在国产操作系统上运行。
+
+## 1. 安装docker
+
+如果您的电脑还没安装docker,可以按照这里的教程安装:[docker安装](https://www.runoob.com/docker/ubuntu-docker-install.html)
+
+#### 1.1 创建目录
+
+安装完后,你需要为这个项目找一个安放配置文件的目录,例如我们可以新建一个文件夹叫`xiaozhi-server`。
+
+创建好目录后,你需要在`xiaozhi-server`下面创建`data`文件夹和`models`文件夹,`models`下面还要再创建`SenseVoiceSmall`文件夹。
+
+最终目录结构如下所示:
+
+```
+xiaozhi-server
+ ├─ data
+ ├─ models
+ ├─ SenseVoiceSmall
+```
+
+#### 1.2 下载语音识别模型文件
+
+本项目语音识别模型,默认使用`SenseVoiceSmall`模型,进行语音转文字。因为模型较大,需要独立下载,下载后把`model.pt`
+文件放在`models/SenseVoiceSmall`
+目录下。下面两个下载路线任选一个。
+
+- 线路一:阿里魔塔下载[SenseVoiceSmall](https://modelscope.cn/models/iic/SenseVoiceSmall/resolve/master/model.pt)
+- 线路二:百度网盘下载[SenseVoiceSmall](https://pan.baidu.com/share/init?surl=QlgM58FHhYv1tFnUT_A8Sg&pwd=qvna) 提取码:
+ `qvna`
+
+
+#### 1.3 下载配置文件
+
+你需要下载两个配置文件:`docker-compose_all.yaml` 和 `config_from_api.yaml`。需要从项目仓库下载这两个文件。
+
+##### 1.3.1 下载 docker-compose_all.yaml
+
+用浏览器打开[这个链接](../main/xiaozhi-server/docker-compose_all.yml)。
+
+在页面的右侧找到名称为`RAW`按钮,在`RAW`按钮的旁边,找到下载的图标,点击下载按钮,下载`docker-compose_all.yml`文件。 把文件下载到你的
+`xiaozhi-server`中。
+
+下载完后,回到本教程继续往下。
+
+##### 1.3.2 下载 config_from_api.yaml
+
+用浏览器打开[这个链接](../main/xiaozhi-server/config_from_api.yaml)。
+
+在页面的右侧找到名称为`RAW`按钮,在`RAW`按钮的旁边,找到下载的图标,点击下载按钮,下载`config_from_api.yaml`文件。 把文件下载到你的
+`xiaozhi-server`下面的`data`文件夹中,然后把`config_from_api.yaml`文件重命名为`.config.yaml`。
+
+下载完配置文件后,我们确认一下整个`xiaozhi-server`里面的文件如下所示:
+
+```
+xiaozhi-server
+ ├─ docker-compose_all.yml
+ ├─ data
+ ├─ .config.yaml
+ ├─ models
+ ├─ SenseVoiceSmall
+ ├─ model.pt
+```
+
+如果你的文件目录结构也是上面的,就继续往下。如果不是,你就再仔细看看是不是漏操作了什么。
+
+## 2. 安装Mysql和Redis
+
+### 2.1 安装Mysql数据库
+如果本机已经安装了MySQL,可以直接在数据库中创建名为`xiaozhi_esp32_server`的数据库。
+
+```sql
+CREATE DATABASE xiaozhi_esp32_server CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+```
+
+如果还没有MySQL,你可以通过docker安装mysql
+
+```
+docker run --name xiaozhi-esp32-server-db -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -e MYSQL_DATABASE=xiaozhi_esp32_server -e MYSQL_INITDB_ARGS="--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci" -d mysql:latest
+```
+
+### 2.2 安装Redis
+
+如果还没有Redis,你可以通过docker安装redis
+
+```
+docker run --name xiaozhi-esp32-server-redis -d -p 6379:6379 redis
+```
+
+## 3. 配置docker-compose_all.yml文件文件
+
+在`xiaozhi-server`目录,打开docker-compose_all.yml,
+
+1、修改`SPRING_DATASOURCE_DRUID_URL`里,把`192.168.1.25`修改成部署mysql的电脑局域网ip,如果是你本地,你要查看一下你本机的局域网ip是什么
+
+2、修改`SPRING_DATA_REDIS_HOST`里,把`192.168.1.25`修改成部署redis的电脑局域网ip,如果是你本地,你要查看一下你本机的局域网ip是什么
+
+3、确认一下mysql的用户名`SPRING_DATASOURCE_DRUID_USERNAME`和密码`SPRING_DATASOURCE_DRUID_PASSWORD`
+
+## 4. 运行程序
+
+确认mysql和redis是否运行正常,输入
+```
+docker ps
+```
+如果你能看到`xiaozhi-esp32-server-redis`和`xiaozhi-esp32-server-db`信息,就可以继续往下,如果看不到,说明你的`mysql`和`redis`没有安装或没有启动。需要继续回到上面的教程,看看哪一步漏了。
+
+```
+CONTAINER ID IMAGE COMMAND CREATED TATUS PORTS NAMES
+xxx redis "xx" xxx xxx 0.0.0.0:6379->6379/tcp xiaozhi-esp32-server-redis
+xxx mysql:latest "xx" xxx xxx 0.0.0.0:3306->3306/tcp, 33060/tcp xiaozhi-esp32-server-db
+```
+
+接下来打开命令行工具,使用`终端`或`命令行`工具 进入到你的`xiaozhi-server`,执行以下命令
+
+```
+docker-compose -f docker-compose_all.yml up -d
+```
+
+执行完后,再执行以下命令,查看日志信息。
+
+```
+docker logs -f xiaozhi-esp32-server-web
+```
+
+当你看到输出日志时,说明你的`智控台`启动成功了。
+
+```
+2025-xx-xx 22:11:12.445 [main] INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource
+2025-xx-xx 21:28:53.873 [main] INFO xiaozhi.AdminApplication - Started AdminApplication in 16.057 seconds (process running for 17.941)
+http://localhost:8002/xiaozhi/doc.html
+```
+
+请注意此刻仅是`智控台`能运行,如果8000端口`xiaozhi-esp32-server`报错,先不要理会。
+
+这时,你需要使用浏览器,打开`智控台`,链接:http://127.0.0.1:8002 ,注册第一个用户。第一个用户即是超级管理员,以后的用户都是普通用户。普通用户只能绑定设备和配置智能体;超级管理员可以进行模型管理、用户管理、参数配置等功能。
+
+接下来要做两件重要的事情:
+
+### 第一件重要的事情
+
+使用超级管理员账号,登录系统,在顶部菜单找到`参数管理`,找到列表中第三条数据,参数编码是`server.secret`,复制它到`参数值`。
+
+`server.secret`需要说明一下,这个`参数值`很重要,作用是让我们的`Server`端连接`manager-api`。`server.secret`是每次从零部署manager模块时,会自动随机生成的密钥。
+
+复制`参数值`后,打开`xiaozhi-server`下的`data`目录的`.config.yaml`文件。此刻你的配置文件内容应该是这样的:
+
+```
+manager-api:
+ url: http://127.0.0.1:8002/xiaozhi
+ secret: 你的server.secret值
+```
+1、把你刚才从`智控台`复制过来的`server.secret`的`参数值`复制到`.config.yaml`文件里的`secret`里。
+
+2、把`url`里的`127.0.0.1`改成你电脑局域网内的ip
+
+类似这样的效果
+```
+manager-api:
+ url: http://192.168.1.25:8002/xiaozhi
+ secret: 12345678-xxxx-xxxx-xxxx-123456789000
+```
+
+保存好后,继续往下做第二件重要的事情
+
+### 第二件重要的事情
+
+使用超级管理员账号,登录系统,在顶部菜单找到`模型配置`,然后在左侧栏点击`大语言模型`,找到第一条数据`智谱AI`,点击`修改`按钮,
+弹出修改框后,将你注册到的`智谱AI`的密钥填写到`API密钥`中。然后点击保存。
+
+## 5.重启xiaozhi-esp32-server
+
+接下来打开命令行工具,使用`终端`或`命令行`工具 输入
+```
+docker restart xiaozhi-esp32-server
+docker logs -f xiaozhi-esp32-server
+```
+如果你能看到,类似以下日志,则是Server启动成功的标志。
+
+```
+25-02-23 12:01:09[core.websocket_server] - INFO - Server is running at ws://xxx.xx.xx.xx:8000/xiaozhi/v1/
+25-02-23 12:01:09[core.websocket_server] - INFO - =======上面的地址是websocket协议地址,请勿用浏览器访问=======
+25-02-23 12:01:09[core.websocket_server] - INFO - 如想测试websocket请用谷歌浏览器打开test目录下的test_page.html
+25-02-23 12:01:09[core.websocket_server] - INFO - =======================================================
+```
+
+由于你是全模块部署,因此你有两个重要的接口需要写入到esp32中。
+
+OTA接口:http://你电脑局域网的ip:8002/xiaozhi/ota/
+
+Websocket接口:ws://你电脑局域网的ip:8000/xiaozhi/v1/
+
+接下来,你就可以开始 [编译esp32固件](firmware-build.md)了。
+
+
+## 6. 版本升级操作
+
+如果后期想升级版本,先备份你的模型密钥。
+
+进入`xiaozhi-server`目录
+
+5.1、执行以下命令
+
+```
+docker-compose down
+docker rmi ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest
+docker rmi ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:web_latest
+```
+
+5.2、删掉`docker-compose_all.yaml`文件
+
+5.3、重新按1.1开始部署
+
+# 方式二:本地源码运行全模块
+
+## 1.安装MySQL数据库
+
+如果本机已经安装了MySQL,可以直接在数据库中创建名为`xiaozhi_esp32_server`的数据库。
+
+```sql
+CREATE DATABASE xiaozhi_esp32_server CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+```
+
+如果还没有MySQL,你可以通过docker安装mysql
+
+```
+docker run --name xiaozhi-esp32-server-db -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -e MYSQL_DATABASE=xiaozhi_esp32_server -e MYSQL_INITDB_ARGS="--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci" -d mysql:latest
+```
+
+## 2.安装redis
+
+如果还没有Redis,你可以通过docker安装redis
+
+```
+docker run --name xiaozhi-esp32-server-redis -d -p 6379:6379 redis
+```
+
+## 3.运行manager-api程序
+
+3.1 安装JDK21,设置JDK环境变量
+
+3.2 安装Maven,设置Maven环境变量
+
+3.3 使用Vscode编程工具,安装好Java环境相关插件
+
+3.4 使用Vscode编程工具加载manager-api模块
+
+在`src/main/resources/application-dev.yml`中配置数据库连接信息
+
+```
+spring:
+ datasource:
+ username: root
+ password: 123456
+```
+在`src/main/resources/application-dev.yml`中配置Redis连接信息
+```
+spring:
+ data:
+ redis:
+ host: localhost
+ port: 6379
+ password:
+ database: 0
+```
+
+3.5 运行主程序
+
+本项目为SpringBoot项目,启动方式为:
+打开`Application.java`运行`Main`方法启动
+
+```
+路径地址:
+src/main/java/xiaozhi/AdminApplication.java
+```
+
+当你看到输出日志时,说明你的`manager-api`启动成功了。
+
+```
+2025-xx-xx 22:11:12.445 [main] INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource
+2025-xx-xx 21:28:53.873 [main] INFO xiaozhi.AdminApplication - Started AdminApplication in 16.057 seconds (process running for 17.941)
+http://localhost:8002/xiaozhi/doc.html
+```
+
+## 4.运行manager-web程序
+
+4.1 安装nodejs
+
+4.2 使用Vscode编程工具加载manager-web模块
+
+终端命令进入manager-web目录下
+
+```
+npm install
+```
+然后启动
+```
+npm run serve
+```
+
+请注意,如果你的manager-api的接口不在`http://localhost:8002`,请在开发时,修改
+`main/manager-web/.env.development`中的路径
+
+运行成功后,你需要使用浏览器,打开`智控台`,链接:http://127.0.0.1:8001 ,注册第一个用户。第一个用户即是超级管理员,以后的用户都是普通用户。普通用户只能绑定设备和配置智能体;超级管理员可以进行模型管理、用户管理、参数配置等功能。
+
+
+重要:注册成功后,使用超级管理员账号,登录系统,在顶部菜单找到`模型配置`,然后在左侧栏点击`大语言模型`,找到第一条数据`智谱AI`,点击`修改`按钮,
+弹出修改框后,将你注册到的`智谱AI`的密钥填写到`API密钥`中。然后点击保存。
+
+重要:注册成功后,使用超级管理员账号,登录系统,在顶部菜单找到`模型配置`,然后在左侧栏点击`大语言模型`,找到第一条数据`智谱AI`,点击`修改`按钮,
+弹出修改框后,将你注册到的`智谱AI`的密钥填写到`API密钥`中。然后点击保存。
+
+重要:注册成功后,使用超级管理员账号,登录系统,在顶部菜单找到`模型配置`,然后在左侧栏点击`大语言模型`,找到第一条数据`智谱AI`,点击`修改`按钮,
+弹出修改框后,将你注册到的`智谱AI`的密钥填写到`API密钥`中。然后点击保存。
+
+## 5.安装Python环境
+
+本项目使用`conda`管理依赖环境。如果不方便安装`conda`,需要根据实际的操作系统安装好`libopus`和`ffmpeg`。
+如果确定使用`conda`,则安装好后,开始执行以下命令。
+
+重要提示!windows 用户,可以通过安装`Anaconda`来管理环境。安装好`Anaconda`后,在`开始`那里搜索`anaconda`相关的关键词,
+找到`Anaconda Prpmpt`,使用管理员身份运行它。如下图。
+
+
+
+运行之后,如果你能看到命令行窗口前面有一个(base)字样,说明你成功进入了`conda`环境。那么你就可以执行以下命令了。
+
+
+
+```
+conda remove -n xiaozhi-esp32-server --all -y
+conda create -n xiaozhi-esp32-server python=3.10 -y
+conda activate xiaozhi-esp32-server
+
+# 添加清华源通道
+conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
+conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
+conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
+
+conda install libopus -y
+conda install ffmpeg -y
+```
+
+请注意,以上命令,不是一股脑执行就成功的,你需要一步步执行,每一步执行完后,都检查一下输出的日志,查看是否成功。
+
+## 6.安装本项目依赖
+
+你先要下载本项目源码,源码可以通过`git clone`命令下载,如果你不熟悉`git clone`命令。
+
+你可以用浏览器打开这个地址`https://github.com/xinnan-tech/xiaozhi-esp32-server.git`
+
+打开完,找到页面中一个绿色的按钮,写着`Code`的按钮,点开它,然后你就看到`Download ZIP`的按钮。
+
+点击它,下载本项目源码压缩包。下载到你电脑后,解压它,此时它的名字可能叫`xiaozhi-esp32-server-main`
+你需要把它重命名成`xiaozhi-esp32-server`,在这个文件里,进入到`main`文件夹,再进入到`xiaozhi-server`,好了请记住这个目录`xiaozhi-server`。
+
+```
+# 继续使用conda环境
+conda activate xiaozhi-esp32-server
+# 进入到你的项目根目录,再进入main/xiaozhi-server
+cd main/xiaozhi-server
+pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
+pip install -r requirements.txt
+```
+
+### 7.下载语音识别模型文件
+
+本项目语音识别模型,默认使用`SenseVoiceSmall`模型,进行语音转文字。因为模型较大,需要独立下载,下载后把`model.pt`
+文件放在`models/SenseVoiceSmall`
+目录下。下面两个下载路线任选一个。
+
+- 线路一:阿里魔塔下载[SenseVoiceSmall](https://modelscope.cn/models/iic/SenseVoiceSmall/resolve/master/model.pt)
+- 线路二:百度网盘下载[SenseVoiceSmall](https://pan.baidu.com/share/init?surl=QlgM58FHhYv1tFnUT_A8Sg&pwd=qvna) 提取码:
+ `qvna`
+
+## 8.配置项目文件
+
+使用超级管理员账号,登录智控台http://127.0.0.1:8001,在顶部菜单找到`参数管理`,找到列表中第三条数据,参数编码是`server.secret`,复制它到`参数值`。
+
+`server.secret`需要说明一下,这个`参数值`很重要,作用是让我们的`Server`端连接`manager-api`。`server.secret`是每次从零部署manager模块时,会自动随机生成的密钥。
+
+复制`参数值`后,打开`xiaozhi-server`下的`data`目录的`.config.yaml`文件。此刻你的配置文件内容应该是这样的:
+
+```
+manager-api:
+ url: http://127.0.0.1:8002/xiaozhi
+ secret: 你的server.secret值
+```
+
+把你刚才从`智控台`复制过来的`server.secret`的`参数值`复制到`.config.yaml`文件里的`secret`里。
+
+类似这样的效果
+```
+manager-api:
+ url: http://127.0.0.1:8002/xiaozhi
+ secret: 12345678-xxxx-xxxx-xxxx-123456789000
+```
+
+## 5.运行项目
+
+```
+# 确保在xiaozhi-server目录下执行
+conda activate xiaozhi-esp32-server
+python app.py
+```
+
+如果你能看到,类似以下日志,则是本项目服务启动成功的标志。
+
+```
+25-02-23 12:01:09[core.websocket_server] - INFO - Server is running at ws://xxx.xx.xx.xx:8000/xiaozhi/v1/
+25-02-23 12:01:09[core.websocket_server] - INFO - =======上面的地址是websocket协议地址,请勿用浏览器访问=======
+25-02-23 12:01:09[core.websocket_server] - INFO - 如想测试websocket请用谷歌浏览器打开test目录下的test_page.html
+25-02-23 12:01:09[core.websocket_server] - INFO - =======================================================
+```
+
+由于你是全模块部署,因此你有两个重要的接口需要写入到esp32中。
+
+OTA接口:http://你电脑局域网的ip:8002/xiaozhi/ota/
+
+Websocket接口:ws://你电脑局域网的ip:8000/xiaozhi/v1/
+
+接下来,你就可以开始 [编译esp32固件](firmware-build.md)了。
+
+# 常见问题
+
+以下是一些常见问题,供参考:
+
+[1、为什么我说的话,小智识别出来很多韩文、日文、英文](./FAQ.md)
+
+[2、为什么会出现“TTS 任务出错 文件不存在”?](./FAQ.md)
+
+[3、TTS 经常失败,经常超时](./FAQ.md)
+
+[4、使用Wifi能连接自建服务器,但是4G模式却接不上](./FAQ.md)
+
+[5、如何提高小智对话响应速度?](./FAQ.md)
+
+[6、我说话很慢,停顿时小智老是抢话](./FAQ.md)
+
+[7、我想通过小智控制电灯、空调、远程开关机等操作](./FAQ.md)
diff --git a/docs/firmware-build.md b/docs/firmware-build.md
index 9187681e..0dafd058 100644
--- a/docs/firmware-build.md
+++ b/docs/firmware-build.md
@@ -1,8 +1,13 @@
# 编译esp32固件
-1. 先按照这个教程配置项目环境[《Windows搭建 ESP IDF 5.3.2开发环境以及编译小智》](https://icnynnzcwou8.feishu.cn/wiki/JEYDwTTALi5s2zkGlFGcDiRknXf)
+## 第1步 配置环境
+先按照这个教程配置项目环境[《Windows搭建 ESP IDF 5.3.2开发环境以及编译小智》](https://icnynnzcwou8.feishu.cn/wiki/JEYDwTTALi5s2zkGlFGcDiRknXf)
-2. 配置好编译环境后,下载虾哥[xiaozhi-esp32](https://github.com/78/xiaozhi-esp32)项目源码,进入虾哥项目,打开`xiaozhi-esp32/main/Kconfig.projbuild`文件,找到`WEBSOCKET_URL`的`default`的内容,把`wss://api.tenclass.net`
+## 第2步 打开配置文件
+配置好编译环境后,下载虾哥[xiaozhi-esp32](https://github.com/78/xiaozhi-esp32)项目源码,进入虾哥项目,打开`xiaozhi-esp32/main/Kconfig.projbuild`文件。
+
+## 第3步 修改WEBSOCKET地址
+找到`WEBSOCKET_URL`的`default`的内容,把`wss://api.tenclass.net/xiaozhi/v1/`
改成你自己的地址,例如,我的接口地址是`ws://192.168.1.25:8000/xiaozhi/v1/`,就把内容改成这个。
修改前:
@@ -33,7 +38,32 @@ config WEBSOCKET_URL
注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。
-3. 设置编译参数
+## 第4步 修改OTA地址
+如果你是全模块部署本项目,就修改OTA接口,如果你只是部署了8000端口的xiaozhi-server,可以继续沿用虾哥团队的OTA接口。如果你不修改OTA接口,请直接忽略本第4步,直接看第5步
+
+找到`OTA_VERSION_URL`的`default`的内容,把`https://api.tenclass.net/xiaozhi/ota/`
+ 改成你自己的地址,例如,我的接口地址是`http://192.168.1.25:8000/xiaozhi/ota/`,就把内容改成这个。
+
+修改前:
+```
+config OTA_VERSION_URL
+ string "OTA Version URL"
+ default "https://api.tenclass.net/xiaozhi/ota/"
+ help
+ The application will access this URL to check for updates.
+```
+修改后:
+```
+config OTA_VERSION_URL
+ string "OTA Version URL"
+ default "http://192.168.1.25:8000/xiaozhi/ota/"
+ help
+ The application will access this URL to check for updates.
+```
+
+## 第5步 设置编译参数
+
+设置编译参数
```
# 终端命令行进入xiaozhi-esp32的根目录
@@ -52,7 +82,7 @@ idf.py menuconfig

-4. 编译固件
+## 第6步 编译固件
```
idf.py build
@@ -64,7 +94,7 @@ idf.py build
-5. 打包bin固件
+## 第7步 打包bin固件
```
cd scripts
@@ -77,7 +107,7 @@ python release.py
注意:如果执行到第二命令后,报了“zip”相关的错误,请忽略这个错误,只要`build`目录下生成固件文件`merged-binary.bin`
,对你没有太大影响,请继续。
-6. 烧录固件
+## 第8步 烧录固件
将esp32设备连接电脑,使用chrome浏览器,打开以下网址
```
@@ -89,6 +119,7 @@ https://espressif.github.io/esp-launchpad/
烧录成功且联网成功后,通过唤醒词唤醒小智,留意server端输出的控制台信息。
+## 常见问题
以下是一些常见问题,供参考:
[1、为什么我说的话,小智识别出来很多韩文、日文、英文](./FAQ.md)
diff --git a/docs/images/deploy.png b/docs/images/deploy.png
deleted file mode 100644
index e1db8a48b61297b4ed8df5623e8fc27dd1afb2c6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 589852
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