mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-24 08:03:53 +08:00
add:支持IOT功能
* 自动注册iot消息为function call函数,并通过function call控制设备 * 增加配置项,控制iot自动注册function call功能的开启 * 增加function call action的 Error code * update:补充音量太大声、太小声的意图动作 * update:支持IOT功能 --------- Co-authored-by: 玄凤科技 <eric230308@gmail.com> Co-authored-by: hrz <1710360675@qq.com>
This commit is contained in:
@@ -112,7 +112,6 @@ def get_music_files(music_dir, music_ext):
|
||||
def initialize_music_handler(conn):
|
||||
global MUSIC_CACHE
|
||||
if MUSIC_CACHE == {}:
|
||||
logger.bind(tag=TAG).info(f"实例化音乐:")
|
||||
if "music" in conn.config:
|
||||
MUSIC_CACHE["music_config"] = conn.config["music"]
|
||||
MUSIC_CACHE["music_dir"] = os.path.abspath(
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
from config.logger import setup_logging
|
||||
from plugins_func.register import register_function, ToolType, ActionResponse, Action
|
||||
from core.handle.iotHandle import get_iot_status, send_iot_conn
|
||||
import asyncio
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
raise_and_lower_the_volume_function_desc = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "raise_and_lower_the_volume",
|
||||
"description": "用户觉得声音过高或过低,或者用户想提高或降低音量。比如用户说太大声了,参数为:lower,比如用户说提高音量,参数为:raise",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"description": "动作名称,要么是raise,要么是lower"
|
||||
}
|
||||
},
|
||||
"required": ["action"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@register_function('raise_and_lower_the_volume', raise_and_lower_the_volume_function_desc, ToolType.IOT_CTL)
|
||||
def raise_and_lower_the_volume(conn, action: str):
|
||||
"""
|
||||
获取当前设备音量
|
||||
"""
|
||||
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
_raise_and_lower_the_volume(conn, action),
|
||||
conn.loop
|
||||
)
|
||||
|
||||
try:
|
||||
new_volume = future.result() # 同步等待异步操作完成
|
||||
logger.bind(tag=TAG).info(f"音量操作完成: {new_volume}")
|
||||
response = f"音量已调整到{new_volume}"
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"音量操作失败: {e}")
|
||||
response = f"音量调整失败: {e}"
|
||||
|
||||
return ActionResponse(action=Action.RESPONSE, result="指令已接收", response=response)
|
||||
|
||||
|
||||
async def _raise_and_lower_the_volume(conn, action):
|
||||
volume = await get_iot_status(conn, "Speaker", "volume")
|
||||
if action == 'raise':
|
||||
volume += 10
|
||||
elif action == 'lower':
|
||||
volume -= 10
|
||||
# 限制音量范围在0到100之间
|
||||
if volume < 0:
|
||||
volume = 0
|
||||
elif volume > 100:
|
||||
volume = 100
|
||||
await send_iot_conn(conn, "Speaker", "SetVolume", {"volume": volume})
|
||||
return volume
|
||||
@@ -11,6 +11,7 @@ class ToolType(Enum):
|
||||
WAIT = (2, "调用工具,等待函数返回")
|
||||
CHANGE_SYS_PROMPT = (3, "修改系统提示词,切换角色性格或职责")
|
||||
SYSTEM_CTL = (4, "系统控制,影响正常的对话流程,如退出、播放音乐等,需要传递conn参数")
|
||||
IOT_CTL = (5, "IOT设备控制,需要传递conn参数")
|
||||
|
||||
def __init__(self, code, message):
|
||||
self.code = code
|
||||
@@ -18,6 +19,7 @@ class ToolType(Enum):
|
||||
|
||||
|
||||
class Action(Enum):
|
||||
ERROR = (-1, "错误")
|
||||
NOTFOUND = (0, "没有找到函数")
|
||||
NONE = (1, "啥也不干")
|
||||
RESPONSE = (2, "直接回复")
|
||||
@@ -40,8 +42,31 @@ class FunctionItem:
|
||||
self.func = func
|
||||
self.type = type
|
||||
|
||||
class DeviceTypeRegistry:
|
||||
"""设备类型注册表,用于管理IOT设备类型及其函数"""
|
||||
def __init__(self):
|
||||
self.type_functions = {} # type_signature -> {func_name: FunctionItem}
|
||||
|
||||
def generate_device_type_id(self, descriptor):
|
||||
"""通过设备能力描述生成类型ID"""
|
||||
properties = sorted(descriptor["properties"].keys())
|
||||
methods = sorted(descriptor["methods"].keys())
|
||||
# 使用属性和方法的组合作为设备类型的唯一标识
|
||||
type_signature = f"{descriptor['name']}:{','.join(properties)}:{','.join(methods)}"
|
||||
return type_signature
|
||||
|
||||
def get_device_functions(self, type_id):
|
||||
"""获取设备类型对应的所有函数"""
|
||||
return self.type_functions.get(type_id, {})
|
||||
|
||||
def register_device_type(self, type_id, functions):
|
||||
"""注册设备类型及其函数"""
|
||||
if type_id not in self.type_functions:
|
||||
self.type_functions[type_id] = functions
|
||||
|
||||
# 初始化函数注册字典
|
||||
all_function_registry = {}
|
||||
device_type_registry = DeviceTypeRegistry()
|
||||
|
||||
def register_function(name, desc, type=None):
|
||||
"""注册函数到函数注册字典的装饰器"""
|
||||
|
||||
Reference in New Issue
Block a user