Update version to 0.1.21, enhance NavServer with user_id parameter for command functions, and improve error handling. Added new wheel and tar.gz distribution files.

This commit is contained in:
2025-09-28 15:00:20 +08:00
parent 924bce9554
commit 65792ccd89
4 changed files with 225 additions and 258 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "terminal_temi_mcp" name = "terminal_temi_mcp"
version = "0.1.17" version = "0.1.21"
description = "MQTT-based navigation server for robot" description = "MQTT-based navigation server for robot"
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [

View File

@@ -1,4 +1,4 @@
from typing import Optional, Sequence from typing import Optional, Sequence, List
import logging import logging
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel from pydantic import BaseModel
@@ -27,268 +27,179 @@ class NavServer:
def __init__(self, mmhandler=None): def __init__(self, mmhandler=None):
self.mmhandler = mmhandler or get_mcpmqtt_handler() self.mmhandler = mmhandler or get_mcpmqtt_handler()
async def publish_Cmd(self, device_id: str, cmd: str, params: dict): async def publish_Cmd(self, device_id: str, user_id: str, cmd: str, params: dict):
try: try:
payload = { payload = {
"device_id": device_id, "device_id": device_id,
"user_id": user_id,
"cmd": cmd, "cmd": cmd,
"data": params["data"] "data": params["data"]
} }
self.mmhandler.client.publish("robot/cmd", json.dumps(payload), qos=2) self.mmhandler.client.publish("robot/cmd", json.dumps(payload), qos=2)
return f"{cmd}工具执行成功" return f"{cmd} 任务已经下达完成"
except Exception as e: except Exception as e:
logger.error(f"Failed to publish {cmd} command: {str(e)}", exc_info=True) logger.error(f"Failed to publish command: {str(e)}", exc_info=True)
raise return f"Failed to publish command: {str(e)}"
async def nav_to(self, location: str): async def nav_to(self, user_id: str, location: str, flag: bool):
""" """轮足导航到指定位置"""
机器人导航去某个地方。 try:
Args: if not location:
- location (str): 目标地点名称 return "Location is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if location:
try:
if location == "充电桩":
location = "home base"
params = { params = {
"data": {"location": location} "data": {"location": location, "flag": flag}
} }
return await self.publish_Cmd("123456", "nav", params) return await self.publish_Cmd("123456", user_id, "nav", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call navigation mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call navigation mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call navigation mcp-tool: {str(e)}"
async def speak(self, speech: str): async def speak(self, user_id: str, speech: str):
""" """轮足机器人语音播报"""
机器人说某些话。 try:
Args: if not speech:
- speech (str): 说话内容 return "Speech content is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if speech:
try:
params = { params = {
"data": {"speech": speech} "data": {"speech": speech}
} }
return await self.publish_Cmd("123456", "speak", params) return await self.publish_Cmd("123456", user_id, "speak", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call speak mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call speak mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call speak mcp-tool: {str(e)}"
async def reception(self, location: str): async def reception(self, user_id: str, location: str):
""" """轮足机器人移动到指定位置迎宾"""
机器人接待客人。 try:
Args: if not location:
- location (str): 机器人接待客人到这个位置 return "Location is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if location :
try:
params = { params = {
"data": { "data": {
"location": location "location": location
} }
} }
return await self.publish_Cmd("123456", "reception", params) return await self.publish_Cmd("123456", user_id, "reception", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call reception mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call reception mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call reception mcp-tool: {str(e)}"
async def notification(self, location: str, text: str):
"""
机器人通知事情。
Args:
- location (str): 机器人去这个位置通知事情
- text (str): 通知的内容
Returns:
str: 命令执行结果消息
Raises: async def notification(self, user_id: str, location: str, text: str):
ValueError: 如果参数无效或为空 """轮足机器人移动到指定位置通知"""
Exception: 如果MQTT发布失败 try:
""" if not location or not text:
if location : return "Location or text is not specified."
try: else:
params = { params = {
"data": { "data": {
"location": location, "location": location,
"text": text "text": text
} }
} }
return await self.publish_Cmd("123456", "notification", params) return await self.publish_Cmd("123456", user_id, "notification", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call notification mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call notification mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call notification mcp-tool: {str(e)}"
async def repose(self):
""" async def repose(self, user_id: str):
机器人重新定位 """轮足机器人重新定位"""
"""
try: try:
params = { params = {
"data": { "data": {
"action": "repose" "action": "repose"
} }
} }
return await self.publish_Cmd("123456", "map", params) return await self.publish_Cmd("123456", user_id, "map", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call repose mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call repose mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call repose mcp-tool: {str(e)}"
async def delivery(self, first_location: str, next_location: str): async def delivery(self, user_id: str, first_location: str, next_location: str):
""" """轮足机器人配送"""
机器人运送物品。 try:
Args: if not first_location or not next_location:
- first_location (str): 机器人去这个位置取物品 return "first_location or next_location is not specified."
- next_location (str): 机器人将物品送到这个位置 else:
Returns:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if first_location and next_location:
try:
params = { params = {
"data": { "data": {
"first_location": first_location, "first_location": first_location,
"next_location": next_location "next_location": next_location
} }
} }
return await self.publish_Cmd("123456", "delivery", params) return await self.publish_Cmd("123456", user_id, "delivery", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call delivery mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call delivery mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call delivery mcp-tool: {str(e)}"
async def patrol(self, locations: list[str]): async def patrol(self, user_id: str, locations: list):
""" """轮足机器人巡逻"""
机器人去巡逻。 try:
Args: if not locations:
- locations (list[str]): 机器人巡逻经过的地点列表 return "locations is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if locations:
try:
params = { params = {
"data": {"locations": locations} "data": {"locations": locations}
} }
return await self.publish_Cmd("123456", "patrol", params) return await self.publish_Cmd("123456", user_id, "patrol", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call patrol mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call patrol mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call patrol mcp-tool: {str(e)}"
async def startFaceRecognize(self, device_id: str): async def startFaceRecognize(self, device_id: str, user_id: str):
""" """人脸识别"""
机器人进行人脸识别。 try:
Args: if not device_id:
- device_id (str): 设备id return "device_id is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if device_id:
try:
params = { params = {
"data": {} "data": {}
} }
return await self.publish_Cmd("123456", "face", params) return await self.publish_Cmd("123456", user_id, "face", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call face recognize mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call face recognize mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call face recognize mcp-tool: {str(e)}"
async def scanQRCode(self, device_id: str): async def scanQRCode(self, device_id: str, user_id: str):
""" """扫描二维码"""
机器人进行二维码扫描。 try:
Args: if not device_id:
- device_id (str): 设备id return "device_id is not specified."
Returns: else:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if device_id:
try:
params = { params = {
"data": {} "data": {}
} }
return await self.publish_Cmd("123456", "qrcode", params) return await self.publish_Cmd("123456", user_id, "qrcode", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call QR code scan mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call QR code scan mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call QR code scan mcp-tool: {str(e)}"
async def save_position(self, device_id: str, location_name: str): async def save_position(self, user_id: str, location_name: str):
""" """保存当前位置"""
机器人保存具体地点。 try:
Args: if not location_name:
- device_id (str): 设备id return "location is not specified."
- location_name (str): 地点名称 else:
Returns:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
if device_id and location_name:
try:
params = { params = {
"data": {"location_name": location_name} "data": {"location_name": location_name}
} }
return await self.publish_Cmd("123456", "saveLocation", params) return await self.publish_Cmd("123456", user_id, "saveLocation", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call save_position mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call save_position mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call save_position mcp-tool: {str(e)}"
async def guide(self, user_id: str, datas: List[TourStop]):
async def guide(self): """引导"""
"""
机器人导览。
Args:
Returns:
str: 命令执行结果消息
Raises:
ValueError: 如果参数无效或为空
Exception: 如果MQTT发布失败
"""
try: try:
datas = [ if not datas:
TourStop(name="前台", text="欢迎来到我们的场所,这是入口区域"), return "datas is not specified."
TourStop(name="灵泽万川展厅", text="这是我们的主大厅,提供接待服务"),
TourStop(name="爱易拍展厅", text="这里展示我们的主要产品和成果")
]
params = { params = {
"data": [data.model_dump() for data in datas] "data": [data.model_dump() for data in datas]
} }
return await self.publish_Cmd("123456", "guide", params) return await self.publish_Cmd("123456", user_id, "guide", params)
except Exception as e: except Exception as e:
logger.error(f"Failed to call guide mcp-tool: {str(e)} ", exc_info=True) logger.error(f"Failed to call guide mcp-tool: {str(e)} ", exc_info=True)
raise return f"Failed to call guide mcp-tool: {str(e)}"
async def serve() -> None: async def serve() -> None:
server = Server("terminal_temi_mcp") server = Server("terminal_temi_mcp")
@@ -301,7 +212,7 @@ async def serve() -> None:
return [ return [
Tool( Tool(
name="nav_to", name="nav_to",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人导航带路到指定地点:带我去、去XX、请引路、导航去、我想去、能带我去吗、带路、送我去、在哪里、前往XX、去XX位置、带我去、请带我到、我想前往、去那个地方、我要去、能不能去、带我导航、这个地方怎么走、我想找XX、导航带我去、请带路到、我要去那边、走一趟去、去下XX、到XX怎么走", description="轮足机器人导航到指定地点为用户引路。支持普通引导和通知两种模式。普通引导用于一般带路场景;通知模式下,机器人到达后会播放提示。适用于带路、引路、前往某个位置等场景。触发关键词:带我去、导航、引路、带路、怎么走、在哪里。",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
@@ -309,14 +220,22 @@ async def serve() -> None:
"type": "string", "type": "string",
"description": "目标地点名称", "description": "目标地点名称",
"minLength": 1 "minLength": 1
},
"flag": {
"type": "boolean",
"description": "是否为通知类型的导航。True为通知False为普通引导默认"
},
"user_id": {
"type": "string",
"description": "用户ID"
} }
}, },
"required": ["location"] "required": ["location", "user_id"]
} }
), ),
Tool( Tool(
name="speak", name="speak",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人进行语音播报:告诉、提醒、告知、提示", description="轮足机器人进行语音播报:告诉、提醒、告知、提示、通知",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
@@ -324,14 +243,18 @@ async def serve() -> None:
"type": "string", "type": "string",
"description": "要播报的语音内容", "description": "要播报的语音内容",
"minLength": 1 "minLength": 1
},
"user_id": {
"type": "string",
"description": "用户ID"
} }
}, },
"required": ["speech"] "required": ["speech", "user_id"]
} }
), ),
Tool( Tool(
name="reception", name="reception",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人去接待客人:去接人、请迎接客人、去接待、迎接一下、带人过来、把客人带过来、去门口接人、去接一下、请接人、接客人、帮我迎接、去把人接过来、接待来访者、请去接一下客人、送客人过来、从XX接到YY、引导访客、带访客过来、请引领客人、去门口把人接进来、从入口接人、去接待处接人、带客人进来", description="轮足机器人去接待客人:去接人、请迎接客人、去接待、迎接一下、带人过来、把客人带过来、去门口接人、去接一下、请接人、接客人、帮我迎接、去把人接过来、接待来访者、请去接一下客人、送客人过来、从XX接到YY、引导访客、带访客过来、请引领客人、去门口把人接进来、从入口接人、去接待处接人、带客人进来",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
@@ -340,42 +263,55 @@ async def serve() -> None:
"description": "引导接待客人到这个位置", "description": "引导接待客人到这个位置",
"minLength": 1 "minLength": 1
}, },
"user_id": {
"type": "string",
"description": "用户ID"
}
}, },
"required": ["location"] "required": ["location", "user_id"]
} }
), ),
# Tool(
# name="notification",
# description="轮足机器人去通知事情:通知、告诉、提醒、告知、提示",
# inputSchema={
# "type": "object",
# "properties": {
# "location": {
# "type": "string",
# "description": "去这个位置通知事情",
# "minLength": 1
# },
# "text": {
# "type": "string",
# "description": "通知事情的内容",
# "minLength": 1
# },
# "user_id": {
# "type": "string",
# "description": "用户ID"
# }
# },
# "required": ["location","text", "user_id"]
# }
# ),
Tool( Tool(
name="notification", name="repose",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人去通知事情:通知、告诉、提醒、告知、提示", description="轮足机器人、助手、机器人去重新定位",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
"location": { "user_id": {
"type": "string", "type": "string",
"description": "去这个位置通知事情", "description": "用户ID"
"minLength": 1
},
"text": {
"type": "string",
"description": "通知事情的内容",
"minLength": 1
} }
}, },
"required": ["location","text"] "required": ["user_id"]
}
),
Tool(
name="repose",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人去重新定位",
inputSchema={
"type": "object",
"properties": {},
"required": []
} }
), ),
Tool( Tool(
name="delivery", name="delivery",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人去运输物品:帮我送东西、去送一下、去送物品、帮我拿过去、送这个过去、去送快递、运送一下、帮我带东西、把东西送过去、物品配送、拿去给XX、去取个东西、取完送过去、帮我捎个东西、把这个拿去、请运过去、送过去给谁、请配送一下、帮我转交、帮我送到、从XX拿到YY、物品搬运", description="轮足机器人去运输物品:帮我送东西、去送一下、去送物品、帮我拿过去、送这个过去、去送快递、运送一下、帮我带东西、把东西送过去、物品配送、拿去给XX、去取个东西、取完送过去、帮我捎个东西、把这个拿去、请运过去、送过去给谁、请配送一下、帮我转交、帮我送到、从XX拿到YY、物品搬运",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
@@ -388,14 +324,18 @@ async def serve() -> None:
"type": "string", "type": "string",
"description": "将物品运输、送到这个位置", "description": "将物品运输、送到这个位置",
"minLength": 1 "minLength": 1
},
"user_id": {
"type": "string",
"description": "用户ID"
} }
}, },
"required": ["first_location","next_location"] "required": ["first_location","next_location", "user_id"]
} }
), ),
Tool( Tool(
name="patrol", name="patrol",
description="数字员工、终端、具身机器人、前台机器人、助手、机器人去巡逻:巡逻、巡查、去检查一下、去看看、去巡视", description="轮足机器人、助手、机器人去巡逻:巡逻、巡查、去检查一下、去看看、去巡视",
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
@@ -405,24 +345,32 @@ async def serve() -> None:
"items": { "items": {
"type": "string" "type": "string"
} }
},
"user_id": {
"type": "string",
"description": "用户ID"
} }
}, },
"required": ["locations"] "required": ["locations", "user_id"]
} }
), ),
# Tool( # Tool(
# name="guide", # name="guide",
# description="数字员工、终端、具身机器人、前台机器人、助手、机器人进行导览服务:导览、介绍、参观、带领参观、导游、讲解、展示、演示、介绍场所、带我看看", # description="轮足机器人进行导览服务:导览、介绍、参观、带领参观、导游、讲解、展示、演示、介绍场所、带我看看",
# inputSchema={ # inputSchema={
# "type": "object", # "type": "object",
# "properties": { # "properties": {
# "user_id": {
# "type": "string",
# "description": "用户ID"
# }
# }, # },
# "required": [] # "required": ["user_id"]
# } # }
# ) # )
# Tool( # Tool(
# name="face", # name="face",
# description="数字员工、终端、具身机器人、前台机器人、助手、机器人进行人脸识别:识别人脸、人脸识别、脸部识别、面部识别、认脸、看看是谁、识别一下、看看这个人、辨识人脸、扫脸、人脸检测、看脸识别、脸部检测、识别面孔、看人脸、人脸扫描、脸识别、面孔识别、认人、识别身份、看看这是谁、人脸认证、脸部扫描、面部扫描", # description="轮足机器人进行人脸识别:识别人脸、人脸识别、脸部识别、面部识别、认脸、看看是谁、识别一下、看看这个人、辨识人脸、扫脸、人脸检测、看脸识别、脸部检测、识别面孔、看人脸、人脸扫描、脸识别、面孔识别、认人、识别身份、看看这是谁、人脸认证、脸部扫描、面部扫描",
# inputSchema={ # inputSchema={
# "type": "object", # "type": "object",
# "properties": { # "properties": {
@@ -431,13 +379,17 @@ async def serve() -> None:
# "description": "设备ID", # "description": "设备ID",
# "minLength": 1 # "minLength": 1
# }, # },
# "user_id": {
# "type": "string",
# "description": "用户ID"
# }
# }, # },
# "required": ["device_id"] # "required": ["device_id", "user_id"]
# } # }
# ), # ),
# Tool( # Tool(
# name="qrcode", # name="qrcode",
# description="数字员工、终端、具身机器人、前台机器人、助手、机器人进行二维码扫描:扫码、扫二维码、扫QR码、二维码识别、码扫描、扫一下码、读取二维码、识别二维码、二维码扫描、QR扫描、扫描条码、扫描编码、读码、解析二维码、扫描识别、码识别、条码扫描、扫描二维码、读取码、扫描条形码、二维码读取、码解析", # description="轮足机器人进行二维码扫描:扫码、扫二维码、扫QR码、二维码识别、码扫描、扫一下码、读取二维码、识别二维码、二维码扫描、QR扫描、扫描条码、扫描编码、读码、解析二维码、扫描识别、码识别、条码扫描、扫描二维码、读取码、扫描条形码、二维码读取、码解析",
# inputSchema={ # inputSchema={
# "type": "object", # "type": "object",
# "properties": { # "properties": {
@@ -449,9 +401,13 @@ async def serve() -> None:
# "task_id": { # "task_id": {
# "type": "string", # "type": "string",
# "description": "任务ID" # "description": "任务ID"
# },
# "user_id": {
# "type": "string",
# "description": "用户ID"
# } # }
# }, # },
# "required": ["device_id"] # "required": ["device_id", "user_id"]
# } # }
# ) # )
] ]
@@ -462,56 +418,67 @@ async def serve() -> None:
try: try:
result = "" result = ""
if name == "nav_to": if name == "nav_to":
if "location" not in arguments: if "location" not in arguments or "user_id" not in arguments:
raise ValueError("缺少必要参数: location") raise ValueError("缺少必要参数: location or user_id")
result = await nav_server.nav_to( result = await nav_server.nav_to(
location=arguments["location"] user_id=arguments["user_id"],
location=arguments["location"],
flag=arguments.get("flag", False)
) )
elif name == "speak": elif name == "speak":
if "speech" not in arguments: if "speech" not in arguments or "user_id" not in arguments:
raise ValueError("缺少必要参数: speech") raise ValueError("缺少必要参数: speech or user_id")
result = await nav_server.speak( result = await nav_server.speak(
user_id=arguments["user_id"],
speech=arguments["speech"] speech=arguments["speech"]
) )
elif name == "reception": elif name == "reception":
if "location" not in arguments: if "location" not in arguments or "user_id" not in arguments:
raise ValueError("缺少必要参数: location") raise ValueError("缺少必要参数: location or user_id")
result = await nav_server.reception( result = await nav_server.reception(
location=arguments["location"], user_id=arguments["user_id"],
) location=arguments["location"]
elif name == "notification":
if "location" not in arguments or "text" not in arguments:
raise ValueError("缺少必要参数: location或text")
result = await nav_server.notification(
location=arguments["location"],
text=arguments["text"]
) )
# elif name == "notification":
# if "location" not in arguments or "text" not in arguments or "user_id" not in arguments:
# raise ValueError("缺少必要参数: location、text or user_id")
# result = await nav_server.notification(
# user_id=arguments["user_id"],
# location=arguments["location"],
# text=arguments["text"]
# )
elif name == "repose": elif name == "repose":
result = await nav_server.repose() if "user_id" not in arguments:
raise ValueError("缺少必要参数: user_id")
result = await nav_server.repose(user_id=arguments["user_id"])
elif name == "delivery": elif name == "delivery":
if "first_location" not in arguments or "next_location" not in arguments: if "first_location" not in arguments or "next_location" not in arguments or "user_id" not in arguments:
raise ValueError("缺少必要参数: first_locationnext_location") raise ValueError("缺少必要参数: first_locationnext_location or user_id")
result = await nav_server.delivery( result = await nav_server.delivery(
user_id=arguments["user_id"],
first_location=arguments["first_location"], first_location=arguments["first_location"],
next_location=arguments["next_location"] next_location=arguments["next_location"]
) )
elif name == "patrol": elif name == "patrol":
if "locations" not in arguments: if "locations" not in arguments or "user_id" not in arguments:
raise ValueError("缺少必要参数: locations") raise ValueError("缺少必要参数: locations or user_id")
result = await nav_server.patrol( result = await nav_server.patrol(
user_id=arguments["user_id"],
locations=arguments["locations"] locations=arguments["locations"]
) )
# elif name == "face": # elif name == "face":
# if "device_id" not in arguments: # if "device_id" not in arguments or "user_id" not in arguments:
# raise ValueError("缺少必要参数: device_id") # raise ValueError("缺少必要参数: device_id or user_id")
# result = await nav_server.startFaceRecognize( # result = await nav_server.startFaceRecognize(
# device_id=arguments["device_id"], # device_id=arguments["device_id"],
# user_id=arguments["user_id"]
# ) # )
# elif name == "qrcode": # elif name == "qrcode":
# if "device_id" not in arguments: # if "device_id" not in arguments or "user_id" not in arguments:
# raise ValueError("缺少必要参数: device_id") # raise ValueError("缺少必要参数: device_id or user_id")
# result = await nav_server.scanQRCode( # result = await nav_server.scanQRCode(
# device_id=arguments["device_id"], # device_id=arguments["device_id"],
# user_id=arguments["user_id"]
# ) # )
else: else:
raise ValueError(f"未知工具: {name}") raise ValueError(f"未知工具: {name}")