mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-30 05:13:59 +08:00
update:合并非tts代码
This commit is contained in:
@@ -10,7 +10,6 @@ from plugins_func.register import (
|
||||
)
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
def wrap_async_function(async_func):
|
||||
@@ -21,7 +20,7 @@ def wrap_async_function(async_func):
|
||||
# 获取连接对象(第一个参数)
|
||||
conn = args[0]
|
||||
if not hasattr(conn, "loop"):
|
||||
logger.bind(tag=TAG).error("Connection对象没有loop属性")
|
||||
conn.logger.bind(tag=TAG).error("Connection对象没有loop属性")
|
||||
return ActionResponse(
|
||||
Action.ERROR,
|
||||
"Connection对象没有loop属性",
|
||||
@@ -35,7 +34,7 @@ def wrap_async_function(async_func):
|
||||
# 等待结果返回
|
||||
return future.result()
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"运行异步函数时出错: {e}")
|
||||
conn.logger.bind(tag=TAG).error(f"运行异步函数时出错: {e}")
|
||||
return ActionResponse(Action.ERROR, str(e), f"执行操作时出错: {e}")
|
||||
|
||||
return wrapper
|
||||
@@ -57,7 +56,7 @@ def create_iot_function(device_name, method_name, method_info):
|
||||
response_failure = "操作失败"
|
||||
|
||||
# 打印响应参数
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).debug(
|
||||
f"控制函数接收到的响应参数: success='{response_success}', failure='{response_failure}'"
|
||||
)
|
||||
|
||||
@@ -86,7 +85,9 @@ def create_iot_function(device_name, method_name, method_info):
|
||||
|
||||
return ActionResponse(Action.RESPONSE, result, response)
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"执行{device_name}的{method_name}操作失败: {e}")
|
||||
conn.logger.bind(tag=TAG).error(
|
||||
f"执行{device_name}的{method_name}操作失败: {e}"
|
||||
)
|
||||
|
||||
# 操作失败时使用大模型提供的失败响应
|
||||
response = response_failure
|
||||
@@ -104,7 +105,7 @@ def create_iot_query_function(device_name, prop_name, prop_info):
|
||||
async def iot_query_function(conn, response_success=None, response_failure=None):
|
||||
try:
|
||||
# 打印响应参数
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).info(
|
||||
f"查询函数接收到的响应参数: success='{response_success}', failure='{response_failure}'"
|
||||
)
|
||||
|
||||
@@ -122,7 +123,9 @@ def create_iot_query_function(device_name, prop_name, prop_info):
|
||||
|
||||
return ActionResponse(Action.ERROR, f"属性{prop_name}不存在", response)
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"查询{device_name}的{prop_name}时出错: {e}")
|
||||
conn.logger.bind(tag=TAG).error(
|
||||
f"查询{device_name}的{prop_name}时出错: {e}"
|
||||
)
|
||||
|
||||
# 查询出错时使用大模型提供的失败响应
|
||||
response = response_failure
|
||||
@@ -144,33 +147,34 @@ class IotDescriptor:
|
||||
self.methods = []
|
||||
|
||||
# 根据描述创建属性
|
||||
for key, value in properties.items():
|
||||
property_item = globals()[key] = {}
|
||||
property_item["name"] = key
|
||||
property_item["description"] = value["description"]
|
||||
if value["type"] == "number":
|
||||
property_item["value"] = 0
|
||||
elif value["type"] == "boolean":
|
||||
property_item["value"] = False
|
||||
else:
|
||||
property_item["value"] = ""
|
||||
self.properties.append(property_item)
|
||||
if properties is not None:
|
||||
for key, value in properties.items():
|
||||
property_item = {}
|
||||
property_item["name"] = key
|
||||
property_item["description"] = value["description"]
|
||||
if value["type"] == "number":
|
||||
property_item["value"] = 0
|
||||
elif value["type"] == "boolean":
|
||||
property_item["value"] = False
|
||||
else:
|
||||
property_item["value"] = ""
|
||||
self.properties.append(property_item)
|
||||
|
||||
# 根据描述创建方法
|
||||
for key, value in methods.items():
|
||||
method = globals()[key] = {}
|
||||
method["description"] = value["description"]
|
||||
method["name"] = key
|
||||
for k, v in value["parameters"].items():
|
||||
method[k] = {}
|
||||
method[k]["description"] = v["description"]
|
||||
if v["type"] == "number":
|
||||
method[k]["value"] = 0
|
||||
elif v["type"] == "boolean":
|
||||
method[k]["value"] = False
|
||||
else:
|
||||
method[k]["value"] = ""
|
||||
self.methods.append(method)
|
||||
if methods is not None:
|
||||
for key, value in methods.items():
|
||||
method = {}
|
||||
method["description"] = value["description"]
|
||||
method["name"] = key
|
||||
# 检查方法是否有参数
|
||||
if "parameters" in value:
|
||||
method["parameters"] = {}
|
||||
for k, v in value["parameters"].items():
|
||||
method["parameters"][k] = {
|
||||
"description": v["description"],
|
||||
"type": v["type"],
|
||||
}
|
||||
self.methods.append(method)
|
||||
|
||||
|
||||
def register_device_type(descriptor):
|
||||
@@ -219,13 +223,19 @@ def register_device_type(descriptor):
|
||||
func_name = f"{device_name.lower()}_{method_name.lower()}"
|
||||
|
||||
# 创建参数字典,添加原有参数
|
||||
parameters = {
|
||||
param_name: {
|
||||
"type": param_info["type"],
|
||||
"description": param_info["description"],
|
||||
parameters = {}
|
||||
required_params = []
|
||||
|
||||
# 如果方法有参数,则添加参数信息
|
||||
if "parameters" in method_info:
|
||||
parameters = {
|
||||
param_name: {
|
||||
"type": param_info["type"],
|
||||
"description": param_info["description"],
|
||||
}
|
||||
for param_name, param_info in method_info["parameters"].items()
|
||||
}
|
||||
for param_name, param_info in method_info["parameters"].items()
|
||||
}
|
||||
required_params = list(method_info["parameters"].keys())
|
||||
|
||||
# 添加响应参数
|
||||
parameters.update(
|
||||
@@ -242,7 +252,6 @@ def register_device_type(descriptor):
|
||||
)
|
||||
|
||||
# 构建必须参数列表(原有参数 + 响应参数)
|
||||
required_params = list(method_info["parameters"].keys())
|
||||
required_params.extend(["response_success", "response_failure"])
|
||||
|
||||
func_desc = {
|
||||
@@ -269,19 +278,36 @@ def register_device_type(descriptor):
|
||||
|
||||
# 用于接受前端设备推送的搜索iot描述
|
||||
async def handleIotDescriptors(conn, descriptors):
|
||||
if not conn.use_function_call_mode:
|
||||
return
|
||||
wait_max_time = 5
|
||||
while conn.func_handler is None or not conn.func_handler.finish_init:
|
||||
await asyncio.sleep(1)
|
||||
wait_max_time -= 1
|
||||
if wait_max_time <= 0:
|
||||
logger.bind(tag=TAG).error("连接对象没有func_handler")
|
||||
conn.logger.bind(tag=TAG).debug("连接对象没有func_handler")
|
||||
return
|
||||
"""处理物联网描述"""
|
||||
functions_changed = False
|
||||
|
||||
for descriptor in descriptors:
|
||||
|
||||
# 如果descriptor没有properties和methods,则直接跳过
|
||||
if "properties" not in descriptor and "methods" not in descriptor:
|
||||
continue
|
||||
|
||||
# 处理缺失properties的情况
|
||||
if "properties" not in descriptor:
|
||||
descriptor["properties"] = {}
|
||||
# 从methods中提取所有参数作为properties
|
||||
if "methods" in descriptor:
|
||||
for method_name, method_info in descriptor["methods"].items():
|
||||
if "parameters" in method_info:
|
||||
for param_name, param_info in method_info["parameters"].items():
|
||||
# 将参数信息转换为属性信息
|
||||
descriptor["properties"][param_name] = {
|
||||
"description": param_info["description"],
|
||||
"type": param_info["type"],
|
||||
}
|
||||
|
||||
# 创建IOT设备描述符
|
||||
iot_descriptor = IotDescriptor(
|
||||
descriptor["name"],
|
||||
@@ -291,7 +317,7 @@ async def handleIotDescriptors(conn, descriptors):
|
||||
)
|
||||
conn.iot_descriptors[descriptor["name"]] = iot_descriptor
|
||||
|
||||
if conn.use_function_call_mode:
|
||||
if conn.load_function_plugin:
|
||||
# 注册或获取设备类型
|
||||
type_id = register_device_type(descriptor)
|
||||
device_functions = device_type_registry.get_device_functions(type_id)
|
||||
@@ -300,7 +326,7 @@ async def handleIotDescriptors(conn, descriptors):
|
||||
if hasattr(conn, "func_handler"):
|
||||
for func_name in device_functions:
|
||||
conn.func_handler.function_registry.register_function(func_name)
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).info(
|
||||
f"注册IOT函数到function handler: {func_name}"
|
||||
)
|
||||
functions_changed = True
|
||||
@@ -309,8 +335,8 @@ async def handleIotDescriptors(conn, descriptors):
|
||||
if functions_changed and hasattr(conn, "func_handler"):
|
||||
conn.func_handler.upload_functions_desc()
|
||||
func_names = conn.func_handler.current_support_functions()
|
||||
logger.bind(tag=TAG).info(f"设备类型: {type_id}")
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).info(f"设备类型: {type_id}")
|
||||
conn.logger.bind(tag=TAG).info(
|
||||
f"更新function描述列表完成,当前支持的函数: {func_names}"
|
||||
)
|
||||
|
||||
@@ -324,13 +350,13 @@ async def handleIotStatus(conn, states):
|
||||
for k, v in state["state"].items():
|
||||
if property_item["name"] == k:
|
||||
if type(v) != type(property_item["value"]):
|
||||
logger.bind(tag=TAG).error(
|
||||
conn.logger.bind(tag=TAG).error(
|
||||
f"属性{property_item['name']}的值类型不匹配"
|
||||
)
|
||||
break
|
||||
else:
|
||||
property_item["value"] = v
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).info(
|
||||
f"物联网状态更新: {key} , {property_item['name']} = {v}"
|
||||
)
|
||||
break
|
||||
@@ -344,7 +370,7 @@ async def get_iot_status(conn, name, property_name):
|
||||
for property_item in value.properties:
|
||||
if property_item["name"] == property_name:
|
||||
return property_item["value"]
|
||||
logger.bind(tag=TAG).warning(f"未找到设备 {name} 的属性 {property_name}")
|
||||
conn.logger.bind(tag=TAG).warning(f"未找到设备 {name} 的属性 {property_name}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -355,16 +381,16 @@ async def set_iot_status(conn, name, property_name, value):
|
||||
for property_item in iot_descriptor.properties:
|
||||
if property_item["name"] == property_name:
|
||||
if type(value) != type(property_item["value"]):
|
||||
logger.bind(tag=TAG).error(
|
||||
conn.logger.bind(tag=TAG).error(
|
||||
f"属性{property_item['name']}的值类型不匹配"
|
||||
)
|
||||
return
|
||||
property_item["value"] = value
|
||||
logger.bind(tag=TAG).info(
|
||||
conn.logger.bind(tag=TAG).info(
|
||||
f"物联网状态更新: {name} , {property_name} = {value}"
|
||||
)
|
||||
return
|
||||
logger.bind(tag=TAG).warning(f"未找到设备 {name} 的属性 {property_name}")
|
||||
conn.logger.bind(tag=TAG).warning(f"未找到设备 {name} 的属性 {property_name}")
|
||||
|
||||
|
||||
async def send_iot_conn(conn, name, method_name, parameters):
|
||||
@@ -375,19 +401,17 @@ async def send_iot_conn(conn, name, method_name, parameters):
|
||||
for method in value.methods:
|
||||
# 找到了方法
|
||||
if method["name"] == method_name:
|
||||
await conn.websocket.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "iot",
|
||||
"commands": [
|
||||
{
|
||||
"name": name,
|
||||
"method": method_name,
|
||||
"parameters": parameters,
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
)
|
||||
# 构建命令对象
|
||||
command = {
|
||||
"name": name,
|
||||
"method": method_name,
|
||||
}
|
||||
|
||||
# 只有当参数不为空时才添加parameters字段
|
||||
if parameters:
|
||||
command["parameters"] = parameters
|
||||
send_message = json.dumps({"type": "iot", "commands": [command]})
|
||||
await conn.websocket.send(send_message)
|
||||
conn.logger.bind(tag=TAG).info(f"发送物联网指令: {send_message}")
|
||||
return
|
||||
logger.bind(tag=TAG).error(f"未找到方法{method_name}")
|
||||
conn.logger.bind(tag=TAG).error(f"未找到方法{method_name}")
|
||||
|
||||
Reference in New Issue
Block a user