mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
8.4 KiB
8.4 KiB
HTTP API 指南
本文档介绍如何通过 HTTP API 与 Uni-Lab-OS 进行交互,包括查询设备、提交任务和获取结果。
概述
Uni-Lab-OS 提供 RESTful HTTP API,允许外部系统通过标准 HTTP 请求控制实验室设备。API 基于 FastAPI 构建,默认运行在 http://localhost:8002。
基础信息
- Base URL:
http://localhost:8002/api/v1 - Content-Type:
application/json - 响应格式: JSON
通用响应结构
{
"code": 0,
"data": { ... },
"message": "success"
}
| 字段 | 类型 | 说明 |
|---|---|---|
code |
int | 状态码,0 表示成功 |
data |
object | 响应数据 |
message |
string | 响应消息 |
快速开始
以下是一个完整的工作流示例:查询设备 → 获取动作 → 提交任务 → 获取结果。
步骤 1: 获取在线设备
curl -X GET "http://localhost:8002/api/v1/online-devices"
响应示例:
{
"code": 0,
"data": {
"online_devices": {
"host_node": {
"device_key": "/host_node",
"namespace": "",
"machine_name": "本地",
"uuid": "xxx-xxx-xxx",
"node_name": "host_node"
}
},
"total_count": 1,
"timestamp": 1732612345.123
},
"message": "success"
}
步骤 2: 获取设备可用动作
curl -X GET "http://localhost:8002/api/v1/devices/host_node/actions"
响应示例:
{
"code": 0,
"data": {
"device_id": "host_node",
"actions": {
"test_latency": {
"type_name": "unilabos_msgs.action._empty_in.EmptyIn",
"type_name_convert": "unilabos_msgs/action/_empty_in/EmptyIn",
"action_path": "/devices/host_node/test_latency",
"goal_info": "{}",
"is_busy": false,
"current_job_id": null
},
"create_resource": {
"type_name": "unilabos_msgs.action._resource_create_from_outer_easy.ResourceCreateFromOuterEasy",
"action_path": "/devices/host_node/create_resource",
"goal_info": "{res_id: '', device_id: '', class_name: '', ...}",
"is_busy": false,
"current_job_id": null
}
},
"action_count": 5
},
"message": "success"
}
动作状态字段说明:
| 字段 | 说明 |
|---|---|
type_name |
动作类型的完整名称 |
action_path |
ROS2 动作路径 |
goal_info |
动作参数模板 |
is_busy |
动作是否正在执行 |
current_job_id |
当前执行的任务 ID(如果繁忙) |
步骤 3: 提交任务
curl -X POST "http://localhost:8002/api/v1/job/add" \
-H "Content-Type: application/json" \
-d '{"device_id":"host_node","action":"test_latency","action_args":{}}'
请求体:
{
"device_id": "host_node",
"action": "test_latency",
"action_args": {}
}
请求参数说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
device_id |
string | ✓ | 目标设备 ID |
action |
string | ✓ | 动作名称 |
action_args |
object | ✓ | 动作参数(根据动作类型不同而变化) |
响应示例:
{
"code": 0,
"data": {
"jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
"status": 1,
"result": {}
},
"message": "success"
}
任务状态码:
| 状态码 | 含义 | 说明 |
|---|---|---|
| 0 | UNKNOWN | 未知状态 |
| 1 | ACCEPTED | 任务已接受,等待执行 |
| 2 | EXECUTING | 任务执行中 |
| 3 | CANCELING | 任务取消中 |
| 4 | SUCCEEDED | 任务成功完成 |
| 5 | CANCELED | 任务已取消 |
| 6 | ABORTED | 任务中止(设备繁忙或执行失败) |
步骤 4: 查询任务状态和结果
curl -X GET "http://localhost:8002/api/v1/job/b6acb586-733a-42ab-9f73-55c9a52aa8bd/status"
响应示例(执行中):
{
"code": 0,
"data": {
"jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
"status": 2,
"result": {}
},
"message": "success"
}
响应示例(执行完成):
{
"code": 0,
"data": {
"jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
"status": 4,
"result": {
"error": "",
"suc": true,
"return_value": {
"avg_rtt_ms": 103.99,
"avg_time_diff_ms": 7181.55,
"max_time_error_ms": 7210.57,
"task_delay_ms": -1,
"raw_delay_ms": 33.19,
"test_count": 5,
"status": "success"
}
}
},
"message": "success"
}
注意: 任务结果在首次查询后会被自动删除,请确保保存返回的结果数据。
API 端点列表
设备相关
| 端点 | 方法 | 说明 |
|---|---|---|
/api/v1/online-devices |
GET | 获取在线设备列表 |
/api/v1/devices |
GET | 获取设备配置 |
/api/v1/devices/{device_id}/actions |
GET | 获取指定设备的可用动作 |
/api/v1/devices/{device_id}/actions/{action_name}/schema |
GET | 获取动作参数 Schema |
/api/v1/actions |
GET | 获取所有设备的可用动作 |
任务相关
| 端点 | 方法 | 说明 |
|---|---|---|
/api/v1/job/add |
POST | 提交新任务 |
/api/v1/job/{job_id}/status |
GET | 查询任务状态和结果 |
资源相关
| 端点 | 方法 | 说明 |
|---|---|---|
/api/v1/resources |
GET | 获取资源列表 |
常见动作示例
test_latency - 延迟测试
测试系统延迟,无需参数。
curl -X POST "http://localhost:8002/api/v1/job/add" \
-H "Content-Type: application/json" \
-d '{"device_id":"host_node","action":"test_latency","action_args":{}}'
create_resource - 创建资源
在设备上创建新资源。
curl -X POST "http://localhost:8002/api/v1/job/add" \
-H "Content-Type: application/json" \
-d '{
"device_id": "host_node",
"action": "create_resource",
"action_args": {
"res_id": "my_plate",
"device_id": "host_node",
"class_name": "Plate",
"parent": "deck",
"bind_locations": {"x": 0, "y": 0, "z": 0}
}
}'
错误处理
设备繁忙
当设备正在执行其他任务时,提交新任务会返回 status: 6(ABORTED):
{
"code": 0,
"data": {
"jobId": "xxx",
"status": 6,
"result": {}
},
"message": "success"
}
此时应等待当前任务完成后重试,或使用 /devices/{device_id}/actions 检查动作的 is_busy 状态。
参数错误
{
"code": 2002,
"data": { ... },
"message": "device_id is required"
}
轮询策略
推荐的任务状态轮询策略:
import requests
import time
def wait_for_job(job_id, timeout=60, interval=0.5):
"""等待任务完成并返回结果"""
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(f"http://localhost:8002/api/v1/job/{job_id}/status")
data = response.json()["data"]
status = data["status"]
if status in (4, 5, 6): # SUCCEEDED, CANCELED, ABORTED
return data
time.sleep(interval)
raise TimeoutError(f"Job {job_id} did not complete within {timeout} seconds")
# 使用示例
response = requests.post(
"http://localhost:8002/api/v1/job/add",
json={"device_id": "host_node", "action": "test_latency", "action_args": {}}
)
job_id = response.json()["data"]["jobId"]
result = wait_for_job(job_id)
print(result)