From e357cad2bb5827571c3b22af9c39d27a10723ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 26 Apr 2025 21:56:41 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=B8=BA=E6=9C=80=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E7=8E=AF=E5=A2=83=E6=8F=90=E4=BE=9BOTA?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E4=BF=A1=E6=81=AF=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/app.py | 7 ++ main/xiaozhi-server/config.yaml | 10 +- main/xiaozhi-server/core/ota_server.py | 99 ++++++++++++++++++++ main/xiaozhi-server/core/websocket_server.py | 2 +- 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 main/xiaozhi-server/core/ota_server.py diff --git a/main/xiaozhi-server/app.py b/main/xiaozhi-server/app.py index 593362b1..4dd0e29d 100644 --- a/main/xiaozhi-server/app.py +++ b/main/xiaozhi-server/app.py @@ -3,6 +3,7 @@ import sys import signal from config.settings import load_config, check_config_file from core.websocket_server import WebSocketServer +from core.ota_server import SimpleOtaServer from core.utils.util import check_ffmpeg_installed TAG = __name__ @@ -35,14 +36,20 @@ async def main(): ws_server = WebSocketServer(config) ws_task = asyncio.create_task(ws_server.start()) + # 启动 Simple OAT 服务器 + ota_server = SimpleOtaServer(config) + ota_task = asyncio.create_task(ota_server.start()) + try: await wait_for_exit() # 监听退出信号 except asyncio.CancelledError: print("任务被取消,清理资源中...") finally: ws_task.cancel() + ota_task.cancel() try: await ws_task + await ota_task except asyncio.CancelledError: pass print("服务器已关闭,程序退出。") diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index 696c82d0..dc40db90 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -9,6 +9,10 @@ server: # 服务器监听地址和端口(Server listening address and port) ip: 0.0.0.0 port: 8000 + # 最简化安装环供OTA基础信息接口 + ota_port: 8002 + # OAT返回信息时区偏移量 + timezone_offset: +8 # 认证配置 auth: # 是否启用认证 @@ -239,8 +243,8 @@ LLM: api_key: 你的deepseek web key temperature: 0.7 # 温度值 max_tokens: 500 # 最大生成token数 - top_p: 1 - top_k: 50 + top_p: 1 + top_k: 50 frequency_penalty: 0 # 频率惩罚 AliAppLLM: # 定义LLM API类型 @@ -249,7 +253,7 @@ LLM: app_id: 你的app_id # 可在这里找到你的 api_key https://bailian.console.aliyun.com/?apiKey=1#/api-key api_key: 你的api_key - # 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt) + # 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt) is_no_prompt: true # Ali_memory_id:false(不使用)|你的memory_id(请在百练应用中设置中获取) # Tips!:Ali_memory未实现多用户存储记忆(记忆按id调用) diff --git a/main/xiaozhi-server/core/ota_server.py b/main/xiaozhi-server/core/ota_server.py new file mode 100644 index 00000000..b6841ae1 --- /dev/null +++ b/main/xiaozhi-server/core/ota_server.py @@ -0,0 +1,99 @@ +import json +import time +import asyncio +from aiohttp import web +from config.logger import setup_logging +from core.connection import ConnectionHandler +from core.utils.util import get_local_ip, initialize_modules + +TAG = __name__ + + +class SimpleOtaServer: + def __init__(self, config: dict): + self.config = config + self.logger = setup_logging() + + async def start(self): + server_config = self.config["server"] + host = server_config.get("ip", "0.0.0.0") + port = int(server_config.get("ota_port")) + + if port: + self.logger.bind(tag=TAG).info( + "Simple OTA Server is running at http://{}:{}/xiaozhi/ota/", get_local_ip(), port + ) + self.logger.bind(tag=TAG).info( + "=======上面的地址为最简化安装环境提供OTA基础信息,可用作小智固件的自定义OTA地址=======" + ) + self.logger.bind(tag=TAG).info( + "如想测试OTA地址请用谷歌浏览器打开test目录下的test_page.html" + ) + self.logger.bind(tag=TAG).info( + "=============================================================\n" + ) + + app = web.Application() + + # 添加路由 + app.add_routes([ + web.post("/xiaozhi/ota/", self._handle_ota_request), + web.options("/xiaozhi/ota/", self._handle_ota_request) + ]) + + # 运行服务 + runner = web.AppRunner(app) + await runner.setup() + site = web.TCPSite(runner, host, port) + await site.start() + + # 保持服务运行 + while True: + await asyncio.sleep(3600) # 每隔 1 小时检查一次 + + async def _handle_ota_request(self, request): + """处理 /xiaozhi/ota/ 的 POST 请求""" + try: + data = await request.text() + self.logger.bind(tag=TAG).debug(f"OTA请求方法: {request.method}") + self.logger.bind(tag=TAG).debug(f"OTA请求头: {request.headers}") + self.logger.bind(tag=TAG).debug(f"OTA请求数据: {data}") + + device_id = request.headers.get("device-id", "") + if device_id: + self.logger.bind(tag=TAG).info(f"OTA请求设备ID: {device_id}") + else: + raise Exception("OTA请求设备ID为空") + + data_json = json.loads(data) + + server_config = self.config["server"] + host = server_config.get("ip", "0.0.0.0") + port = int(server_config.get("port", 8000)) + local_ip = get_local_ip() + + # OTA基础信息 + return_json = { + "server_time":{ + "timestamp": int(round(time.time() * 1000)), + "timezone_offset": server_config.get("timezone_offset", 8) * 60 + }, + "firmware": { + "version": data_json["application"].get("version", "1.0.0"), + "url": "" + }, + "websocket":{ + "url": f"ws://{local_ip}:{port}/xiaozhi/v1/", + } + } + response = web.Response(text=json.dumps(return_json, separators=(',', ':')), content_type="application/json") + except Exception as e: + self.logger.bind(tag=TAG).error(f"OTA请求异常: {e}") + return_json = {"success": False, "message": "request error."} + response = web.Response(text=json.dumps(return_json, separators=(',', ':')), content_type="application/json") + finally: + # 添加header,允许跨域访问 + response.headers["Access-Control-Allow-Headers"] = "client-id, content-type, device-id" + response.headers["Access-Control-Allow-Credentials"] = "true" + response.headers["Access-Control-Allow-Origin"] = "*" + return response diff --git a/main/xiaozhi-server/core/websocket_server.py b/main/xiaozhi-server/core/websocket_server.py index d5fb69db..358eea5d 100644 --- a/main/xiaozhi-server/core/websocket_server.py +++ b/main/xiaozhi-server/core/websocket_server.py @@ -28,7 +28,7 @@ class WebSocketServer: port = int(server_config.get("port", 8000)) self.logger.bind(tag=TAG).info( - "Server is running at ws://{}:{}/xiaozhi/v1/", get_local_ip(), port + "Web Socket Server is running at ws://{}:{}/xiaozhi/v1/", get_local_ip(), port ) self.logger.bind(tag=TAG).info( "=======上面的地址是websocket协议地址,请勿用浏览器访问=======" From 5ddc2451c1bc85fcea668d5d2a9158a3c679faf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E=E4=BE=A8?= Date: Sat, 26 Apr 2025 22:07:21 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Deployment.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/Deployment.md b/docs/Deployment.md index 508fa754..c9963482 100644 --- a/docs/Deployment.md +++ b/docs/Deployment.md @@ -240,7 +240,7 @@ selected_module: LLM: ChatGLMLLM TTS: EdgeTTS # 默认不开启记忆,如需开启请看配置文件里的描述 - Memory: nomem + Memory: nomem # 默认不开启意图识别,如需开启请看配置文件里的描述 Intent: nointent ``` @@ -276,17 +276,22 @@ LLM: 如果你能看到,类似以下日志,则是本项目服务启动成功的标志。 ``` -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 - ======================================================= +250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-Web Socket Server is running at ws://xx.xx.xx.xx:8000/xiaozhi/v1/ +250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-=======上面的地址是websocket协议地址,请勿用浏览器访问======= +250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-如想测试websocket请用谷歌浏览器打开test目录下的test_page.html +250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-============================================================= + +250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-Simple OTA Server is running at http://xx.xx.xx.xx:8002/xiaozhi/ota/ +250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-=======上面的地址为最简化安装环境提供OTA基础信息,可用作小智固件v1.6.1及以后版本的自定义OTA地址======= +250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-如想测试OTA地址请用谷歌浏览器打开test目录下的test_page.html +250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-============================================================= ``` 正常来说,如果您是通过源码运行本项目,日志会有你的接口地址信息。 但是如果你用docker部署,那么你的日志里给出的接口地址信息就不是真实的接口地址。 最正确的方法,是根据电脑的局域网IP来确定你的接口地址。 -如果你的电脑的局域网IP比如是`192.168.1.25`,那么你的接口地址就是:`ws://192.168.1.25:8000/xiaozhi/v1/`。 +如果你的电脑的局域网IP比如是`192.168.1.25`,那么你的接口地址就是:`ws://192.168.1.25:8000/xiaozhi/v1/`,对应的OTA地址就是:`http://192.168.1.25:8002/xiaozhi/ota/`。 这个信息很有用的,后面`编译esp32固件`需要用到。 From b46bd4d0dd834e4c35e1bf0b8a768665338150c0 Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sun, 27 Apr 2025 13:07:14 +0800 Subject: [PATCH 3/5] =?UTF-8?q?update:=E5=85=BC=E5=AE=B9=E5=85=A8=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E9=83=A8=E7=BD=B2=EF=BC=8C=E4=B8=8D=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=87=AA=E5=B8=A6=E7=9A=84OTA=20=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/app.py | 46 ++++++++-- main/xiaozhi-server/config.yaml | 9 +- main/xiaozhi-server/core/ota_server.py | 90 ++++++++++++++------ main/xiaozhi-server/core/websocket_server.py | 12 --- 4 files changed, 111 insertions(+), 46 deletions(-) diff --git a/main/xiaozhi-server/app.py b/main/xiaozhi-server/app.py index 4dd0e29d..2a80c6ca 100644 --- a/main/xiaozhi-server/app.py +++ b/main/xiaozhi-server/app.py @@ -5,8 +5,11 @@ from config.settings import load_config, check_config_file from core.websocket_server import WebSocketServer from core.ota_server import SimpleOtaServer from core.utils.util import check_ffmpeg_installed +from config.logger import setup_logging +from core.utils.util import get_local_ip TAG = __name__ +logger = setup_logging() async def wait_for_exit(): @@ -35,10 +38,41 @@ async def main(): # 启动 WebSocket 服务器 ws_server = WebSocketServer(config) ws_task = asyncio.create_task(ws_server.start()) + ota_task = None - # 启动 Simple OAT 服务器 - ota_server = SimpleOtaServer(config) - ota_task = asyncio.create_task(ota_server.start()) + read_config_from_api = config.get("read_config_from_api", False) + if not read_config_from_api: + # 启动 Simple OAT 服务器 + ota_server = SimpleOtaServer(config) + ota_task = asyncio.create_task(ota_server.start()) + + logger.bind(tag=TAG).info( + "OTA接口是\t\thttp://{}:{}/xiaozhi/ota/", + get_local_ip(), + config["server"]["ota_port"], + ) + + # 获取WebSocket配置,使用安全的默认值 + websocket_port = 8000 + server_config = config.get("server", {}) + if isinstance(server_config, dict): + websocket_port = int(server_config.get("port", 8000)) + + logger.bind(tag=TAG).info( + "Websocket地址是\tws://{}:{}/xiaozhi/v1/", + get_local_ip(), + websocket_port, + ) + + logger.bind(tag=TAG).info( + "=======上面的地址是websocket协议地址,请勿用浏览器访问=======" + ) + logger.bind(tag=TAG).info( + "如想测试websocket请用谷歌浏览器打开test目录下的test_page.html" + ) + logger.bind(tag=TAG).info( + "=============================================================\n" + ) try: await wait_for_exit() # 监听退出信号 @@ -46,10 +80,12 @@ async def main(): print("任务被取消,清理资源中...") finally: ws_task.cancel() - ota_task.cancel() + if ota_task: + ota_task.cancel() try: await ws_task - await ota_task + if ota_task: + await ota_task except asyncio.CancelledError: pass print("服务器已关闭,程序退出。") diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index dc40db90..4b93d87e 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -9,9 +9,14 @@ server: # 服务器监听地址和端口(Server listening address and port) ip: 0.0.0.0 port: 8000 - # 最简化安装环供OTA基础信息接口 + # OTA接口的端口号 ota_port: 8002 - # OAT返回信息时区偏移量 + # 这个websocket配置是指ota接口向设备发送的websocket地址 + # 如果按默认的写法,ota接口会自动生成websocket地址。这个地址你可以直接用浏览器访问ota接口确认一下 + # 当你使用docker部署或使用公网部署(使用ssl、域名)时,不一定准确 + # 所以如果你使用docker部署或使用公网部署时,请设置正确的websocket地址 + websocket: ws://你的ip或者域名:端口号/xiaozhi/v1/ + # OTA返回信息时区偏移量 timezone_offset: +8 # 认证配置 auth: diff --git a/main/xiaozhi-server/core/ota_server.py b/main/xiaozhi-server/core/ota_server.py index b6841ae1..383725d9 100644 --- a/main/xiaozhi-server/core/ota_server.py +++ b/main/xiaozhi-server/core/ota_server.py @@ -14,32 +14,39 @@ class SimpleOtaServer: self.config = config self.logger = setup_logging() + def _get_websocket_url(self, local_ip: str, port: int) -> str: + """获取websocket地址 + + Args: + local_ip: 本地IP地址 + port: 端口号 + + Returns: + str: websocket地址 + """ + server_config = self.config["server"] + websocket_config = server_config.get("websocket") + + if websocket_config and "你" not in websocket_config: + return websocket_config + else: + return f"ws://{local_ip}:{port}/xiaozhi/v1/" + async def start(self): server_config = self.config["server"] host = server_config.get("ip", "0.0.0.0") port = int(server_config.get("ota_port")) if port: - self.logger.bind(tag=TAG).info( - "Simple OTA Server is running at http://{}:{}/xiaozhi/ota/", get_local_ip(), port - ) - self.logger.bind(tag=TAG).info( - "=======上面的地址为最简化安装环境提供OTA基础信息,可用作小智固件的自定义OTA地址=======" - ) - self.logger.bind(tag=TAG).info( - "如想测试OTA地址请用谷歌浏览器打开test目录下的test_page.html" - ) - self.logger.bind(tag=TAG).info( - "=============================================================\n" - ) - app = web.Application() - # 添加路由 - app.add_routes([ - web.post("/xiaozhi/ota/", self._handle_ota_request), - web.options("/xiaozhi/ota/", self._handle_ota_request) - ]) + app.add_routes( + [ + web.get("/xiaozhi/ota/", self._handle_ota_get_request), + web.post("/xiaozhi/ota/", self._handle_ota_request), + web.options("/xiaozhi/ota/", self._handle_ota_request), + ] + ) # 运行服务 runner = web.AppRunner(app) @@ -74,26 +81,55 @@ class SimpleOtaServer: # OTA基础信息 return_json = { - "server_time":{ + "server_time": { "timestamp": int(round(time.time() * 1000)), - "timezone_offset": server_config.get("timezone_offset", 8) * 60 + "timezone_offset": server_config.get("timezone_offset", 8) * 60, }, "firmware": { "version": data_json["application"].get("version", "1.0.0"), - "url": "" + "url": "", + }, + "websocket": { + "url": self._get_websocket_url(local_ip, port), }, - "websocket":{ - "url": f"ws://{local_ip}:{port}/xiaozhi/v1/", - } } - response = web.Response(text=json.dumps(return_json, separators=(',', ':')), content_type="application/json") + response = web.Response( + text=json.dumps(return_json, separators=(",", ":")), + content_type="application/json", + ) except Exception as e: self.logger.bind(tag=TAG).error(f"OTA请求异常: {e}") return_json = {"success": False, "message": "request error."} - response = web.Response(text=json.dumps(return_json, separators=(',', ':')), content_type="application/json") + response = web.Response( + text=json.dumps(return_json, separators=(",", ":")), + content_type="application/json", + ) finally: # 添加header,允许跨域访问 - response.headers["Access-Control-Allow-Headers"] = "client-id, content-type, device-id" + response.headers["Access-Control-Allow-Headers"] = ( + "client-id, content-type, device-id" + ) + response.headers["Access-Control-Allow-Credentials"] = "true" + response.headers["Access-Control-Allow-Origin"] = "*" + return response + + async def _handle_ota_get_request(self, request): + """处理 /xiaozhi/ota/ 的 GET 请求""" + try: + server_config = self.config["server"] + local_ip = get_local_ip() + port = int(server_config.get("port", 8000)) + websocket_url = self._get_websocket_url(local_ip, port) + message = f"OTA接口运行正常,向设备发送的websocket地址是:{websocket_url}" + response = web.Response(text=message, content_type="text/plain") + except Exception as e: + self.logger.bind(tag=TAG).error(f"OTA GET请求异常: {e}") + response = web.Response(text="OTA接口异常", content_type="text/plain") + finally: + # 添加header,允许跨域访问 + response.headers["Access-Control-Allow-Headers"] = ( + "client-id, content-type, device-id" + ) response.headers["Access-Control-Allow-Credentials"] = "true" response.headers["Access-Control-Allow-Origin"] = "*" return response diff --git a/main/xiaozhi-server/core/websocket_server.py b/main/xiaozhi-server/core/websocket_server.py index 358eea5d..038379d2 100644 --- a/main/xiaozhi-server/core/websocket_server.py +++ b/main/xiaozhi-server/core/websocket_server.py @@ -27,18 +27,6 @@ class WebSocketServer: host = server_config.get("ip", "0.0.0.0") port = int(server_config.get("port", 8000)) - self.logger.bind(tag=TAG).info( - "Web Socket Server is running at ws://{}:{}/xiaozhi/v1/", get_local_ip(), port - ) - self.logger.bind(tag=TAG).info( - "=======上面的地址是websocket协议地址,请勿用浏览器访问=======" - ) - self.logger.bind(tag=TAG).info( - "如想测试websocket请用谷歌浏览器打开test目录下的test_page.html" - ) - self.logger.bind(tag=TAG).info( - "=============================================================\n" - ) async with websockets.serve(self._handle_connection, host, port): await asyncio.Future() From 96d0f2e6f9bbec091a30890f8f4c7f3d6dd2888b Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sun, 27 Apr 2025 13:34:17 +0800 Subject: [PATCH 4/5] =?UTF-8?q?update:=E6=9B=B4=E6=96=B0=E6=95=99=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- docs/Deployment.md | 6 +- docs/firmware-build-1.6.0.md | 118 ------------------ docs/firmware-build.md | 21 +++- .../xiaozhi/common/constant/Constant.java | 2 +- main/xiaozhi-server/config/logger.py | 2 +- 6 files changed, 28 insertions(+), 125 deletions(-) delete mode 100644 docs/firmware-build-1.6.0.md diff --git a/README.md b/README.md index 4f762d97..989cc130 100644 --- a/README.md +++ b/README.md @@ -156,8 +156,8 @@ server: | 部署方式 | 特点 | 适用场景 | Docker部署文档 | 源码部署文档 | |---------|------|---------|---------|---------| -| **最简化安装** | 智能对话、IOT功能,数据存储在配置文件 | 低配置环境,无需数据库,仅支持虾哥1.6.0及以下固件版本 | [Docker只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E5%8F%AA%E8%BF%90%E8%A1%8Cserver) | [本地源码只运行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)| -| **全模块安装** | 智能对话、IOT、OTA、智控台,数据存储在数据库 | 完整功能体验,支持虾哥最新固件 |[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) | [本地源码运行全模块](./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) | +| **最简化安装** | 智能对话、IOT功能,数据存储在配置文件 | 低配置环境,无需数据库 | [Docker只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E5%8F%AA%E8%BF%90%E8%A1%8Cserver) | [本地源码只运行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)| +| **全模块安装** | 智能对话、IOT、OTA、智控台,数据存储在数据库 | 完整功能体验 |[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) | [本地源码运行全模块](./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) | > 💡 提示:以下是按最新代码部署后的测试平台,有需要可烧录测试,并发为6个,每天会清空数据 diff --git a/docs/Deployment.md b/docs/Deployment.md index c9963482..b0c934da 100644 --- a/docs/Deployment.md +++ b/docs/Deployment.md @@ -295,7 +295,11 @@ LLM: 这个信息很有用的,后面`编译esp32固件`需要用到。 -接下来,你就可以开始 [编译1.6.0版本esp32固件](firmware-build.md)了。 +接下来,你就可以开始操作你的esp32设备了,你可以`自行编译esp32固件`也可以配置使用`虾哥编译好的1.6.1以上版本的固件`。两个任选一个 + +1、 [编译自己的esp32固件](firmware-build.md)了。 + +2、 [基于虾哥编译好的固件配置自定义服务器](firmware-setting.md)了。 以下是一些常见问题,供参考: diff --git a/docs/firmware-build-1.6.0.md b/docs/firmware-build-1.6.0.md deleted file mode 100644 index c5485685..00000000 --- a/docs/firmware-build-1.6.0.md +++ /dev/null @@ -1,118 +0,0 @@ -# 编译1.6.0版本esp32固件 - -## 第1步 配置环境 -先按照这个教程配置项目环境[《Windows搭建 ESP IDF 5.3.2开发环境以及编译小智》](https://icnynnzcwou8.feishu.cn/wiki/JEYDwTTALi5s2zkGlFGcDiRknXf) - -## 第2步 打开配置文件 -配置好编译环境后,下载虾哥iaozhi-esp32项目源码, - - -从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。 - -从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。 - -从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。 - -下载后,解压缩包,打开`xiaozhi-esp32/main/Kconfig.projbuild`文件。 - - -## 第3步 修改WEBSOCKET地址 -找到`WEBSOCKET_URL`的`default`的内容,把`wss://api.tenclass.net/xiaozhi/v1/` - 改成你自己的地址,例如,我的接口地址是`ws://192.168.1.25:8000/xiaozhi/v1/`,就把内容改成这个。 - -修改前: - -``` -config WEBSOCKET_URL - depends on CONNECTION_TYPE_WEBSOCKET - string "Websocket URL" - default "wss://api.tenclass.net/xiaozhi/v1/" - help - Communication with the server through websocket after wake up. -``` - -修改后(示例): - -``` -config WEBSOCKET_URL - depends on CONNECTION_TYPE_WEBSOCKET - string "Websocket URL" - default "ws://192.168.1.25:8000/xiaozhi/v1/" - help - Communication with the server through websocket after wake up. -``` - -注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。 - -注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。 - -注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。 - -## 第4步 设置编译参数 - -设置编译参数 - -``` -# 终端命令行进入xiaozhi-esp32的根目录 -cd xiaozhi-esp32 -# 例如我使用的板子是esp32s3,所以设置编译目标为esp32s3,如果你的板子是其他型号,请替换成对应的型号 -idf.py set-target esp32s3 -# 进入菜单配置 -idf.py menuconfig -``` - -![图片](images/build_setting01.png) - -进入菜单配置后,再进入`Xiaozhi Assistant`,将`CONNECTION_TYPE`设置为`Websocket` -回退到主菜单,再进入`Xiaozhi Assistant`,将`BOARD_TYPE`设置你板子的具体型号 -保存退出,回到终端命令行。 - -![图片](images/build_setting02.png) - -## 第5步 编译固件 - -``` -idf.py build -``` - -## 第6步 打包bin固件 - -``` -cd scripts -python release.py -``` - -上面的打包命令执行完成后,会在项目根目录下的`build`目录下生成固件文件`merged-binary.bin`。 -这个`merged-binary.bin`就是要烧录到硬件上的固件文件。 - -注意:如果执行到第二命令后,报了“zip”相关的错误,请忽略这个错误,只要`build`目录下生成固件文件`merged-binary.bin` -,对你没有太大影响,请继续。 - -## 第7步 烧录固件 - 将esp32设备连接电脑,使用chrome浏览器,打开以下网址 - -``` -https://espressif.github.io/esp-launchpad/ -``` - -打开这个教程,[Flash工具/Web端烧录固件(无IDF开发环境)](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)。 -翻到:`方式二:ESP-Launchpad 浏览器WEB端烧录`,从`3. 烧录固件/下载到开发板`开始,按照教程操作。 - -烧录成功且联网成功后,通过唤醒词唤醒小智,留意server端输出的控制台信息。 - -## 常见问题 -以下是一些常见问题,供参考: - -[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 57ee79b2..f9935951 100644 --- a/docs/firmware-build.md +++ b/docs/firmware-build.md @@ -1,14 +1,31 @@ # esp32固件编译 ## 第1步 准备你的ota地址 -如果你按照教程使用的是全模块部署,就应该会有ota地址。 +如果你,使用的是本项目0.3.12版本,不管是简单Server部署还是全模块部署,都会有ota地址。 + +由于简单Server部署和全模块部署的OTA地址设置方式不一样,请你选择下面的具体方式: + +### 如果你用的是简单Server部署 +此刻,请你用浏览器打开你的ota地址,例如我的ota地址 +``` +http://192.168.1.25:8002/xiaozhi/ota/ +``` +如果显示“OTA接口运行正常,向设备发送的websocket地址是:ws://xxx:8000/xiaozhi/v1/ + +你可以使用项目自带的`test_page.html`测试一下,是否能连上ota页面输出的websocket地址。 + +如果访问不到,你需要到配置文件`.config.yaml`里修改`server.websocket`的地址,重启后再重新测试,直到`test_page.html`能正常访问。 + +成功后,请往下进行第2步 + +### 如果你用的是全模块部署 此刻,请你用浏览器打开你的ota地址,例如我的ota地址 ``` http://192.168.1.25:8002/xiaozhi/ota/ ``` -如果显示“OTA接口运行正常,websocket集群数量:X”。那就往下。 +如果显示“OTA接口运行正常,websocket集群数量:X”。那就往下进行2步。 如果显示“OTA接口运行不正常”,大概是你还没在`智控台`配置`Websocket`地址。那就: diff --git a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java index 1edea3fd..cee9727e 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java +++ b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java @@ -177,5 +177,5 @@ public interface Constant { /** * 版本号 */ - public static final String VERSION = "0.3.11"; + public static final String VERSION = "0.3.12"; } \ No newline at end of file diff --git a/main/xiaozhi-server/config/logger.py b/main/xiaozhi-server/config/logger.py index 705b244c..f42ca6c0 100644 --- a/main/xiaozhi-server/config/logger.py +++ b/main/xiaozhi-server/config/logger.py @@ -3,7 +3,7 @@ import sys from loguru import logger from config.config_loader import load_config -SERVER_VERSION = "0.3.11" +SERVER_VERSION = "0.3.12" def get_module_abbreviation(module_name, module_dict): From 2d6049b7bd28a898be5ca4d9baddd6a8cfd7d38c Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sun, 27 Apr 2025 13:55:04 +0800 Subject: [PATCH 5/5] =?UTF-8?q?update=EF=BC=9A=E4=BC=98=E5=8C=96=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Deployment.md | 14 +++++--------- docs/Deployment_all.md | 2 +- main/xiaozhi-server/app.py | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/Deployment.md b/docs/Deployment.md index b0c934da..03147198 100644 --- a/docs/Deployment.md +++ b/docs/Deployment.md @@ -276,15 +276,11 @@ LLM: 如果你能看到,类似以下日志,则是本项目服务启动成功的标志。 ``` -250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-Web Socket Server is running at ws://xx.xx.xx.xx:8000/xiaozhi/v1/ -250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-=======上面的地址是websocket协议地址,请勿用浏览器访问======= -250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-如想测试websocket请用谷歌浏览器打开test目录下的test_page.html -250426 21:44:42[0.3.11_SiFuChEdnofu][core.websocket_server]-INFO-============================================================= - -250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-Simple OTA Server is running at http://xx.xx.xx.xx:8002/xiaozhi/ota/ -250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-=======上面的地址为最简化安装环境提供OTA基础信息,可用作小智固件v1.6.1及以后版本的自定义OTA地址======= -250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-如想测试OTA地址请用谷歌浏览器打开test目录下的test_page.html -250426 21:44:42[0.3.11_SiFuChEdnofu][core.ota_server]-INFO-============================================================= +250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-OTA接口是 http://192.168.4.123:8002/xiaozhi/ota/ +250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-Websocket地址是 ws://192.168.4.123:8000/xiaozhi/v1/ +250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-=======上面的地址是websocket协议地址,请勿用浏览器访问======= +250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-如想测试websocket请用谷歌浏览器打开test目录下的test_page.html +250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-======================================================= ``` 正常来说,如果您是通过源码运行本项目,日志会有你的接口地址信息。 diff --git a/docs/Deployment_all.md b/docs/Deployment_all.md index a2112227..0d372353 100644 --- a/docs/Deployment_all.md +++ b/docs/Deployment_all.md @@ -169,7 +169,7 @@ 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地址是 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 - ======================================================= diff --git a/main/xiaozhi-server/app.py b/main/xiaozhi-server/app.py index 2a80c6ca..63b40d71 100644 --- a/main/xiaozhi-server/app.py +++ b/main/xiaozhi-server/app.py @@ -42,7 +42,7 @@ async def main(): read_config_from_api = config.get("read_config_from_api", False) if not read_config_from_api: - # 启动 Simple OAT 服务器 + # 启动 Simple OTA 服务器 ota_server = SimpleOtaServer(config) ota_task = asyncio.create_task(ota_server.start())