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:
欣南科技
2025-03-18 00:34:16 +08:00
committed by GitHub
co-authored by 玄凤科技 hrz
parent 773790c8ec
commit 5aa4199dfb
9 changed files with 370 additions and 108 deletions
@@ -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):
"""注册函数到函数注册字典的装饰器"""