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)

相关文档