xiaozhi-sdk 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xiaozhi_sdk-0.2.0/LICENSE +21 -0
- xiaozhi_sdk-0.2.0/MANIFEST.in +5 -0
- xiaozhi_sdk-0.2.0/PKG-INFO +90 -0
- xiaozhi_sdk-0.2.0/README.md +63 -0
- xiaozhi_sdk-0.2.0/file/audio/greet.wav +0 -0
- xiaozhi_sdk-0.2.0/file/audio/play_music.wav +0 -0
- xiaozhi_sdk-0.2.0/file/audio/say_hello.wav +0 -0
- xiaozhi_sdk-0.2.0/file/audio/take_photo.wav +0 -0
- xiaozhi_sdk-0.2.0/file/image/leijun.jpg +0 -0
- xiaozhi_sdk-0.2.0/file/opus/linux-arm64-libopus.so +0 -0
- xiaozhi_sdk-0.2.0/file/opus/linux-x64-libopus.so +0 -0
- xiaozhi_sdk-0.2.0/file/opus/macos-arm64-libopus.dylib +0 -0
- xiaozhi_sdk-0.2.0/file/opus/macos-x64-libopus.dylib +0 -0
- xiaozhi_sdk-0.2.0/file/opus/windows-opus.dll +0 -0
- xiaozhi_sdk-0.2.0/pyproject.toml +67 -0
- xiaozhi_sdk-0.2.0/tests/test_iot.py +28 -0
- {xiaozhi_sdk-0.1.0 → xiaozhi_sdk-0.2.0}/tests/test_pic.py +5 -4
- xiaozhi_sdk-0.2.0/tests/test_wake_word.py +31 -0
- xiaozhi_sdk-0.2.0/tests/test_xiaozhi.py +106 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/__init__.py +3 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/__main__.py +11 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/cli.py +231 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/config.py +3 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/core.py +269 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/iot.py +84 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/mcp.py +171 -0
- {xiaozhi_sdk-0.1.0 → xiaozhi_sdk-0.2.0}/xiaozhi_sdk/opus.py +13 -11
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/utils/__init__.py +57 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk/utils/mcp_tool.py +185 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk.egg-info/PKG-INFO +90 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk.egg-info/SOURCES.txt +43 -0
- xiaozhi_sdk-0.2.0/xiaozhi_sdk.egg-info/requires.txt +13 -0
- xiaozhi_sdk-0.1.0/PKG-INFO +0 -58
- xiaozhi_sdk-0.1.0/README.md +0 -33
- xiaozhi_sdk-0.1.0/setup.py +0 -24
- xiaozhi_sdk-0.1.0/tests/test_xiaozhi.py +0 -92
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/__init__.py +0 -155
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/__main__.py +0 -90
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/config.py +0 -5
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/data.py +0 -58
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/iot.py +0 -50
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/mcp.py +0 -75
- xiaozhi_sdk-0.1.0/xiaozhi_sdk/utils.py +0 -23
- xiaozhi_sdk-0.1.0/xiaozhi_sdk.egg-info/PKG-INFO +0 -58
- xiaozhi_sdk-0.1.0/xiaozhi_sdk.egg-info/SOURCES.txt +0 -17
- xiaozhi_sdk-0.1.0/xiaozhi_sdk.egg-info/requires.txt +0 -3
- {xiaozhi_sdk-0.1.0 → xiaozhi_sdk-0.2.0}/setup.cfg +0 -0
- {xiaozhi_sdk-0.1.0 → xiaozhi_sdk-0.2.0}/xiaozhi_sdk.egg-info/dependency_links.txt +0 -0
- {xiaozhi_sdk-0.1.0 → xiaozhi_sdk-0.2.0}/xiaozhi_sdk.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 dairoot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xiaozhi-sdk
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: 一个用于连接和控制小智智能设备的Python SDK,支持实时音频通信、MCP工具集成和设备管理功能。
|
|
5
|
+
Author-email: dairoot <623815825@qq.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dairoot/xiaozhi-sdk
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: numpy
|
|
14
|
+
Requires-Dist: websockets>=15.0.1
|
|
15
|
+
Requires-Dist: aiohttp
|
|
16
|
+
Requires-Dist: av
|
|
17
|
+
Requires-Dist: opuslib
|
|
18
|
+
Requires-Dist: requests
|
|
19
|
+
Requires-Dist: sounddevice
|
|
20
|
+
Requires-Dist: python-socks
|
|
21
|
+
Requires-Dist: click
|
|
22
|
+
Requires-Dist: colorlog
|
|
23
|
+
Requires-Dist: soundfile>=0.13.1
|
|
24
|
+
Requires-Dist: pydub>=0.25.1
|
|
25
|
+
Requires-Dist: pillow>=11.3.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# 小智SDK (XiaoZhi SDK)
|
|
29
|
+
|
|
30
|
+
[](https://www.python.org/downloads/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
[](https://pypi.org/project/xiaozhi-sdk/)
|
|
33
|
+
|
|
34
|
+
基于虾哥的 [小智esp32 websocket 通讯协议](https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md) 实现的 Python SDK。
|
|
35
|
+
|
|
36
|
+
一个用于连接和控制小智设备的 Python SDK。支持以下功能:
|
|
37
|
+
- 实时音频通信
|
|
38
|
+
- MCP 工具集成
|
|
39
|
+
- 设备管理与控制
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 📦 安装
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install xiaozhi-sdk
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🚀 快速开始
|
|
52
|
+
|
|
53
|
+
### 1. 终端使用
|
|
54
|
+
|
|
55
|
+
最简单的方式是通过终端直接连接设备:
|
|
56
|
+
|
|
57
|
+
#### 查看帮助信息
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m xiaozhi_sdk --help
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### 连接设备(需要提供 MAC 地址)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
python -m xiaozhi_sdk 00:22:44:66:88:00
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. 编程使用 (高阶用法)
|
|
70
|
+
参考 [examples](examples/) 文件中的示例代码,可以快速开始使用 SDK。
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## ✅ 运行测试
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 安装开发依赖
|
|
79
|
+
uv sync --group dev
|
|
80
|
+
|
|
81
|
+
# 运行测试
|
|
82
|
+
uv run pytest
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 🫡 致敬
|
|
89
|
+
|
|
90
|
+
- 🫡 虾哥的 [xiaozhi-esp32](https://github.com/78/xiaozhi-esp32) 项目
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# 小智SDK (XiaoZhi SDK)
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://pypi.org/project/xiaozhi-sdk/)
|
|
6
|
+
|
|
7
|
+
基于虾哥的 [小智esp32 websocket 通讯协议](https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md) 实现的 Python SDK。
|
|
8
|
+
|
|
9
|
+
一个用于连接和控制小智设备的 Python SDK。支持以下功能:
|
|
10
|
+
- 实时音频通信
|
|
11
|
+
- MCP 工具集成
|
|
12
|
+
- 设备管理与控制
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📦 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install xiaozhi-sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🚀 快速开始
|
|
25
|
+
|
|
26
|
+
### 1. 终端使用
|
|
27
|
+
|
|
28
|
+
最简单的方式是通过终端直接连接设备:
|
|
29
|
+
|
|
30
|
+
#### 查看帮助信息
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
python -m xiaozhi_sdk --help
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### 连接设备(需要提供 MAC 地址)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python -m xiaozhi_sdk 00:22:44:66:88:00
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. 编程使用 (高阶用法)
|
|
43
|
+
参考 [examples](examples/) 文件中的示例代码,可以快速开始使用 SDK。
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ✅ 运行测试
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 安装开发依赖
|
|
52
|
+
uv sync --group dev
|
|
53
|
+
|
|
54
|
+
# 运行测试
|
|
55
|
+
uv run pytest
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🫡 致敬
|
|
62
|
+
|
|
63
|
+
- 🫡 虾哥的 [xiaozhi-esp32](https://github.com/78/xiaozhi-esp32) 项目
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "xiaozhi-sdk"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "一个用于连接和控制小智智能设备的Python SDK,支持实时音频通信、MCP工具集成和设备管理功能。"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{name = "dairoot", email = "623815825@qq.com"}]
|
|
11
|
+
license = "MIT"
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"numpy",
|
|
15
|
+
"websockets>=15.0.1",
|
|
16
|
+
"aiohttp",
|
|
17
|
+
"av",
|
|
18
|
+
"opuslib",
|
|
19
|
+
"requests",
|
|
20
|
+
"sounddevice",
|
|
21
|
+
"python-socks",
|
|
22
|
+
"click",
|
|
23
|
+
"colorlog",
|
|
24
|
+
"soundfile>=0.13.1",
|
|
25
|
+
"pydub>=0.25.1",
|
|
26
|
+
"pillow>=11.3.0",
|
|
27
|
+
]
|
|
28
|
+
classifiers = [
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/dairoot/xiaozhi-sdk"
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.dynamic]
|
|
37
|
+
version = {attr = "xiaozhi_sdk.__version__"}
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
include = ["xiaozhi_sdk*"]
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.package-data]
|
|
43
|
+
xiaozhi_sdk = ["../file/**/*"]
|
|
44
|
+
|
|
45
|
+
[tool.uv]
|
|
46
|
+
dev-dependencies = [
|
|
47
|
+
"black>=24.8.0",
|
|
48
|
+
"flake8>=5.0.4",
|
|
49
|
+
"flake8-bugbear",
|
|
50
|
+
"flake8-comprehensions",
|
|
51
|
+
"isort>=5.13.2",
|
|
52
|
+
"mypy>=1.14.1",
|
|
53
|
+
"types-requests",
|
|
54
|
+
"pre-commit>=3.5.0",
|
|
55
|
+
"pytest>=8.3.5",
|
|
56
|
+
"pytest-asyncio",
|
|
57
|
+
"pytest-cov",
|
|
58
|
+
"build>=0.10",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
# 保留现有的工具配置
|
|
62
|
+
[tool.coverage.run]
|
|
63
|
+
omit = [
|
|
64
|
+
"xiaozhi_sdk/__main__.py",
|
|
65
|
+
"xiaozhi_sdk/cli.py",
|
|
66
|
+
"tests/*",
|
|
67
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import uuid
|
|
6
|
+
|
|
7
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
8
|
+
|
|
9
|
+
from xiaozhi_sdk.iot import OtaDevice
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def iot_main():
|
|
13
|
+
serial_number = ""
|
|
14
|
+
license_key = ""
|
|
15
|
+
mac_address = "00:22:44:66:88:14"
|
|
16
|
+
ota_url = "http://localhost:3080/api/ota"
|
|
17
|
+
ota_url = None
|
|
18
|
+
ota = OtaDevice(mac_addr=mac_address, client_id=str(uuid.uuid4()), serial_number=serial_number, ota_url=ota_url)
|
|
19
|
+
res = await ota.activate_device()
|
|
20
|
+
print(json.dumps(res["mqtt"]))
|
|
21
|
+
|
|
22
|
+
# if not res.get("activation"):
|
|
23
|
+
# return
|
|
24
|
+
# await ota.check_activate(res["activation"]["challenge"], license_key)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
asyncio.run(iot_main())
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import aiohttp
|
|
2
1
|
import asyncio
|
|
3
2
|
|
|
3
|
+
import aiohttp
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
async def explain_image():
|
|
6
|
-
url = "http://api.xiaozhi.me/
|
|
7
|
+
url = "http://api.xiaozhi.me/vision/explain"
|
|
7
8
|
question = "这个图片里有什么?"
|
|
8
|
-
image_path = "./file/leijun.jpg"
|
|
9
|
+
image_path = "./file/image/leijun.jpg"
|
|
9
10
|
|
|
10
11
|
boundary = "----ESP32_CAMERA_BOUNDARY"
|
|
11
12
|
headers = {
|
|
12
|
-
|
|
13
13
|
"Content-Type": f"multipart/form-data; boundary={boundary}",
|
|
14
14
|
# 不设置Transfer-Encoding,aiohttp自动处理
|
|
15
15
|
}
|
|
@@ -42,5 +42,6 @@ async def explain_image():
|
|
|
42
42
|
text = await resp.text()
|
|
43
43
|
print("Response:", text)
|
|
44
44
|
|
|
45
|
+
|
|
45
46
|
if __name__ == "__main__":
|
|
46
47
|
asyncio.run(explain_image())
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
8
|
+
|
|
9
|
+
from xiaozhi_sdk import XiaoZhiWebsocket
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
MAC_ADDR = "00:22:44:66:88:00"
|
|
13
|
+
ota_url = None
|
|
14
|
+
URL = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.mark.asyncio
|
|
18
|
+
async def test_main():
|
|
19
|
+
is_end = asyncio.Event()
|
|
20
|
+
async def message_handler_callback(message):
|
|
21
|
+
if message.get("state") == "stop":
|
|
22
|
+
is_end.set()
|
|
23
|
+
print("message received:", message)
|
|
24
|
+
|
|
25
|
+
xiaozhi = XiaoZhiWebsocket(message_handler_callback, url=URL, ota_url=ota_url)
|
|
26
|
+
await xiaozhi.init_connection(MAC_ADDR)
|
|
27
|
+
|
|
28
|
+
await xiaozhi.send_wake_word("你是")
|
|
29
|
+
|
|
30
|
+
await asyncio.wait_for(is_end.wait(), timeout=20.0)
|
|
31
|
+
await xiaozhi.close()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pytest
|
|
8
|
+
import sounddevice as sd
|
|
9
|
+
|
|
10
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
11
|
+
|
|
12
|
+
from xiaozhi_sdk import XiaoZhiWebsocket
|
|
13
|
+
from xiaozhi_sdk.utils import read_audio_file
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def assistant_audio_play(audio_queue, wait_time=5):
|
|
17
|
+
# 创建一个持续播放的流
|
|
18
|
+
stream = sd.OutputStream(samplerate=16000, channels=1, dtype=np.int16)
|
|
19
|
+
stream.start()
|
|
20
|
+
last_time = int(time.time())
|
|
21
|
+
while True:
|
|
22
|
+
if not audio_queue:
|
|
23
|
+
await asyncio.sleep(0.01)
|
|
24
|
+
if last_time and time.time() - last_time > wait_time:
|
|
25
|
+
break
|
|
26
|
+
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
pcm_data = audio_queue.popleft()
|
|
30
|
+
|
|
31
|
+
# 将字节数据转换为 numpy int16 数组
|
|
32
|
+
audio_array = pcm_data
|
|
33
|
+
|
|
34
|
+
stream.write(audio_array)
|
|
35
|
+
last_time = time.time()
|
|
36
|
+
|
|
37
|
+
stream.stop()
|
|
38
|
+
stream.close()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def mcp_tool_func():
|
|
42
|
+
def mcp_take_photo(data) -> tuple[bytes, bool]:
|
|
43
|
+
with open("./file/image/leijun.jpg", "rb") as f:
|
|
44
|
+
return f.read(), False
|
|
45
|
+
|
|
46
|
+
def mcp_get_device_status(data) -> tuple[dict, bool]:
|
|
47
|
+
data = {
|
|
48
|
+
"audio_speaker": {"volume": 80},
|
|
49
|
+
"screen": {"brightness": 75, "theme": "light"},
|
|
50
|
+
"network": {"type": "wifi", "ssid": "wifi名称", "signal": "strong"},
|
|
51
|
+
}
|
|
52
|
+
return data, False
|
|
53
|
+
|
|
54
|
+
def mcp_set_volume(data) -> tuple[dict, bool]:
|
|
55
|
+
return {}, False
|
|
56
|
+
|
|
57
|
+
from xiaozhi_sdk.utils.mcp_tool import take_photo, get_device_status, set_volume
|
|
58
|
+
|
|
59
|
+
take_photo["tool_func"] = mcp_take_photo
|
|
60
|
+
get_device_status["tool_func"] = mcp_get_device_status
|
|
61
|
+
set_volume["tool_func"] = mcp_set_volume
|
|
62
|
+
|
|
63
|
+
return [take_photo, get_device_status, set_volume]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def message_handler_callback(message):
|
|
67
|
+
print("message received:", message)
|
|
68
|
+
if message["type"] == "music":
|
|
69
|
+
print("music:", message["text"])
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
MAC_ADDR = "00:22:44:66:88:00"
|
|
73
|
+
|
|
74
|
+
ota_url = None
|
|
75
|
+
URL = None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# URL = None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.mark.asyncio
|
|
82
|
+
async def test_main():
|
|
83
|
+
xiaozhi = XiaoZhiWebsocket(message_handler_callback, url=URL, ota_url=ota_url)
|
|
84
|
+
|
|
85
|
+
await xiaozhi.set_mcp_tool(mcp_tool_func())
|
|
86
|
+
await xiaozhi.init_connection(MAC_ADDR)
|
|
87
|
+
|
|
88
|
+
# # say hellow
|
|
89
|
+
for pcm in read_audio_file("./file/audio/say_hello.wav"):
|
|
90
|
+
await xiaozhi.send_audio(pcm)
|
|
91
|
+
await xiaozhi.send_silence_audio()
|
|
92
|
+
await assistant_audio_play(xiaozhi.output_audio_queue)
|
|
93
|
+
|
|
94
|
+
# say take photo
|
|
95
|
+
for pcm in read_audio_file("./file/audio/take_photo.wav"):
|
|
96
|
+
await xiaozhi.send_audio(pcm)
|
|
97
|
+
await xiaozhi.send_silence_audio()
|
|
98
|
+
await assistant_audio_play(xiaozhi.output_audio_queue, 5)
|
|
99
|
+
|
|
100
|
+
# play music
|
|
101
|
+
# for pcm in read_audio_file("./file/audio/play_music.wav"):
|
|
102
|
+
# await xiaozhi.send_audio(pcm)
|
|
103
|
+
# await xiaozhi.send_silence_audio()
|
|
104
|
+
# await assistant_audio_play(xiaozhi.output_audio_queue, 500)
|
|
105
|
+
|
|
106
|
+
await xiaozhi.close()
|