Compare commits

..

8 Commits

Author SHA1 Message Date
Junhan Chang
d776550a4b add virtual_sample_demo 样品追踪测试设备 2026-03-23 16:43:20 +08:00
Xuwznln
3d8123849a add external devices param
fix registry upload missing type
2026-03-23 15:01:16 +08:00
Xuwznln
d2f204c5b0 bump to 0.10.19 2026-03-22 04:17:21 +08:00
Xuwznln
d8922884b1 fast registry load 2026-03-22 04:14:47 +08:00
Xuwznln
427afe83d4 minor fix on skill & registry 2026-03-22 03:36:28 +08:00
Xuwznln
23c2e3b2f7 stripe ros2 schema desc
add create-device-skill
2026-03-22 03:21:13 +08:00
Xuwznln
59c26265e9 new registry system backwards to yaml 2026-03-22 02:19:54 +08:00
Xuwznln
4c2adea55a remove not exist resource 2026-03-21 23:35:51 +08:00
79 changed files with 7136 additions and 6576 deletions

View File

@@ -3,7 +3,7 @@
package: package:
name: unilabos name: unilabos
version: 0.10.18 version: 0.10.19
source: source:
path: ../../unilabos path: ../../unilabos
@@ -54,7 +54,7 @@ requirements:
- pymodbus - pymodbus
- matplotlib - matplotlib
- pylibftdi - pylibftdi
- uni-lab::unilabos-env ==0.10.18 - uni-lab::unilabos-env ==0.10.19
about: about:
repository: https://github.com/deepmodeling/Uni-Lab-OS repository: https://github.com/deepmodeling/Uni-Lab-OS

View File

@@ -2,7 +2,7 @@
package: package:
name: unilabos-env name: unilabos-env
version: 0.10.18 version: 0.10.19
build: build:
noarch: generic noarch: generic

View File

@@ -3,7 +3,7 @@
package: package:
name: unilabos-full name: unilabos-full
version: 0.10.18 version: 0.10.19
build: build:
noarch: generic noarch: generic
@@ -11,7 +11,7 @@ build:
requirements: requirements:
run: run:
# Base unilabos package (includes unilabos-env) # Base unilabos package (includes unilabos-env)
- uni-lab::unilabos ==0.10.18 - uni-lab::unilabos ==0.10.19
# Documentation tools # Documentation tools
- sphinx - sphinx
- sphinx_rtd_theme - sphinx_rtd_theme

View File

@@ -0,0 +1,160 @@
---
name: add-device
description: Guide for adding new devices to Uni-Lab-OS (接入新设备). Uses @device decorator + AST auto-scanning instead of manual YAML. Walks through device category, communication protocol, driver creation with decorators, and graph file setup. Use when the user wants to add/integrate a new device, create a device driver, write a device class, or mentions 接入设备/添加设备/设备驱动/物模型.
---
# 添加新设备到 Uni-Lab-OS
**第一步:** 使用 Read 工具读取 `docs/ai_guides/add_device.md`,获取完整的设备接入指南。
该指南包含设备类别(物模型)列表、通信协议模板、常见错误检查清单等。搜索 `unilabos/devices/` 获取已有设备的实现参考。
---
## 装饰器参考
### @device — 设备类装饰器
```python
from unilabos.registry.decorators import device
# 单设备
@device(
id="my_device.vendor", # 注册表唯一标识(必填)
category=["temperature"], # 分类标签列表(必填)
description="设备描述", # 设备描述
display_name="显示名称", # UI 显示名称(默认用 id
icon="DeviceIcon.webp", # 图标文件名
version="1.0.0", # 版本号
device_type="python", # "python" 或 "ros2"
handles=[...], # 端口列表InputHandle / OutputHandle
model={...}, # 3D 模型配置
hardware_interface=HardwareInterface(...), # 硬件通信接口
)
# 多设备(同一个类注册多个设备 ID各自有不同的 handles 等配置)
@device(
ids=["pump.vendor.model_A", "pump.vendor.model_B"],
id_meta={
"pump.vendor.model_A": {"handles": [...], "description": "型号 A"},
"pump.vendor.model_B": {"handles": [...], "description": "型号 B"},
},
category=["pump_and_valve"],
)
```
### @action — 动作方法装饰器
```python
from unilabos.registry.decorators import action
@action # 无参:注册为 UniLabJsonCommand 动作
@action() # 同上
@action(description="执行操作") # 带描述
@action(
action_type=HeatChill, # 指定 ROS Action 消息类型
goal={"temperature": "temp"}, # Goal 字段映射
feedback={}, # Feedback 字段映射
result={}, # Result 字段映射
handles=[...], # 动作级别端口
goal_default={"temp": 25.0}, # Goal 默认值
placeholder_keys={...}, # 参数占位符
always_free=True, # 不受排队限制
auto_prefix=True, # 强制使用 auto- 前缀
parent=True, # 从父类 MRO 获取参数签名
)
```
**自动识别规则:**
-`@action` 的公开方法 → 注册为动作(方法名即动作名)
- **不带 `@action` 的公开方法** → 自动注册为 `auto-{方法名}` 动作
- `_` 开头的方法 → 不扫描
- `@not_action` 标记的方法 → 排除
### @topic_config — 状态属性配置
```python
from unilabos.registry.decorators import topic_config
@property
@topic_config(
period=5.0, # 发布周期(秒),默认 5.0
print_publish=False, # 是否打印发布日志
qos=10, # QoS 深度,默认 10
name="custom_name", # 自定义发布名称(默认用属性名)
)
def temperature(self) -> float:
return self.data.get("temperature", 0.0)
```
### 辅助装饰器
```python
from unilabos.registry.decorators import not_action, always_free
@not_action # 标记为非动作post_init、辅助方法等
@always_free # 标记为不受排队限制(查询类操作)
```
---
## 设备模板
```python
import logging
from typing import Any, Dict, Optional
from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode
from unilabos.registry.decorators import device, action, topic_config, not_action
@device(id="my_device", category=["my_category"], description="设备描述")
class MyDevice:
_ros_node: BaseROS2DeviceNode
def __init__(self, device_id: Optional[str] = None, config: Optional[Dict[str, Any]] = None, **kwargs):
self.device_id = device_id or "my_device"
self.config = config or {}
self.logger = logging.getLogger(f"MyDevice.{self.device_id}")
self.data: Dict[str, Any] = {"status": "Idle"}
@not_action
def post_init(self, ros_node: BaseROS2DeviceNode) -> None:
self._ros_node = ros_node
@action
async def initialize(self) -> bool:
self.data["status"] = "Ready"
return True
@action
async def cleanup(self) -> bool:
self.data["status"] = "Offline"
return True
@action(description="执行操作")
def my_action(self, param: float = 0.0, name: str = "") -> Dict[str, Any]:
"""带 @action 装饰器 → 注册为 'my_action' 动作"""
return {"success": True}
def get_info(self) -> Dict[str, Any]:
"""无 @action → 自动注册为 'auto-get_info' 动作"""
return {"device_id": self.device_id}
@property
@topic_config()
def status(self) -> str:
return self.data.get("status", "Idle")
@property
@topic_config(period=2.0)
def temperature(self) -> float:
return self.data.get("temperature", 0.0)
```
### 要点
- `_ros_node: BaseROS2DeviceNode` 类型标注放在类体顶部
- `__init__` 签名固定为 `(self, device_id=None, config=None, **kwargs)`
- `post_init``@not_action` 标记,参数类型标注为 `BaseROS2DeviceNode`
- 运行时状态存储在 `self.data` 字典中
- 设备文件放在 `unilabos/devices/<category>/` 目录下

View File

@@ -0,0 +1,351 @@
---
name: add-resource
description: Guide for adding new resources (materials, bottles, carriers, decks, warehouses) to Uni-Lab-OS (添加新物料/资源). Uses @resource decorator for AST auto-scanning. Covers Bottle, Carrier, Deck, WareHouse definitions. Use when the user wants to add resources, define materials, create a deck layout, add bottles/carriers/plates, or mentions 物料/资源/resource/bottle/carrier/deck/plate/warehouse.
---
# 添加新物料资源
Uni-Lab-OS 的资源体系基于 PyLabRobot通过扩展实现 Bottle、Carrier、WareHouse、Deck 等实验室物料管理。使用 `@resource` 装饰器注册AST 自动扫描生成注册表条目。
---
## 资源类型
| 类型 | 基类 | 用途 | 示例 |
|------|------|------|------|
| **Bottle** | `Well` (PyLabRobot) | 单个容器(瓶、小瓶、烧杯、反应器) | 试剂瓶、粉末瓶 |
| **BottleCarrier** | `ItemizedCarrier` | 多槽位载架(放多个 Bottle | 6 位试剂架、枪头盒 |
| **WareHouse** | `ItemizedCarrier` | 堆栈/仓库(放多个 Carrier | 4x4 堆栈 |
| **Deck** | `Deck` (PyLabRobot) | 工作站台面(放多个 WareHouse | 反应站 Deck |
**层级关系:** `Deck``WareHouse``BottleCarrier``Bottle`
WareHouse 本质上和 Site 是同一概念 — 都是定义一组固定的放置位slot只不过 WareHouse 多嵌套了一层 Deck。两者都需要开发者根据实际物理尺寸自行计算各 slot 的偏移坐标。
---
## @resource 装饰器
```python
from unilabos.registry.decorators import resource
@resource(
id="my_resource_id", # 注册表唯一标识(必填)
category=["bottles"], # 分类标签列表(必填)
description="资源描述",
icon="", # 图标
version="1.0.0",
handles=[...], # 端口列表InputHandle / OutputHandle
model={...}, # 3D 模型配置
class_type="pylabrobot", # "python" / "pylabrobot" / "unilabos"
)
```
---
## 创建规范
### 命名规则
1. **`name` 参数作为前缀**:所有工厂函数必须接受 `name: str` 参数,创建子物料时以 `name` 作为前缀,确保实例名在运行时全局唯一
2. **Bottle 命名约定**:试剂瓶-Bottle烧杯-Beaker烧瓶-Flask小瓶-Vial
3. **函数名 = `@resource(id=...)`**:工厂函数名与注册表 id 保持一致
### 子物料命名示例
```python
# Carrier 内部的 sites 用 name 前缀
for k, v in sites.items():
v.name = f"{name}_{v.name}" # "堆栈1左_A01", "堆栈1左_B02" ...
# Carrier 中放置 Bottle 时用 name 前缀
carrier[0] = My_Reagent_Bottle(f"{name}_flask_1") # "堆栈1左_flask_1"
carrier[i] = My_Solid_Vial(f"{name}_vial_{ordering[i]}") # "堆栈1左_vial_A1"
# create_homogeneous_resources 使用 name_prefix
sites=create_homogeneous_resources(
klass=ResourceHolder,
locations=[...],
name_prefix=name, # 自动生成 "{name}_0", "{name}_1" ...
)
# Deck setup 中用仓库名称作为 name 传入
self.warehouses = {
"堆栈1左": my_warehouse_4x4("堆栈1左"), # WareHouse.name = "堆栈1左"
"试剂堆栈": my_reagent_stack("试剂堆栈"), # WareHouse.name = "试剂堆栈"
}
```
### 其他规范
- **max_volume 单位为 μL**500mL = 500000
- **尺寸单位为 mm**`diameter`, `height`, `size_x/y/z`, `dx/dy/dz`
- **BottleCarrier 必须设置 `num_items_x/y/z`**:用于前端渲染布局
- **Deck 的 `__init__` 必须接受 `setup=False`**:图文件中 `config.setup=true` 触发 `setup()`
- **按项目分组文件**:同一工作站的资源放在 `unilabos/resources/<project>/`
- **`__init__` 必须接受 `serialize()` 输出的所有字段**`serialize()` 输出会作为 `config` 回传到 `__init__`,因此必须通过显式参数或 `**kwargs` 接受,否则反序列化会报错
- **持久化运行时状态用 `serialize_state()`**:通过 `_unilabos_state` 字典存储可变信息(如物料内容、液体量),只存 JSON 可序列化的基本类型
---
## 资源模板
### Bottle
```python
from unilabos.registry.decorators import resource
from unilabos.resources.itemized_carrier import Bottle
@resource(id="My_Reagent_Bottle", category=["bottles"], description="我的试剂瓶")
def My_Reagent_Bottle(
name: str,
diameter: float = 70.0,
height: float = 120.0,
max_volume: float = 500000.0,
barcode: str = None,
) -> Bottle:
return Bottle(
name=name,
diameter=diameter,
height=height,
max_volume=max_volume,
barcode=barcode,
model="My_Reagent_Bottle",
)
```
**Bottle 参数:**
- `name`: 实例名称(运行时唯一,由上层 Carrier 以前缀方式传入)
- `diameter`: 瓶体直径 (mm)
- `height`: 瓶体高度 (mm)
- `max_volume`: 最大容积(**μL**500mL = 500000
- `barcode`: 条形码(可选)
### BottleCarrier
```python
from pylabrobot.resources import ResourceHolder
from pylabrobot.resources.carrier import create_ordered_items_2d
from unilabos.resources.itemized_carrier import BottleCarrier
from unilabos.registry.decorators import resource
@resource(id="My_6SlotCarrier", category=["bottle_carriers"], description="六槽位载架")
def My_6SlotCarrier(name: str) -> BottleCarrier:
sites = create_ordered_items_2d(
klass=ResourceHolder,
num_items_x=3, num_items_y=2,
dx=10.0, dy=10.0, dz=5.0,
item_dx=42.0, item_dy=35.0,
size_x=20.0, size_y=20.0, size_z=50.0,
)
# 子 site 用 name 作为前缀
for k, v in sites.items():
v.name = f"{name}_{v.name}"
carrier = BottleCarrier(
name=name, size_x=146.0, size_y=80.0, size_z=55.0,
sites=sites, model="My_6SlotCarrier",
)
carrier.num_items_x = 3
carrier.num_items_y = 2
carrier.num_items_z = 1
# 放置 Bottle 时用 name 作为前缀
ordering = ["A1", "B1", "A2", "B2", "A3", "B3"]
for i in range(6):
carrier[i] = My_Reagent_Bottle(f"{name}_vial_{ordering[i]}")
return carrier
```
### WareHouse / Deck 放置位
WareHouse 和 Site 本质上是同一概念都是定义一组固定放置位slot根据物理尺寸自行批量计算偏移坐标。WareHouse 只是多嵌套了一层 Deck 而已。推荐开发者直接根据实物测量数据计算各 slot 偏移量。
#### WareHouse使用 warehouse_factory
```python
from unilabos.resources.warehouse import warehouse_factory
from unilabos.registry.decorators import resource
@resource(id="my_warehouse_4x4", category=["warehouse"], description="4x4 堆栈仓库")
def my_warehouse_4x4(name: str) -> "WareHouse":
return warehouse_factory(
name=name,
num_items_x=4, num_items_y=4, num_items_z=1,
dx=10.0, dy=10.0, dz=10.0, # 第一个 slot 的起始偏移
item_dx=147.0, item_dy=106.0, item_dz=130.0, # slot 间距
resource_size_x=127.0, resource_size_y=85.0, resource_size_z=100.0, # slot 尺寸
model="my_warehouse_4x4",
col_offset=0, # 列标签起始偏移0 → A01, 4 → A05
layout="row-major", # "row-major" 行优先 / "col-major" 列优先 / "vertical-col-major" 竖向
)
```
`warehouse_factory` 参数说明:
- `dx/dy/dz`:第一个 slot 相对 WareHouse 原点的偏移mm
- `item_dx/item_dy/item_dz`:相邻 slot 间距mm需根据实际物理间距测量
- `resource_size_x/y/z`:每个 slot 的可放置区域尺寸
- `layout`:影响 slot 标签和坐标映射
- `"row-major"`A01,A02,...,B01,B02,...(行优先,适合横向排列)
- `"col-major"`A01,B01,...,A02,B02,...(列优先)
- `"vertical-col-major"`竖向排列y 坐标反向
#### Deck 组装 WareHouse
Deck 通过 `setup()` 将多个 WareHouse 放置到指定坐标:
```python
from pylabrobot.resources import Deck, Coordinate
from unilabos.registry.decorators import resource
@resource(id="MyStation_Deck", category=["deck"], description="我的工作站 Deck")
class MyStation_Deck(Deck):
def __init__(self, name="MyStation_Deck", size_x=2700.0, size_y=1080.0, size_z=1500.0,
category="deck", setup=False, **kwargs) -> None:
super().__init__(name=name, size_x=size_x, size_y=size_y, size_z=size_z)
if setup:
self.setup()
def setup(self) -> None:
self.warehouses = {
"堆栈1左": my_warehouse_4x4("堆栈1左"),
"堆栈1右": my_warehouse_4x4("堆栈1右"),
}
self.warehouse_locations = {
"堆栈1左": Coordinate(-200.0, 400.0, 0.0), # 自行测量计算
"堆栈1右": Coordinate(2350.0, 400.0, 0.0),
}
for wh_name, wh in self.warehouses.items():
self.assign_child_resource(wh, location=self.warehouse_locations[wh_name])
```
#### Site 模式(前端定向放置)
适用于有固定孔位/槽位的设备(如移液站 PRCXI 9300Deck 通过 `sites` 列表定义前端展示的放置位,前端据此渲染可拖拽的孔位布局:
```python
import collections
from typing import Any, Dict, List, Optional
from pylabrobot.resources import Deck, Resource, Coordinate
from unilabos.registry.decorators import resource
@resource(id="MyLabDeck", category=["deck"], description="带 Site 定向放置的 Deck")
class MyLabDeck(Deck):
# 根据设备台面实测批量计算各 slot 坐标偏移
_DEFAULT_SITE_POSITIONS = [
(0, 0, 0), (138, 0, 0), (276, 0, 0), (414, 0, 0), # T1-T4
(0, 96, 0), (138, 96, 0), (276, 96, 0), (414, 96, 0), # T5-T8
]
_DEFAULT_SITE_SIZE = {"width": 128.0, "height": 86.0, "depth": 0}
_DEFAULT_CONTENT_TYPE = ["plate", "tip_rack", "tube_rack", "adaptor"]
def __init__(self, name: str, size_x: float, size_y: float, size_z: float,
sites: Optional[List[Dict[str, Any]]] = None, **kwargs):
super().__init__(size_x, size_y, size_z, name)
if sites is not None:
self.sites = [dict(s) for s in sites]
else:
self.sites = []
for i, (x, y, z) in enumerate(self._DEFAULT_SITE_POSITIONS):
self.sites.append({
"label": f"T{i + 1}", # 前端显示的槽位标签
"visible": True, # 是否在前端可见
"position": {"x": x, "y": y, "z": z}, # 槽位物理坐标
"size": dict(self._DEFAULT_SITE_SIZE), # 槽位尺寸
"content_type": list(self._DEFAULT_CONTENT_TYPE), # 允许放入的物料类型
})
self._ordering = collections.OrderedDict(
(site["label"], None) for site in self.sites
)
def assign_child_resource(self, resource: Resource,
location: Optional[Coordinate] = None,
reassign: bool = True,
spot: Optional[int] = None):
idx = spot
if spot is None:
for i, site in enumerate(self.sites):
if site.get("label") == resource.name:
idx = i
break
if idx is None:
for i in range(len(self.sites)):
if self._get_site_resource(i) is None:
idx = i
break
if idx is None:
raise ValueError(f"No available site for '{resource.name}'")
loc = Coordinate(**self.sites[idx]["position"])
super().assign_child_resource(resource, location=loc, reassign=reassign)
def serialize(self) -> dict:
data = super().serialize()
sites_out = []
for i, site in enumerate(self.sites):
occupied = self._get_site_resource(i)
sites_out.append({
"label": site["label"],
"visible": site.get("visible", True),
"occupied_by": occupied.name if occupied else None,
"position": site["position"],
"size": site["size"],
"content_type": site["content_type"],
})
data["sites"] = sites_out
return data
```
**Site 字段说明:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `label` | str | 槽位标签(如 `"T1"`),前端显示名称,也用于匹配 resource.name |
| `visible` | bool | 是否在前端可见 |
| `position` | dict | 物理坐标 `{x, y, z}`mm需自行测量计算偏移 |
| `size` | dict | 槽位尺寸 `{width, height, depth}`mm |
| `content_type` | list | 允许放入的物料类型,如 `["plate", "tip_rack", "tube_rack", "adaptor"]` |
**参考实现:** `unilabos/devices/liquid_handling/prcxi/prcxi.py` 中的 `PRCXI9300Deck`4x4 共 16 个 site
---
## 文件位置
```
unilabos/resources/
├── <project>/ # 按项目分组
│ ├── bottles.py # Bottle 工厂函数
│ ├── bottle_carriers.py # Carrier 工厂函数
│ ├── warehouses.py # WareHouse 工厂函数
│ └── decks.py # Deck 类定义
```
---
## 验证
```bash
# 资源可导入
python -c "from unilabos.resources.my_project.bottles import My_Reagent_Bottle; print(My_Reagent_Bottle('test'))"
# 启动测试AST 自动扫描)
unilab -g <graph>.json
```
仅在以下情况仍需 YAML第三方库资源如 pylabrobot 内置资源,无 `@resource` 装饰器)。
---
## 关键路径
| 内容 | 路径 |
|------|------|
| Bottle/Carrier 基类 | `unilabos/resources/itemized_carrier.py` |
| WareHouse 基类 + 工厂 | `unilabos/resources/warehouse.py` |
| PLR 注册 | `unilabos/resources/plr_additional_res_reg.py` |
| 装饰器定义 | `unilabos/registry/decorators.py` |

View File

@@ -0,0 +1,292 @@
# 资源高级参考
本文件是 SKILL.md 的补充,包含类继承体系、序列化/反序列化、Bioyond 物料同步、非瓶类资源和仓库工厂模式。Agent 在需要实现这些功能时按需阅读。
---
## 1. 类继承体系
```
PyLabRobot
├── Resource (PLR 基类)
│ ├── Well
│ │ └── Bottle (unilabos) → 瓶/小瓶/烧杯/反应器
│ ├── Deck
│ │ └── 自定义 Deck 类 (unilabos) → 工作站台面
│ ├── ResourceHolder → 槽位占位符
│ └── Container
│ └── Battery (unilabos) → 组装好的电池
├── ItemizedCarrier (unilabos, 继承 Resource)
│ ├── BottleCarrier (unilabos) → 瓶载架
│ └── WareHouse (unilabos) → 堆栈仓库
├── ItemizedResource (PLR)
│ └── MagazineHolder (unilabos) → 子弹夹载架
└── ResourceStack (PLR)
└── Magazine (unilabos) → 子弹夹洞位
```
### Bottle 类细节
```python
class Bottle(Well):
def __init__(self, name, diameter, height, max_volume,
size_x=0.0, size_y=0.0, size_z=0.0,
barcode=None, category="container", model=None, **kwargs):
super().__init__(
name=name,
size_x=diameter, # PLR 用 diameter 作为 size_x/size_y
size_y=diameter,
size_z=height, # PLR 用 height 作为 size_z
max_volume=max_volume,
category=category,
model=model,
bottom_type="flat",
cross_section_type="circle"
)
```
注意 `size_x = size_y = diameter``size_z = height`
### ItemizedCarrier 核心方法
| 方法 | 说明 |
|------|------|
| `__getitem__(identifier)` | 通过索引或 Excel 标识(如 `"A01"`)访问槽位 |
| `__setitem__(identifier, resource)` | 向槽位放入资源 |
| `get_child_identifier(child)` | 获取子资源的标识符 |
| `capacity` | 总槽位数 |
| `sites` | 所有槽位字典 |
---
## 2. 序列化与反序列化
### PLR ↔ UniLab 转换
| 函数 | 位置 | 方向 |
|------|------|------|
| `ResourceTreeSet.from_plr_resources(resources)` | `resource_tracker.py` | PLR → UniLab |
| `ResourceTreeSet.to_plr_resources()` | `resource_tracker.py` | UniLab → PLR |
### `from_plr_resources` 流程
```
PLR Resource
↓ build_uuid_mapping (递归生成 UUID)
↓ resource.serialize() → dict
↓ resource.serialize_all_state() → states
↓ resource_plr_inner (递归构建 ResourceDictInstance)
ResourceTreeSet
```
关键:每个 PLR 资源通过 `unilabos_uuid` 属性携带 UUID`unilabos_extra` 携带扩展数据(如 `class` 名)。
### `to_plr_resources` 流程
```
ResourceTreeSet
↓ collect_node_data (收集 UUID、状态、扩展数据)
↓ node_to_plr_dict (转为 PLR 字典格式)
↓ find_subclass(type_name, PLRResource) (查找 PLR 子类)
↓ sub_cls.deserialize(plr_dict) (反序列化)
↓ loop_set_uuid, loop_set_extra (递归设置 UUID 和扩展)
PLR Resource
```
### Bottle 序列化
```python
class Bottle(Well):
def serialize(self) -> dict:
data = super().serialize()
return {**data, "diameter": self.diameter, "height": self.height}
@classmethod
def deserialize(cls, data: dict, allow_marshal=False):
barcode_data = data.pop("barcode", None)
instance = super().deserialize(data, allow_marshal=allow_marshal)
if barcode_data and isinstance(barcode_data, str):
instance.barcode = barcode_data
return instance
```
---
## 3. Bioyond 物料同步
### 双向转换函数
| 函数 | 位置 | 方向 |
|------|------|------|
| `resource_bioyond_to_plr(materials, type_mapping, deck)` | `graphio.py` | Bioyond → PLR |
| `resource_plr_to_bioyond(resources, type_mapping, warehouse_mapping)` | `graphio.py` | PLR → Bioyond |
### `resource_bioyond_to_plr` 流程
```
Bioyond 物料列表
↓ reverse_type_mapping: {typeName → (model, UUID)}
↓ 对每个物料:
typeName → 查映射 → model (如 "BIOYOND_PolymerStation_Reactor")
initialize_resource({"name": unique_name, "class": model})
↓ 设置 unilabos_extra (material_bioyond_id, material_bioyond_name 等)
↓ 处理 detail (子物料/坐标)
↓ 按 locationName 放入 deck.warehouses 对应槽位
PLR 资源列表
```
### `resource_plr_to_bioyond` 流程
```
PLR 资源列表
↓ 遍历每个资源:
载架(capacity > 1): 生成 details 子物料 + 坐标
单瓶: 直接映射
↓ type_mapping 查找 typeId
↓ warehouse_mapping 查找位置 UUID
↓ 组装 Bioyond 格式 (name, typeName, typeId, quantity, Parameters, locations)
Bioyond 物料列表
```
### BioyondResourceSynchronizer
工作站通过 `ResourceSynchronizer` 自动同步物料:
```python
class BioyondResourceSynchronizer(ResourceSynchronizer):
def sync_from_external(self) -> bool:
all_data = []
all_data.extend(api_client.stock_material('{"typeMode": 0}')) # 耗材
all_data.extend(api_client.stock_material('{"typeMode": 1}')) # 样品
all_data.extend(api_client.stock_material('{"typeMode": 2}')) # 试剂
unilab_resources = resource_bioyond_to_plr(
all_data,
type_mapping=self.workstation.bioyond_config["material_type_mappings"],
deck=self.workstation.deck
)
# 更新 deck 上的资源
```
---
## 4. 非瓶类资源
### ElectrodeSheet极片
路径:`unilabos/resources/battery/electrode_sheet.py`
```python
class ElectrodeSheet(ResourcePLR):
"""片状材料(极片、隔膜、弹片、垫片等)"""
_unilabos_state = {
"diameter": 0.0,
"thickness": 0.0,
"mass": 0.0,
"material_type": "",
"color": "",
"info": "",
}
```
工厂函数:`PositiveCan`, `PositiveElectrode`, `NegativeCan`, `NegativeElectrode`, `SpringWasher`, `FlatWasher`, `AluminumFoil`
### Battery电池
```python
class Battery(Container):
"""组装好的电池"""
_unilabos_state = {
"color": "",
"electrolyte_name": "",
"open_circuit_voltage": 0.0,
}
```
### Magazine / MagazineHolder子弹夹
```python
class Magazine(ResourceStack):
"""子弹夹洞位,可堆叠 ElectrodeSheet"""
# direction, max_sheets
class MagazineHolder(ItemizedResource):
"""多洞位子弹夹"""
# hole_diameter, hole_depth, max_sheets_per_hole
```
工厂函数 `magazine_factory()``create_homogeneous_resources` 生成洞位,可选预填 `ElectrodeSheet``Battery`
---
## 5. 仓库工厂模式参考
### 实际 warehouse 工厂函数示例
```python
# 行优先 4x4 仓库
def bioyond_warehouse_1x4x4(name: str) -> WareHouse:
return warehouse_factory(
name=name,
num_items_x=4, num_items_y=4, num_items_z=1,
dx=10.0, dy=10.0, dz=10.0,
item_dx=147.0, item_dy=106.0, item_dz=130.0,
layout="row-major", # A01,A02,A03,A04, B01,...
)
# 右侧 4x4 仓库(列名偏移)
def bioyond_warehouse_1x4x4_right(name: str) -> WareHouse:
return warehouse_factory(
name=name,
num_items_x=4, num_items_y=4, num_items_z=1,
dx=10.0, dy=10.0, dz=10.0,
item_dx=147.0, item_dy=106.0, item_dz=130.0,
col_offset=4, # A05,A06,A07,A08
layout="row-major",
)
# 竖向仓库(站内试剂存放)
def bioyond_warehouse_reagent_storage(name: str) -> WareHouse:
return warehouse_factory(
name=name,
num_items_x=1, num_items_y=2, num_items_z=1,
dx=10.0, dy=10.0, dz=10.0,
item_dx=147.0, item_dy=106.0, item_dz=130.0,
layout="vertical-col-major",
)
# 行偏移F 行开始)
def bioyond_warehouse_5x3x1(name: str, row_offset: int = 0) -> WareHouse:
return warehouse_factory(
name=name,
num_items_x=3, num_items_y=5, num_items_z=1,
dx=10.0, dy=10.0, dz=10.0,
item_dx=159.0, item_dy=183.0, item_dz=130.0,
row_offset=row_offset, # 0→A行起5→F行起
layout="row-major",
)
```
### layout 类型说明
| layout | 命名顺序 | 适用场景 |
|--------|---------|---------|
| `col-major` (默认) | A01,B01,C01,D01, A02,B02,... | 列优先,标准堆栈 |
| `row-major` | A01,A02,A03,A04, B01,B02,... | 行优先Bioyond 前端展示 |
| `vertical-col-major` | 竖向排列,标签从底部开始 | 竖向仓库(试剂存放、测密度) |
---
## 6. 关键路径
| 内容 | 路径 |
|------|------|
| Bottle/Carrier 基类 | `unilabos/resources/itemized_carrier.py` |
| WareHouse 类 + 工厂 | `unilabos/resources/warehouse.py` |
| ResourceTreeSet 转换 | `unilabos/resources/resource_tracker.py` |
| Bioyond 物料转换 | `unilabos/resources/graphio.py` |
| Bioyond 仓库定义 | `unilabos/resources/bioyond/warehouses.py` |
| 电池资源 | `unilabos/resources/battery/` |
| PLR 注册 | `unilabos/resources/plr_additional_res_reg.py` |

View File

@@ -0,0 +1,328 @@
---
name: create-device-skill
description: Create a skill for any Uni-Lab device by extracting action schemas from the device registry. Use when the user wants to create a new device skill, add device API documentation, or set up action schemas for a device.
---
# 创建设备 Skill 指南
本 meta-skill 教你如何为任意 Uni-Lab-OS 设备创建完整的 API 操作技能(参考 `unilab-device-api` 的成功案例)。
## 数据源
- **设备注册表**: `unilabos_data/req_device_registry_upload.json`
- **结构**: `{ "resources": [{ "id": "<device_id>", "class": { "module": "<python_module:ClassName>", "action_value_mappings": { ... } } }] }`
- **生成时机**: `unilab` 启动并完成注册表上传后自动生成
- **module 字段**: 格式 `unilabos.devices.xxx.yyy:ClassName`,可转为源码路径 `unilabos/devices/xxx/yyy.py`,阅读源码可了解参数含义和设备行为
## 创建流程
### Step 0 — 收集必备信息(缺一不可,否则询问后终止)
开始前**必须**确认以下 4 项信息全部就绪。如果用户未提供任何一项,**立即询问并终止当前流程**,等用户补齐后再继续。
向用户提问:「请提供你的 unilab 启动参数,我需要以下信息:」
#### 必备项 ①ak / sk认证凭据
来源:启动命令的 `--ak` `--sk` 参数,或 config.py 中的 `ak = "..."` `sk = "..."`
获取后立即生成 AUTH token
```bash
python ./scripts/gen_auth.py <ak> <sk>
# 或从 config.py 提取
python ./scripts/gen_auth.py --config <config.py>
```
认证算法:`base64(ak:sk)``Authorization: Lab <token>`
#### 必备项 ②:--addr目标环境
决定 API 请求发往哪个服务器。从启动命令的 `--addr` 参数获取:
| `--addr` 值 | BASE URL |
|-------------|----------|
| `test` | `https://uni-lab.test.bohrium.com` |
| `uat` | `https://uni-lab.uat.bohrium.com` |
| `local` | `http://127.0.0.1:48197` |
| 不传(默认) | `https://uni-lab.bohrium.com` |
| 其他自定义 URL | 直接使用该 URL |
#### 必备项 ③req_device_registry_upload.json设备注册表
数据文件由 `unilab` 启动时自动生成,需要定位它:
**推断 working_dir**(即 `unilabos_data` 所在目录):
| 条件 | working_dir 取值 |
|------|------------------|
| 传了 `--working_dir` | `<working_dir>/unilabos_data/`(若子目录已存在则直接用) |
| 仅传了 `--config` | `<config 文件所在目录>/unilabos_data/` |
| 都没传 | `<当前工作目录>/unilabos_data/` |
**按优先级搜索文件**
```
<推断的 working_dir>/unilabos_data/req_device_registry_upload.json
<推断的 working_dir>/req_device_registry_upload.json
<workspace 根目录>/unilabos_data/req_device_registry_upload.json
```
也可以直接 Glob 搜索:`**/req_device_registry_upload.json`
找到后**必须检查文件修改时间**并告知用户:「找到注册表文件 `<路径>`,生成于 `<时间>`。请确认这是最近一次启动生成的。」超过 1 天提醒用户是否需要重新启动 `unilab`
**如果文件不存在** → 告知用户先运行 `unilab` 启动命令,等日志出现 `注册表响应数据已保存` 后再执行本流程。**终止。**
#### 必备项 ④:目标设备
用户需要明确要为哪个设备创建 skill。可以是设备名称如「PRCXI 移液站」)或 device_id`liquid_handler.prcxi`)。
如果用户不确定,运行提取脚本列出所有设备供选择:
```bash
python ./scripts/extract_device_actions.py --registry <找到的文件路径>
```
#### 完整示例
用户提供:
```
--ak a1fd9d4e-xxxx-xxxx-xxxx-d9a69c09f0fd
--sk 136ff5c6-xxxx-xxxx-xxxx-a03e301f827b
--addr test
--port 8003
--disable_browser
```
从中提取:
- ✅ ak/sk → 运行 `gen_auth.py` 得到 `AUTH="Authorization: Lab YTFmZDlk..."`
- ✅ addr=test → `BASE=https://uni-lab.test.bohrium.com`
- ✅ 搜索 `unilabos_data/req_device_registry_upload.json` → 找到并确认时间
- ✅ 用户指明目标设备 → 如 `liquid_handler.prcxi`
**四项全部就绪后才进入 Step 1。**
### Step 1 — 列出可用设备
运行提取脚本,列出所有设备及 action 数量和 Python 源码路径,让用户选择:
```bash
# 自动搜索(默认在 unilabos_data/ 和当前目录查找)
python ./scripts/extract_device_actions.py
# 指定注册表文件路径
python ./scripts/extract_device_actions.py --registry <path/to/req_device_registry_upload.json>
```
脚本输出包含每个设备的 **Python 源码路径**(从 `class.module` 转换),可用于后续阅读源码理解参数含义。
### Step 2 — 提取 Action Schema
用户选择设备后,运行提取脚本:
```bash
python ./scripts/extract_device_actions.py [--registry <path>] <device_id> ./skills/<skill-name>/actions/
```
脚本会显示设备的 Python 源码路径和类名,方便阅读源码了解参数含义。
每个 action 生成一个 JSON 文件,包含:
- `type` — 作为 API 调用的 `action_type`
- `schema` — 完整 JSON Schema`properties.goal.properties` 参数定义)
- `goal` — goal 字段映射(含占位符 `$placeholder`
- `goal_default` — 默认值
### Step 3 — 写 action-index.md
按模板为每个 action 写条目:
```markdown
### `<action_name>`
<用途描述(一句话)>
- **Schema**: [`actions/<filename>.json`](actions/<filename>.json)
- **核心参数**: `param1`, `param2`(从 schema.required 获取)
- **可选参数**: `param3`, `param4`
- **占位符字段**: `field`(需填入物料信息,值以 `$` 开头)
```
描述规则:
-`schema.properties` 读参数列表schema 已提升为 goal 内容)
-`schema.required` 区分核心/可选参数
- 按功能分类(移液、枪头、外设等)
- 标注 `placeholder_keys` 中的字段类型:
- `unilabos_resources`**ResourceSlot**,填入 `{id, name, uuid}`id 是路径格式,从资源树取物料节点)
- `unilabos_devices`**DeviceSlot**,填入路径字符串如 `"/host_node"`(从资源树筛选 type=device
- `unilabos_nodes`**NodeSlot**,填入路径字符串如 `"/PRCXI/PRCXI_Deck"`(资源树中任意节点)
- `unilabos_class`**ClassSlot**,填入类名字符串如 `"container"`(从注册表查找)
- array 类型字段 → `[{id, name, uuid}, ...]`
- 特殊:`create_resource``res_id`ResourceSlot可填不存在的路径
### Step 4 — 写 SKILL.md
直接复用 `unilab-device-api` 的 API 模板10 个 endpoint修改
- 设备名称
- Action 数量
- 目录列表
- Session state 中的 `device_name`
- **AUTH 头** — 使用 Step 0 中 `gen_auth.py` 生成的 `Authorization: Lab <token>`(不要硬编码 `Api` 类型的 key
- **Python 源码路径** — 在 SKILL.md 开头注明设备对应的源码文件,方便参考参数含义
- **Slot 字段表** — 列出本设备哪些 action 的哪些字段需要填入 Slot物料/设备/节点/类名)
API 模板结构:
```markdown
## 设备信息
- device_id, Python 源码路径, 设备类名
## 前置条件(缺一不可)
- ak/sk → AUTH, --addr → BASE URL
## Session State
- lab_uuid通过 API #1 自动匹配,不要问用户), device_name
## API Endpoints (10 个)
# 注意:
# - #1 获取 lab 列表 + 自动匹配 lab_uuid遍历 is_admin 的 lab
# 调用 /lab/info/{uuid} 比对 access_key == ak
# - #2 创建工作流用 POST /lab/workflow
# - #10 获取资源树路径含 lab_uuid: /lab/material/download/{lab_uuid}
## Placeholder Slot 填写规则
- unilabos_resources → ResourceSlot → {"id":"/path/name","name":"name","uuid":"xxx"}
- unilabos_devices → DeviceSlot → "/parent/device" 路径字符串
- unilabos_nodes → NodeSlot → "/parent/node" 路径字符串
- unilabos_class → ClassSlot → "class_name" 字符串
- 特例create_resource 的 res_id 允许填不存在的路径
- 列出本设备所有 Slot 字段、类型及含义
## 渐进加载策略
## 完整工作流 Checklist
```
### Step 5 — 验证
检查文件完整性:
- [ ] `SKILL.md` 包含 10 个 API endpoint
- [ ] `SKILL.md` 包含 Placeholder Slot 填写规则ResourceSlot / DeviceSlot / NodeSlot / ClassSlot + create_resource 特例)和本设备的 Slot 字段表
- [ ] `action-index.md` 列出所有 action 并有描述
- [ ] `actions/` 目录中每个 action 有对应 JSON 文件
- [ ] JSON 文件包含 `type`, `schema`(已提升为 goal 内容), `goal`, `goal_default`, `placeholder_keys` 字段
- [ ] 描述能让 agent 判断该用哪个 action
## Action JSON 文件结构
```json
{
"type": "LiquidHandlerTransfer", // → API 的 action_type
"goal": { // goal 字段映射
"sources": "sources",
"targets": "targets",
"tip_racks": "tip_racks",
"asp_vols": "asp_vols"
},
"schema": { // ← 直接是 goal 的 schema已提升
"type": "object",
"properties": { // 参数定义(即请求中 goal 的字段)
"sources": { "type": "array", "items": { "type": "object" } },
"targets": { "type": "array", "items": { "type": "object" } },
"asp_vols": { "type": "array", "items": { "type": "number" } }
},
"required": [...],
"_unilabos_placeholder_info": { // ← Slot 类型标记
"sources": "unilabos_resources",
"targets": "unilabos_resources",
"tip_racks": "unilabos_resources"
}
},
"goal_default": { ... }, // 默认值
"placeholder_keys": { // ← 汇总所有 Slot 字段
"sources": "unilabos_resources", // ResourceSlot
"targets": "unilabos_resources",
"tip_racks": "unilabos_resources",
"target_device_id": "unilabos_devices" // DeviceSlot
}
}
```
> **注意**`schema` 已由脚本从原始 `schema.properties.goal` 提升为顶层,直接包含参数定义。
> `schema.properties` 中的字段即为 API 请求 `param.goal` 中的字段。
## Placeholder Slot 类型体系
`placeholder_keys` / `_unilabos_placeholder_info` 中有 4 种值,对应不同的填写方式:
| placeholder 值 | Slot 类型 | 填写格式 | 选取范围 |
|---------------|-----------|---------|---------|
| `unilabos_resources` | ResourceSlot | `{"id": "/path/name", "name": "name", "uuid": "xxx"}` | 仅**物料**节点(不含设备) |
| `unilabos_devices` | DeviceSlot | `"/parent/device_name"` | 仅**设备**节点type=device路径字符串 |
| `unilabos_nodes` | NodeSlot | `"/parent/node_name"` | **设备 + 物料**,即所有节点,路径字符串 |
| `unilabos_class` | ClassSlot | `"class_name"` | 注册表中已上报的资源类 name |
### ResourceSlot`unilabos_resources`
最常见的类型。从资源树中选取**物料**节点(孔板、枪头盒、试剂槽等):
```json
{"id": "/workstation/container1", "name": "container1", "uuid": "ff149a9a-2cb8-419d-8db5-d3ba056fb3c2"}
```
- 单个schema type=object`{"id": "/path/name", "name": "name", "uuid": "xxx"}`
- 数组schema type=array`[{"id": "/path/a", "name": "a", "uuid": "xxx"}, ...]`
- `id` 本身是从 parent 计算的路径格式
- 根据 action 语义选择正确的物料(如 `sources` = 液体来源,`targets` = 目标位置)
> **特例**`create_resource` 的 `res_id` 字段,目标物料可能**尚不存在**,此时直接填写期望的路径(如 `"/workstation/container1"`),不需要 uuid。
### DeviceSlot`unilabos_devices`
填写**设备路径字符串**。从资源树中筛选 type=device 的节点,从 parent 计算路径:
```
"/host_node"
"/bioyond_cell/reaction_station"
```
- 只填路径字符串,不需要 `{id, uuid}` 对象
- 根据 action 语义选择正确的设备(如 `target_device_id` = 目标设备)
### NodeSlot`unilabos_nodes`
范围 = 设备 + 物料。即资源树中**所有节点**都可以选,填写**路径字符串**
```
"/PRCXI/PRCXI_Deck"
```
- 使用场景:当参数既可能指向物料也可能指向设备时(如 `PumpTransferProtocol``from_vessel`/`to_vessel``create_resource``parent`
### ClassSlot`unilabos_class`
填写注册表中已上报的**资源类 name**。从本地 `req_resource_registry_upload.json` 中查找:
```
"container"
```
### 通过 API #10 获取资源树
```bash
curl -s -X GET "$BASE/api/v1/lab/material/download/$lab_uuid" -H "$AUTH"
```
注意 `lab_uuid` 在路径中(不是查询参数)。资源树返回所有节点,每个节点包含 `id`(路径格式)、`name``uuid``type``parent` 等字段。填写 Slot 时需根据 placeholder 类型筛选正确的节点。
## 最终目录结构
```
./<skill-name>/
├── SKILL.md # API 端点 + 渐进加载指引
├── action-index.md # 动作索引:描述/用途/核心参数
└── actions/ # 每个 action 的完整 JSON Schema
├── action1.json
├── action2.json
└── ...
```

View File

@@ -0,0 +1,200 @@
#!/usr/bin/env python3
"""
从 req_device_registry_upload.json 中提取指定设备的 action schema。
用法:
# 列出所有设备及 action 数量(自动搜索注册表文件)
python extract_device_actions.py
# 指定注册表文件路径
python extract_device_actions.py --registry <path/to/req_device_registry_upload.json>
# 提取指定设备的 action 到目录
python extract_device_actions.py <device_id> <output_dir>
python extract_device_actions.py --registry <path> <device_id> <output_dir>
示例:
python extract_device_actions.py --registry unilabos_data/req_device_registry_upload.json
python extract_device_actions.py liquid_handler.prcxi .cursor/skills/unilab-device-api/actions/
"""
import json
import os
import sys
from datetime import datetime
REGISTRY_FILENAME = "req_device_registry_upload.json"
def find_registry(explicit_path=None):
"""
查找 req_device_registry_upload.json 文件。
搜索优先级:
1. 用户通过 --registry 显式指定的路径
2. <cwd>/unilabos_data/req_device_registry_upload.json
3. <cwd>/req_device_registry_upload.json
4. <script所在目录>/../../.. (workspace根) 下的 unilabos_data/
5. 向上逐级搜索父目录(最多 5 层)
"""
if explicit_path:
if os.path.isfile(explicit_path):
return explicit_path
if os.path.isdir(explicit_path):
fp = os.path.join(explicit_path, REGISTRY_FILENAME)
if os.path.isfile(fp):
return fp
print(f"警告: 指定的路径不存在: {explicit_path}")
return None
candidates = [
os.path.join("unilabos_data", REGISTRY_FILENAME),
REGISTRY_FILENAME,
]
for c in candidates:
if os.path.isfile(c):
return c
script_dir = os.path.dirname(os.path.abspath(__file__))
workspace_root = os.path.normpath(os.path.join(script_dir, "..", "..", ".."))
for c in candidates:
path = os.path.join(workspace_root, c)
if os.path.isfile(path):
return path
cwd = os.getcwd()
for _ in range(5):
parent = os.path.dirname(cwd)
if parent == cwd:
break
cwd = parent
for c in candidates:
path = os.path.join(cwd, c)
if os.path.isfile(path):
return path
return None
def load_registry(path):
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
def list_devices(data):
"""列出所有包含 action_value_mappings 的设备,同时返回 module 路径"""
resources = data.get('resources', [])
devices = []
for res in resources:
rid = res.get('id', '')
cls = res.get('class', {})
avm = cls.get('action_value_mappings', {})
module = cls.get('module', '')
if avm:
devices.append((rid, len(avm), module))
return devices
def flatten_schema_to_goal(action_data):
"""将 schema 中嵌套的 goal 内容提升为顶层 schema去掉 feedback/result 包装"""
schema = action_data.get('schema', {})
goal_schema = schema.get('properties', {}).get('goal', {})
if goal_schema:
action_data = dict(action_data)
action_data['schema'] = goal_schema
return action_data
def extract_actions(data, device_id, output_dir):
"""提取指定设备的 action schema 到独立 JSON 文件"""
resources = data.get('resources', [])
for res in resources:
if res.get('id') == device_id:
cls = res.get('class', {})
module = cls.get('module', '')
avm = cls.get('action_value_mappings', {})
if not avm:
print(f"设备 {device_id} 没有 action_value_mappings")
return []
if module:
py_path = module.split(":")[0].replace(".", "/") + ".py"
class_name = module.split(":")[-1] if ":" in module else ""
print(f"Python 源码: {py_path}")
if class_name:
print(f"设备类: {class_name}")
os.makedirs(output_dir, exist_ok=True)
written = []
for action_name in sorted(avm.keys()):
action_data = flatten_schema_to_goal(avm[action_name])
filename = action_name.replace('-', '_') + '.json'
filepath = os.path.join(output_dir, filename)
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(action_data, f, indent=2, ensure_ascii=False)
written.append(filename)
print(f" {filepath}")
return written
print(f"设备 {device_id} 未找到")
return []
def main():
args = sys.argv[1:]
explicit_registry = None
if "--registry" in args:
idx = args.index("--registry")
if idx + 1 < len(args):
explicit_registry = args[idx + 1]
args = args[:idx] + args[idx + 2:]
else:
print("错误: --registry 需要指定路径")
sys.exit(1)
registry_path = find_registry(explicit_registry)
if not registry_path:
print(f"错误: 找不到 {REGISTRY_FILENAME}")
print()
print("解决方法:")
print(" 1. 先运行 unilab 启动命令,等待注册表生成")
print(" 2. 用 --registry 指定文件路径:")
print(f" python {sys.argv[0]} --registry <path/to/{REGISTRY_FILENAME}>")
print()
print("搜索过的路径:")
for p in [
os.path.join("unilabos_data", REGISTRY_FILENAME),
REGISTRY_FILENAME,
os.path.join("<workspace_root>", "unilabos_data", REGISTRY_FILENAME),
]:
print(f" - {p}")
sys.exit(1)
print(f"注册表: {registry_path}")
mtime = os.path.getmtime(registry_path)
gen_time = datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
size_mb = os.path.getsize(registry_path) / (1024 * 1024)
print(f"生成时间: {gen_time} (文件大小: {size_mb:.1f} MB)")
data = load_registry(registry_path)
if len(args) == 0:
devices = list_devices(data)
print(f"\n找到 {len(devices)} 个设备:")
print(f"{'设备 ID':<50} {'Actions':>7} {'Python 模块'}")
print("-" * 120)
for did, count, module in sorted(devices, key=lambda x: x[0]):
py_path = module.split(":")[0].replace(".", "/") + ".py" if module else ""
print(f"{did:<50} {count:>7} {py_path}")
elif len(args) == 2:
device_id = args[0]
output_dir = args[1]
print(f"\n提取 {device_id} 的 actions 到 {output_dir}/")
written = extract_actions(data, device_id, output_dir)
if written:
print(f"\n共写入 {len(written)} 个 action 文件")
else:
print("用法:")
print(" python extract_device_actions.py [--registry <path>] # 列出设备")
print(" python extract_device_actions.py [--registry <path>] <device_id> <dir> # 提取 actions")
sys.exit(1)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env python3
"""
从 ak/sk 生成 UniLab API Authorization header。
算法: base64(ak:sk) → "Authorization: Lab <token>"
用法:
python gen_auth.py <ak> <sk>
python gen_auth.py --config <config.py>
示例:
python gen_auth.py myak mysk
python gen_auth.py --config experiments/config.py
"""
import base64
import re
import sys
def gen_auth(ak: str, sk: str) -> str:
token = base64.b64encode(f"{ak}:{sk}".encode("utf-8")).decode("utf-8")
return token
def extract_from_config(config_path: str) -> tuple:
"""从 config.py 中提取 ak 和 sk"""
with open(config_path, "r", encoding="utf-8") as f:
content = f.read()
ak_match = re.search(r'''ak\s*=\s*["']([^"']+)["']''', content)
sk_match = re.search(r'''sk\s*=\s*["']([^"']+)["']''', content)
if not ak_match or not sk_match:
return None, None
return ak_match.group(1), sk_match.group(1)
def main():
args = sys.argv[1:]
if len(args) == 2 and args[0] == "--config":
ak, sk = extract_from_config(args[1])
if not ak or not sk:
print(f"错误: 在 {args[1]} 中未找到 ak/sk 配置")
print("期望格式: ak = \"xxx\" sk = \"xxx\"")
sys.exit(1)
print(f"配置文件: {args[1]}")
elif len(args) == 2:
ak, sk = args
else:
print("用法:")
print(" python gen_auth.py <ak> <sk>")
print(" python gen_auth.py --config <config.py>")
sys.exit(1)
token = gen_auth(ak, sk)
print(f"ak: {ak}")
print(f"sk: {sk}")
print()
print(f"Authorization header:")
print(f" Authorization: Lab {token}")
print()
print(f"curl 用法:")
print(f' curl -H "Authorization: Lab {token}" ...')
print()
print(f"Shell 变量:")
print(f' AUTH="Authorization: Lab {token}"')
if __name__ == "__main__":
main()

View File

@@ -1,6 +1,6 @@
package: package:
name: ros-humble-unilabos-msgs name: ros-humble-unilabos-msgs
version: 0.10.18 version: 0.10.19
source: source:
path: ../../unilabos_msgs path: ../../unilabos_msgs
target_directory: src target_directory: src

View File

@@ -1,6 +1,6 @@
package: package:
name: unilabos name: unilabos
version: "0.10.18" version: "0.10.19"
source: source:
path: ../.. path: ../..

View File

@@ -4,7 +4,7 @@ package_name = 'unilabos'
setup( setup(
name=package_name, name=package_name,
version='0.10.18', version='0.10.19',
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
install_requires=['setuptools'], install_requires=['setuptools'],

View File

@@ -1 +1 @@
__version__ = "0.10.18" __version__ = "0.10.19"

View File

@@ -247,6 +247,12 @@ def parse_args():
default=False, default=False,
help="Run in check mode for CI: validates registry imports and ensures no file changes", help="Run in check mode for CI: validates registry imports and ensures no file changes",
) )
parser.add_argument(
"--complete_registry",
action="store_true",
default=False,
help="Complete and rewrite YAML registry files using AST analysis results",
)
parser.add_argument( parser.add_argument(
"--no_update_feedback", "--no_update_feedback",
action="store_true", action="store_true",
@@ -258,6 +264,12 @@ def parse_args():
default=False, default=False,
help="Test mode: all actions simulate execution and return mock results without running real hardware", help="Test mode: all actions simulate execution and return mock results without running real hardware",
) )
parser.add_argument(
"--external_devices_only",
action="store_true",
default=False,
help="Only load external device packages (--devices), skip built-in unilabos/devices/ scanning and YAML device registry",
)
parser.add_argument( parser.add_argument(
"--extra_resource", "--extra_resource",
action="store_true", action="store_true",
@@ -336,11 +348,18 @@ def main():
check_mode = args_dict.get("check_mode", False) check_mode = args_dict.get("check_mode", False)
if not skip_env_check: if not skip_env_check:
from unilabos.utils.environment_check import check_environment from unilabos.utils.environment_check import check_environment, check_device_package_requirements
if not check_environment(auto_install=True): if not check_environment(auto_install=True):
print_status("环境检查失败,程序退出", "error") print_status("环境检查失败,程序退出", "error")
os._exit(1) os._exit(1)
# 第一次设备包依赖检查build_registry 之前,确保 import map 可用
devices_dirs_for_req = args_dict.get("devices", None)
if devices_dirs_for_req:
if not check_device_package_requirements(devices_dirs_for_req):
print_status("设备包依赖检查失败,程序退出", "error")
os._exit(1)
else: else:
print_status("跳过环境依赖检查", "warning") print_status("跳过环境依赖检查", "warning")
@@ -471,19 +490,7 @@ def main():
BasicConfig.vis_2d_enable = args_dict["2d_vis"] BasicConfig.vis_2d_enable = args_dict["2d_vis"]
BasicConfig.check_mode = check_mode BasicConfig.check_mode = check_mode
from unilabos.resources.graphio import (
read_node_link_json,
read_graphml,
dict_from_graph,
)
from unilabos.app.communication import get_communication_client
from unilabos.registry.registry import build_registry from unilabos.registry.registry import build_registry
from unilabos.app.backend import start_backend
from unilabos.app.web import http_client
from unilabos.app.web import start_server
from unilabos.app.register import register_devices_and_resources
from unilabos.resources.graphio import modify_to_backend_format
from unilabos.resources.resource_tracker import ResourceTreeSet, ResourceDict
# 显示启动横幅 # 显示启动横幅
print_unilab_banner(args_dict) print_unilab_banner(args_dict)
@@ -491,11 +498,15 @@ def main():
# Step 0: AST 分析优先 + YAML 注册表加载 # Step 0: AST 分析优先 + YAML 注册表加载
# check_mode 和 upload_registry 都会执行实际 import 验证 # check_mode 和 upload_registry 都会执行实际 import 验证
devices_dirs = args_dict.get("devices", None) devices_dirs = args_dict.get("devices", None)
complete_registry = args_dict.get("complete_registry", False) or check_mode
external_only = args_dict.get("external_devices_only", False)
lab_registry = build_registry( lab_registry = build_registry(
registry_paths=args_dict["registry_path"], registry_paths=args_dict["registry_path"],
devices_dirs=devices_dirs, devices_dirs=devices_dirs,
upload_registry=BasicConfig.upload_registry, upload_registry=BasicConfig.upload_registry,
check_mode=check_mode, check_mode=check_mode,
complete_registry=complete_registry,
external_only=external_only,
) )
# Check mode: 注册表验证完成后直接退出 # Check mode: 注册表验证完成后直接退出
@@ -505,6 +516,20 @@ def main():
print_status(f"Check mode: 注册表验证完成 ({device_count} 设备, {resource_count} 资源),退出", "info") print_status(f"Check mode: 注册表验证完成 ({device_count} 设备, {resource_count} 资源),退出", "info")
os._exit(0) os._exit(0)
# 以下导入依赖 ROS2 环境check_mode 已退出不需要
from unilabos.resources.graphio import (
read_node_link_json,
read_graphml,
dict_from_graph,
modify_to_backend_format,
)
from unilabos.app.communication import get_communication_client
from unilabos.app.backend import start_backend
from unilabos.app.web import http_client
from unilabos.app.web import start_server
from unilabos.app.register import register_devices_and_resources
from unilabos.resources.resource_tracker import ResourceTreeSet, ResourceDict
# Step 1: 上传全部注册表到服务端,同步保存到 unilabos_data # Step 1: 上传全部注册表到服务端,同步保存到 unilabos_data
if BasicConfig.upload_registry: if BasicConfig.upload_registry:
if BasicConfig.ak and BasicConfig.sk: if BasicConfig.ak and BasicConfig.sk:
@@ -602,6 +627,10 @@ def main():
resource_tree_set.merge_remote_resources(remote_tree_set) resource_tree_set.merge_remote_resources(remote_tree_set)
print_status("远端物料同步完成", "info") print_status("远端物料同步完成", "info")
# 第二次设备包依赖检查云端物料同步后community 包可能引入新的 requirements
# TODO: 当 community device package 功能上线后,在这里调用
# install_requirements_txt(community_pkg_path / "requirements.txt", label="community.xxx")
# 使用 ResourceTreeSet 代替 list # 使用 ResourceTreeSet 代替 list
args_dict["resources_config"] = resource_tree_set args_dict["resources_config"] = resource_tree_set
args_dict["devices_config"] = resource_tree_set args_dict["devices_config"] = resource_tree_set

View File

@@ -1,19 +1,8 @@
import json
import time import time
from typing import Any, Dict, Optional, Tuple from typing import Any, Dict, Optional, Tuple
from unilabos.utils.log import logger from unilabos.utils.log import logger
from unilabos.utils.type_check import TypeEncoder from unilabos.utils.tools import normalize_json as _normalize_device
try:
import orjson
def _normalize_device(info: dict) -> dict:
"""Serialize via orjson to strip non-JSON types (type objects etc.)."""
return orjson.loads(orjson.dumps(info, default=str))
except ImportError:
def _normalize_device(info: dict) -> dict:
return json.loads(json.dumps(info, ensure_ascii=False, cls=TypeEncoder))
def register_devices_and_resources(lab_registry, gather_only=False) -> Optional[Tuple[Dict[str, Any], Dict[str, Any]]]: def register_devices_and_resources(lab_registry, gather_only=False) -> Optional[Tuple[Dict[str, Any], Dict[str, Any]]]:

View File

@@ -8,24 +8,7 @@ import json
import os import os
from typing import List, Dict, Any, Optional from typing import List, Dict, Any, Optional
try: from unilabos.utils.tools import fast_dumps as _fast_dumps, fast_dumps_pretty as _fast_dumps_pretty
import orjson as _json_fast
def _fast_dumps(obj, **kwargs) -> bytes:
return _json_fast.dumps(obj, option=_json_fast.OPT_NON_STR_KEYS, default=str)
def _fast_dumps_pretty(obj, **kwargs) -> bytes:
return _json_fast.dumps(
obj, option=_json_fast.OPT_NON_STR_KEYS | _json_fast.OPT_INDENT_2, default=str,
)
except ImportError:
_json_fast = None # type: ignore[assignment]
def _fast_dumps(obj, **kwargs) -> bytes:
return json.dumps(obj, ensure_ascii=False, default=str).encode("utf-8")
def _fast_dumps_pretty(obj, **kwargs) -> bytes:
return json.dumps(obj, indent=2, ensure_ascii=False, default=str).encode("utf-8")
import requests import requests
from unilabos.resources.resource_tracker import ResourceTreeSet from unilabos.resources.resource_tracker import ResourceTreeSet

View File

@@ -0,0 +1,88 @@
"""虚拟样品演示设备 — 用于前端 sample tracking 功能的极简 demo"""
import asyncio
import logging
import random
import time
from typing import Any, Dict, List, Optional
class VirtualSampleDemo:
"""虚拟样品追踪演示设备,提供两种典型返回模式:
- measure_samples: 等长输入输出 (前端按 index 自动对齐)
- split_and_measure: 输出比输入长,附带 samples 列标注归属
"""
def __init__(self, device_id: Optional[str] = None, config: Optional[Dict[str, Any]] = None, **kwargs):
if device_id is None and "id" in kwargs:
device_id = kwargs.pop("id")
if config is None and "config" in kwargs:
config = kwargs.pop("config")
self.device_id = device_id or "unknown_sample_demo"
self.config = config or {}
self.logger = logging.getLogger(f"VirtualSampleDemo.{self.device_id}")
self.data: Dict[str, Any] = {"status": "Idle"}
# ------------------------------------------------------------------
# Action 1: 等长输入输出,无 samples 列
# ------------------------------------------------------------------
async def measure_samples(self, concentrations: List[float]) -> Dict[str, Any]:
"""模拟光度测量。absorbance = concentration * 0.05 + noise
入参和出参 list 长度相等,前端按 index 自动对齐。
"""
self.logger.info(f"measure_samples: concentrations={concentrations}")
absorbance = [round(c * 0.05 + random.gauss(0, 0.005), 4) for c in concentrations]
return {"concentrations": concentrations, "absorbance": absorbance}
# ------------------------------------------------------------------
# Action 2: 输出比输入长,带 samples 列
# ------------------------------------------------------------------
async def split_and_measure(self, volumes: List[float], split_count: int = 3) -> Dict[str, Any]:
"""将每个样品均分为 split_count 份后逐份测量。
返回的 list 长度 = len(volumes) * split_count
附带 samples 列标注每行属于第几个输入样品 (0-based index)。
"""
self.logger.info(f"split_and_measure: volumes={volumes}, split_count={split_count}")
out_volumes: List[float] = []
readings: List[float] = []
samples: List[int] = []
for idx, vol in enumerate(volumes):
split_vol = round(vol / split_count, 2)
for _ in range(split_count):
out_volumes.append(split_vol)
readings.append(round(random.uniform(0.1, 1.0), 4))
samples.append(idx)
return {"volumes": out_volumes, "readings": readings, "samples": samples}
# ------------------------------------------------------------------
# Action 3: 入参和出参都带 samples 列(不等长)
# ------------------------------------------------------------------
async def analyze_readings(self, readings: List[float], samples: List[int]) -> Dict[str, Any]:
"""对 split_and_measure 的输出做二次分析。
入参 readings/samples 长度相同但 > 原始样品数,
出参同样带 samples 列,长度与入参一致。
"""
self.logger.info(f"analyze_readings: readings={readings}, samples={samples}")
scores: List[float] = []
passed: List[bool] = []
threshold = 0.4
for r in readings:
score = round(r * 100 + random.gauss(0, 2), 2)
scores.append(score)
passed.append(r >= threshold)
return {"scores": scores, "passed": passed, "samples": samples}
# ------------------------------------------------------------------
# 状态属性
# ------------------------------------------------------------------
@property
def status(self) -> str:
return self.data.get("status", "Idle")

View File

@@ -139,6 +139,7 @@ def scan_directory(
executor: ThreadPoolExecutor = None, executor: ThreadPoolExecutor = None,
exclude_files: Optional[set] = None, exclude_files: Optional[set] = None,
cache: Optional[Dict[str, Any]] = None, cache: Optional[Dict[str, Any]] = None,
include_files: Optional[List[Union[str, Path]]] = None,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
""" """
Recursively scan .py files under *root_dir* for @device and @resource Recursively scan .py files under *root_dir* for @device and @resource
@@ -164,6 +165,7 @@ def scan_directory(
exclude_files: 要排除的文件名集合 (如 {"lab_resources.py"}) exclude_files: 要排除的文件名集合 (如 {"lab_resources.py"})
cache: Mutable cache dict (``load_scan_cache()`` result). Hits are read cache: Mutable cache dict (``load_scan_cache()`` result). Hits are read
from here; misses are written back so the caller can persist later. from here; misses are written back so the caller can persist later.
include_files: 指定扫描的文件列表,提供时跳过目录递归收集,直接扫描这些文件。
""" """
if executor is None: if executor is None:
raise ValueError("executor is required and must not be None") raise ValueError("executor is required and must not be None")
@@ -175,7 +177,10 @@ def scan_directory(
python_path = Path(python_path).resolve() python_path = Path(python_path).resolve()
# --- Collect files (depth/count limited) --- # --- Collect files (depth/count limited) ---
py_files = _collect_py_files(root_dir, max_depth=max_depth, max_files=max_files, exclude_files=exclude_files) if include_files is not None:
py_files = [Path(f).resolve() for f in include_files if Path(f).resolve().exists()]
else:
py_files = _collect_py_files(root_dir, max_depth=max_depth, max_files=max_files, exclude_files=exclude_files)
cache_files: Dict[str, Any] = cache.get("files", {}) if cache else {} cache_files: Dict[str, Any] = cache.get("files", {}) if cache else {}
@@ -839,24 +844,39 @@ def _extract_class_body(
if _has_decorator(item, "not_action") and _is_registry_decorator("not_action", import_map): if _has_decorator(item, "not_action") and _is_registry_decorator("not_action", import_map):
continue continue
# --- get_ 前缀且无额外参数(仅 self→ status property ---
if method_name.startswith("get_"):
real_args = [a for a in item.args.args if a.arg != "self"]
if len(real_args) == 0:
prop_name = method_name[4:]
return_type = _get_annotation_str(item.returns, import_map)
if prop_name not in result["status_properties"]:
result["status_properties"][prop_name] = {
"name": prop_name,
"return_type": return_type,
"is_property": False,
"topic_config": None,
}
continue
# --- Public method without @action => auto-action --- # --- Public method without @action => auto-action ---
# Skip lifecycle / dunder methods that should never be auto-actions
if method_name in ("post_init", "__str__", "__repr__"): if method_name in ("post_init", "__str__", "__repr__"):
continue continue
# 'close' and 'cleanup' could be actions in some drivers -- keep them
method_params = _extract_method_params(item, import_map) method_params = _extract_method_params(item, import_map)
return_type = _get_annotation_str(item.returns, import_map) return_type = _get_annotation_str(item.returns, import_map)
is_async = isinstance(item, ast.AsyncFunctionDef) is_async = isinstance(item, ast.AsyncFunctionDef)
method_doc = ast.get_docstring(item) method_doc = ast.get_docstring(item)
result["auto_methods"][method_name] = { auto_entry: dict = {
"params": method_params, "params": method_params,
"return_type": return_type, "return_type": return_type,
"is_async": is_async, "is_async": is_async,
"docstring": method_doc, "docstring": method_doc,
} }
if _has_decorator(item, "always_free") and _is_registry_decorator("always_free", import_map):
auto_entry["always_free"] = True
result["auto_methods"][method_name] = auto_entry
return result return result

View File

@@ -13,21 +13,18 @@ Qone_nmr:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -71,31 +68,6 @@ Qone_nmr:
title: monitor_folder_for_new_content参数 title: monitor_folder_for_new_content参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: string
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-strings_to_txt: auto-strings_to_txt:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -138,21 +110,18 @@ Qone_nmr:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -167,32 +136,31 @@ Qone_nmr:
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:

View File

@@ -22,7 +22,8 @@ bioyond_cell:
required: required:
- xlsx_path - xlsx_path
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: auto_batch_outbound_from_xlsx参数 title: auto_batch_outbound_from_xlsx参数
@@ -490,7 +491,9 @@ bioyond_cell:
goal: goal:
properties: properties:
material_names: material_names:
type: string items:
type: string
type: array
type_id: type_id:
default: 3a190ca0-b2f6-9aeb-8067-547e72c11469 default: 3a190ca0-b2f6-9aeb-8067-547e72c11469
type: string type: string
@@ -499,7 +502,8 @@ bioyond_cell:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_and_inbound_materials参数 title: create_and_inbound_materials参数
@@ -535,7 +539,8 @@ bioyond_cell:
- type_id - type_id
- warehouse_name - warehouse_name
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_material参数 title: create_material参数
@@ -556,11 +561,16 @@ bioyond_cell:
goal: goal:
properties: properties:
mappings: mappings:
additionalProperties:
type: object
type: object type: object
required: required:
- mappings - mappings
type: object type: object
result: {} result:
items:
type: object
type: array
required: required:
- goal - goal
title: create_materials参数 title: create_materials参数
@@ -592,7 +602,8 @@ bioyond_cell:
required: required:
- xlsx_path - xlsx_path
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_orders参数 title: create_orders参数
@@ -624,7 +635,8 @@ bioyond_cell:
required: required:
- xlsx_path - xlsx_path
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_orders_v2参数 title: create_orders_v2参数
@@ -665,7 +677,8 @@ bioyond_cell:
- bottle_type - bottle_type
- location_code - location_code
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_sample参数 title: create_sample参数
@@ -718,7 +731,8 @@ bioyond_cell:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: order_list_v2参数 title: order_list_v2参数
@@ -821,7 +835,8 @@ bioyond_cell:
required: required:
- material_obj - material_obj
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: report_material_change参数 title: report_material_change参数
@@ -875,7 +890,8 @@ bioyond_cell:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_continue参数 title: scheduler_continue参数
@@ -896,7 +912,8 @@ bioyond_cell:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_reset参数 title: scheduler_reset参数
@@ -917,7 +934,8 @@ bioyond_cell:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_start参数 title: scheduler_start参数
@@ -1362,7 +1380,8 @@ bioyond_cell:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_start_and_auto_feeding参数 title: scheduler_start_and_auto_feeding参数
@@ -1807,7 +1826,8 @@ bioyond_cell:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_start_and_auto_feeding_v2参数 title: scheduler_start_and_auto_feeding_v2参数
@@ -1828,7 +1848,8 @@ bioyond_cell:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: scheduler_stop参数 title: scheduler_stop参数
@@ -1850,12 +1871,15 @@ bioyond_cell:
properties: properties:
items: items:
items: items:
additionalProperties:
type: string
type: object type: object
type: array type: array
required: required:
- items - items
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: storage_batch_inbound参数 title: storage_batch_inbound参数
@@ -1884,7 +1908,8 @@ bioyond_cell:
- material_id - material_id
- location_id - location_id
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: storage_inbound参数 title: storage_inbound参数
@@ -1905,7 +1930,8 @@ bioyond_cell:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: transfer_1_to_2参数 title: transfer_1_to_2参数
@@ -1946,7 +1972,8 @@ bioyond_cell:
type: integer type: integer
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: transfer_3_to_2参数 title: transfer_3_to_2参数
@@ -1983,7 +2010,8 @@ bioyond_cell:
type: integer type: integer
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: transfer_3_to_2_to_1参数 title: transfer_3_to_2_to_1参数
@@ -2007,10 +2035,11 @@ bioyond_cell:
ip: ip:
type: string type: string
port: port:
type: string type: integer
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: update_push_ip参数 title: update_push_ip参数
@@ -2039,7 +2068,8 @@ bioyond_cell:
required: required:
- order_code - order_code
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: wait_for_order_finish参数 title: wait_for_order_finish参数
@@ -2072,7 +2102,8 @@ bioyond_cell:
required: required:
- order_code - order_code
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: wait_for_order_finish_polling参数 title: wait_for_order_finish_polling参数
@@ -2104,7 +2135,8 @@ bioyond_cell:
type: integer type: integer
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: wait_for_transfer_task参数 title: wait_for_transfer_task参数
@@ -2112,8 +2144,7 @@ bioyond_cell:
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.bioyond_cell.bioyond_cell_workstation:BioyondCellWorkstation module: unilabos.devices.workstation.bioyond_studio.bioyond_cell.bioyond_cell_workstation:BioyondCellWorkstation
status_types: status_types:
device_id: String device_id: ''
material_info: dict
type: python type: python
config_info: [] config_info: []
description: '' description: ''
@@ -2134,11 +2165,7 @@ bioyond_cell:
properties: properties:
device_id: device_id:
type: string type: string
material_info:
type: object
required: required:
- device_id - device_id
- material_info
type: object type: object
registry_type: device
version: 1.0.0 version: 1.0.0

View File

@@ -24,7 +24,8 @@ bioyond_dispensing_station:
required: required:
- data - data
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: brief_step_parameters参数 title: brief_step_parameters参数
@@ -53,7 +54,8 @@ bioyond_dispensing_station:
- report_request - report_request
- used_materials - used_materials
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: process_order_finish_report参数 title: process_order_finish_report参数
@@ -78,7 +80,8 @@ bioyond_dispensing_station:
required: required:
- order_id - order_id
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: project_order_report参数 title: project_order_report参数
@@ -128,7 +131,8 @@ bioyond_dispensing_station:
required: required:
- workflow_id - workflow_id
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: workflow_sample_locations参数 title: workflow_sample_locations参数
@@ -144,12 +148,12 @@ bioyond_dispensing_station:
temperature: temperature temperature: temperature
titration: titration titration: titration
goal_default: goal_default:
delay_time: '600' delay_time: null
hold_m_name: '' hold_m_name: null
liquid_material_name: NMP liquid_material_name: NMP
speed: '400' speed: null
temperature: '40' temperature: null
titration: '' titration: null
handles: handles:
input: input:
- data_key: titration - data_key: titration
@@ -165,20 +169,16 @@ bioyond_dispensing_station:
handler_key: BATCH_CREATE_RESULT handler_key: BATCH_CREATE_RESULT
io_type: sink io_type: sink
label: Complete Batch Create Result JSON (contains order_codes and order_ids) label: Complete Batch Create Result JSON (contains order_codes and order_ids)
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 批量创建90%10%小瓶投料任务。从计算节点接收titration数据,包含物料名称、主称固体质量、滴定固体质量和滴定溶剂体积。返回的return_info中包含order_codes和order_ids列表。 description: 批量创建90%10%小瓶投料任务。从计算节点接收titration数据,包含物料名称、主称固体质量、滴定固体质量和滴定溶剂体积。返回的return_info中包含order_codes和order_ids列表。
properties: properties:
feedback: feedback:
properties: {}
required: []
title: BatchCreate9010VialFeedingTasks_Feedback title: BatchCreate9010VialFeedingTasks_Feedback
type: object
goal: goal:
properties: properties:
delay_time: delay_time:
default: '600'
description: 延迟时间(秒),默认600 description: 延迟时间(秒),默认600
type: string type: string
hold_m_name: hold_m_name:
@@ -189,11 +189,9 @@ bioyond_dispensing_station:
description: 10%物料的液体物料名称,默认为"NMP" description: 10%物料的液体物料名称,默认为"NMP"
type: string type: string
speed: speed:
default: '400'
description: 搅拌速度,默认400 description: 搅拌速度,默认400
type: string type: string
temperature: temperature:
default: '40'
description: 温度(℃),默认40 description: 温度(℃),默认40
type: string type: string
titration: titration:
@@ -202,21 +200,14 @@ bioyond_dispensing_station:
type: string type: string
required: required:
- titration - titration
- hold_m_name
title: BatchCreate9010VialFeedingTasks_Goal title: BatchCreate9010VialFeedingTasks_Goal
type: object type: object
result: result:
properties:
return_info:
description: 批量任务创建结果汇总JSON字符串包含total(总数)、success(成功数)、failed(失败数)、order_codes(任务编码数组)、order_ids(任务ID数组)、details(每个任务的详细信息)
type: string
required:
- return_info
title: BatchCreate9010VialFeedingTasks_Result title: BatchCreate9010VialFeedingTasks_Result
type: object type: string
required: required:
- goal - goal
title: BatchCreate9010VialFeedingTasks title: batch_create_90_10_vial_feeding_tasks参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
batch_create_diamine_solution_tasks: batch_create_diamine_solution_tasks:
@@ -228,11 +219,11 @@ bioyond_dispensing_station:
speed: speed speed: speed
temperature: temperature temperature: temperature
goal_default: goal_default:
delay_time: '600' delay_time: null
liquid_material_name: NMP liquid_material_name: NMP
solutions: '' solutions: null
speed: '400' speed: null
temperature: '20' temperature: null
handles: handles:
input: input:
- data_key: solutions - data_key: solutions
@@ -248,20 +239,16 @@ bioyond_dispensing_station:
handler_key: BATCH_CREATE_RESULT handler_key: BATCH_CREATE_RESULT
io_type: sink io_type: sink
label: Complete Batch Create Result JSON (contains order_codes and order_ids) label: Complete Batch Create Result JSON (contains order_codes and order_ids)
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 批量创建二胺溶液配置任务。自动为多个二胺样品创建溶液配置任务每个任务包含固体物料称量、溶剂添加、搅拌混合等步骤。返回的return_info中包含order_codes和order_ids列表。 description: 批量创建二胺溶液配置任务。自动为多个二胺样品创建溶液配置任务每个任务包含固体物料称量、溶剂添加、搅拌混合等步骤。返回的return_info中包含order_codes和order_ids列表。
properties: properties:
feedback: feedback:
properties: {}
required: []
title: BatchCreateDiamineSolutionTasks_Feedback title: BatchCreateDiamineSolutionTasks_Feedback
type: object
goal: goal:
properties: properties:
delay_time: delay_time:
default: '600'
description: 溶液配置完成后的延迟时间用于充分混合和溶解默认600秒 description: 溶液配置完成后的延迟时间用于充分混合和溶解默认600秒
type: string type: string
liquid_material_name: liquid_material_name:
@@ -275,11 +262,9 @@ bioyond_dispensing_station:
4.5, "solvent_volume": 18}]' 4.5, "solvent_volume": 18}]'
type: string type: string
speed: speed:
default: '400'
description: 搅拌速度rpm用于混合溶液默认400转/分钟 description: 搅拌速度rpm用于混合溶液默认400转/分钟
type: string type: string
temperature: temperature:
default: '20'
description: 配置温度溶液配置过程的目标温度默认20℃室温 description: 配置温度溶液配置过程的目标温度默认20℃室温
type: string type: string
required: required:
@@ -287,17 +272,11 @@ bioyond_dispensing_station:
title: BatchCreateDiamineSolutionTasks_Goal title: BatchCreateDiamineSolutionTasks_Goal
type: object type: object
result: result:
properties:
return_info:
description: 批量任务创建结果汇总JSON字符串包含total(总数)、success(成功数)、failed(失败数)、order_codes(任务编码数组)、order_ids(任务ID数组)、details(每个任务的详细信息)
type: string
required:
- return_info
title: BatchCreateDiamineSolutionTasks_Result title: BatchCreateDiamineSolutionTasks_Result
type: object type: string
required: required:
- goal - goal
title: BatchCreateDiamineSolutionTasks title: batch_create_diamine_solution_tasks参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
compute_experiment_design: compute_experiment_design:
@@ -309,7 +288,7 @@ bioyond_dispensing_station:
wt_percent: wt_percent wt_percent: wt_percent
goal_default: goal_default:
m_tot: '70' m_tot: '70'
ratio: '' ratio: null
titration_percent: '0.03' titration_percent: '0.03'
wt_percent: '0.25' wt_percent: '0.25'
handles: handles:
@@ -338,12 +317,8 @@ bioyond_dispensing_station:
handler_key: feeding_order handler_key: feeding_order
io_type: sink io_type: sink
label: Feeding Order Data From Calculation Node label: Feeding Order Data From Calculation Node
result: placeholder_keys: {}
feeding_order: feeding_order result: {}
return_info: return_info
solutions: solutions
solvents: solvents
titration: titration
schema: schema:
description: 计算实验设计输出solutions/titration/solvents/feeding_order用于后续节点。 description: 计算实验设计输出solutions/titration/solvents/feeding_order用于后续节点。
properties: properties:
@@ -356,7 +331,7 @@ bioyond_dispensing_station:
type: string type: string
ratio: ratio:
description: 组分摩尔比的对象,保持输入顺序,如{"MDA":1,"BTDA":1} description: 组分摩尔比的对象,保持输入顺序,如{"MDA":1,"BTDA":1}
type: string type: object
titration_percent: titration_percent:
default: '0.03' default: '0.03'
description: 滴定比例(10%部分) description: 滴定比例(10%部分)
@@ -371,14 +346,23 @@ bioyond_dispensing_station:
result: result:
properties: properties:
feeding_order: feeding_order:
items: {}
title: Feeding Order
type: array type: array
return_info: return_info:
title: Return Info
type: string type: string
solutions: solutions:
items: {}
title: Solutions
type: array type: array
solvents: solvents:
additionalProperties: true
title: Solvents
type: object type: object
titration: titration:
additionalProperties: true
title: Titration
type: object type: object
required: required:
- solutions - solutions
@@ -386,11 +370,11 @@ bioyond_dispensing_station:
- solvents - solvents
- feeding_order - feeding_order
- return_info - return_info
title: ComputeExperimentDesign_Result title: ComputeExperimentDesignReturn
type: object type: object
required: required:
- goal - goal
title: ComputeExperimentDesign title: compute_experiment_design参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
create_90_10_vial_feeding_task: create_90_10_vial_feeding_task:
@@ -444,17 +428,18 @@ bioyond_dispensing_station:
speed: '' speed: ''
temperature: '' temperature: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: DispenStationVialFeed_Feedback title: DispenStationVialFeed_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
delay_time: delay_time:
type: string type: string
@@ -502,38 +487,13 @@ bioyond_dispensing_station:
type: string type: string
temperature: temperature:
type: string type: string
required:
- order_name
- percent_90_1_assign_material_name
- percent_90_1_target_weigh
- percent_90_2_assign_material_name
- percent_90_2_target_weigh
- percent_90_3_assign_material_name
- percent_90_3_target_weigh
- percent_10_1_assign_material_name
- percent_10_1_target_weigh
- percent_10_1_volume
- percent_10_1_liquid_material_name
- percent_10_2_assign_material_name
- percent_10_2_target_weigh
- percent_10_2_volume
- percent_10_2_liquid_material_name
- percent_10_3_assign_material_name
- percent_10_3_target_weigh
- percent_10_3_volume
- percent_10_3_liquid_material_name
- speed
- temperature
- delay_time
- hold_m_name
title: DispenStationVialFeed_Goal title: DispenStationVialFeed_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: DispenStationVialFeed_Result title: DispenStationVialFeed_Result
type: object type: object
required: required:
@@ -564,17 +524,18 @@ bioyond_dispensing_station:
temperature: '' temperature: ''
volume: '' volume: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: DispenStationSolnPrep_Feedback title: DispenStationSolnPrep_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
delay_time: delay_time:
type: string type: string
@@ -594,24 +555,13 @@ bioyond_dispensing_station:
type: string type: string
volume: volume:
type: string type: string
required:
- order_name
- material_name
- target_weigh
- volume
- liquid_material_name
- speed
- temperature
- delay_time
- hold_m_name
title: DispenStationSolnPrep_Goal title: DispenStationSolnPrep_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: DispenStationSolnPrep_Result title: DispenStationSolnPrep_Result
type: object type: object
required: required:
@@ -624,8 +574,8 @@ bioyond_dispensing_station:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 启动调度器 - 启动Bioyond配液站的任务调度器开始执行队列中的任务 description: 启动调度器 - 启动Bioyond配液站的任务调度器开始执行队列中的任务
properties: properties:
@@ -635,12 +585,6 @@ bioyond_dispensing_station:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 调度器启动结果成功返回1失败返回0
type: integer
required:
- return_info
title: scheduler_start结果 title: scheduler_start结果
type: object type: object
required: required:
@@ -654,8 +598,8 @@ bioyond_dispensing_station:
target_device_id: target_device_id target_device_id: target_device_id
transfer_groups: transfer_groups transfer_groups: transfer_groups
goal_default: goal_default:
target_device_id: '' target_device_id: null
transfer_groups: '' transfer_groups: null
handles: {} handles: {}
placeholder_keys: placeholder_keys:
target_device_id: unilabos_devices target_device_id: unilabos_devices
@@ -671,32 +615,13 @@ bioyond_dispensing_station:
type: string type: string
transfer_groups: transfer_groups:
description: 转移任务组列表,每组包含物料名称、目标堆栈和目标库位,可以添加多组 description: 转移任务组列表,每组包含物料名称、目标堆栈和目标库位,可以添加多组
items:
properties:
materials:
description: 物料名称手动输入系统将通过RPC查询验证
type: string
target_sites:
description: 目标库位(手动输入,如"A01"
type: string
target_stack:
description: 目标堆栈名称(从列表选择)
enum:
- 堆栈1左
- 堆栈1右
- 站内试剂存放堆栈
type: string
required:
- materials
- target_stack
- target_sites
type: object
type: array type: array
required: required:
- target_device_id - target_device_id
- transfer_groups - transfer_groups
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: transfer_materials_to_reaction_station参数 title: transfer_materials_to_reaction_station参数
@@ -709,9 +634,9 @@ bioyond_dispensing_station:
check_interval: check_interval check_interval: check_interval
timeout: timeout timeout: timeout
goal_default: goal_default:
batch_create_result: '' batch_create_result: null
check_interval: '10' check_interval: 10
timeout: '7200' timeout: 7200
handles: handles:
input: input:
- data_key: batch_create_result - data_key: batch_create_result
@@ -727,47 +652,35 @@ bioyond_dispensing_station:
handler_key: batch_reports_result handler_key: batch_reports_result
io_type: sink io_type: sink
label: Batch Order Completion Reports label: Batch Order Completion Reports
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 同时等待多个任务完成并获取所有实验报告。从上游batch_create任务接收包含order_codes和order_ids的结果对象并行监控所有任务状态并返回每个任务的报告。 description: 同时等待多个任务完成并获取所有实验报告。从上游batch_create任务接收包含order_codes和order_ids的结果对象并行监控所有任务状态并返回每个任务的报告。
properties: properties:
feedback: feedback:
properties: {}
required: []
title: WaitForMultipleOrdersAndGetReports_Feedback title: WaitForMultipleOrdersAndGetReports_Feedback
type: object
goal: goal:
properties: properties:
batch_create_result: batch_create_result:
description: 批量创建任务的返回结果对象包含order_codes和order_ids数组。从上游batch_create节点通过handle传递 description: 批量创建任务的返回结果对象包含order_codes和order_ids数组。从上游batch_create节点通过handle传递
type: string type: string
check_interval: check_interval:
default: '10' default: 10
description: 检查任务状态的时间间隔默认每10秒检查一次所有待完成任务 description: 检查任务状态的时间间隔默认每10秒检查一次所有待完成任务
type: string type: integer
timeout: timeout:
default: '7200' default: 7200
description: 等待超时时间默认7200秒2小时。超过此时间未完成的任务将标记为timeout description: 等待超时时间默认7200秒2小时。超过此时间未完成的任务将标记为timeout
type: string type: integer
required: required: []
- batch_create_result
title: WaitForMultipleOrdersAndGetReports_Goal title: WaitForMultipleOrdersAndGetReports_Goal
type: object type: object
result: result:
properties:
return_info:
description: 'JSON格式的批量任务完成信息包含: total(总数), completed(成功数), timeout(超时数),
error(错误数), elapsed_time(总耗时), reports(报告数组每个元素包含order_code,
order_id, status, completion_status, report, elapsed_time)'
type: string
required:
- return_info
title: WaitForMultipleOrdersAndGetReports_Result title: WaitForMultipleOrdersAndGetReports_Result
type: object type: object
required: required:
- goal - goal
title: WaitForMultipleOrdersAndGetReports title: wait_for_multiple_orders_and_get_reports参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.dispensing_station.dispensing_station:BioyondDispensingStation module: unilabos.devices.workstation.bioyond_studio.dispensing_station.dispensing_station:BioyondDispensingStation

View File

@@ -1,81 +0,0 @@
camera:
category:
- camera
class:
action_value_mappings:
auto-destroy_node:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: 用于安全地关闭摄像头设备释放摄像头资源停止视频采集和发布服务。调用此函数将清理OpenCV摄像头连接并销毁ROS2节点。
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: destroy_node参数
type: object
type: UniLabJsonCommand
auto-timer_callback:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: 定时器回调函数的参数schema。此函数负责定期采集摄像头视频帧将OpenCV格式的图像转换为ROS Image消息格式并发布到指定的视频话题。默认以10Hz频率执行确保视频流的连续性和实时性。
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: timer_callback参数
type: object
type: UniLabJsonCommand
module: unilabos.ros.nodes.presets.camera:VideoPublisher
status_types: {}
type: ros2
config_info: []
description: VideoPublisher摄像头设备节点用于实时视频采集和流媒体发布。该设备通过OpenCV连接本地摄像头如USB摄像头、内置摄像头等定时采集视频帧并将其转换为ROS2的sensor_msgs/Image消息格式发布到视频话题。主要用于实验室自动化系统中的视觉监控、图像分析、实时观察等应用场景。支持可配置的摄像头索引、发布频率等参数。
handles: []
icon: ''
init_param_schema:
config:
properties:
camera_index:
default: 0
type: string
device_id:
default: video_publisher
type: string
device_uuid:
default: ''
type: string
period:
default: 0.1
type: number
registry_name:
default: ''
type: string
resource_tracker:
type: object
required: []
type: object
data:
properties: {}
required: []
type: object
version: 1.0.0

View File

@@ -18,7 +18,7 @@ cameracontroller_device:
goal: goal:
properties: properties:
config: config:
type: string type: object
required: [] required: []
type: object type: object
result: {} result: {}
@@ -42,7 +42,8 @@ cameracontroller_device:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: stop参数 title: stop参数
@@ -50,7 +51,7 @@ cameracontroller_device:
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.cameraSII.cameraUSB:CameraController module: unilabos.devices.cameraSII.cameraUSB:CameraController
status_types: status_types:
status: dict status: Dict[str, Any]
type: python type: python
config_info: [] config_info: []
description: Uni-Lab-OS 摄像头驱动Linux USB 摄像头版,无 PTZ description: Uni-Lab-OS 摄像头驱动Linux USB 摄像头版,无 PTZ
@@ -103,5 +104,4 @@ cameracontroller_device:
required: required:
- status - status
type: object type: object
registry_type: device
version: 1.0.0 version: 1.0.0

View File

@@ -141,30 +141,26 @@ hplc.agilent:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -175,7 +171,6 @@ hplc.agilent:
module: unilabos.devices.hplc.AgilentHPLC:HPLCDriver module: unilabos.devices.hplc.AgilentHPLC:HPLCDriver
status_types: status_types:
could_run: bool could_run: bool
data_file: String
device_status: str device_status: str
driver_init_ok: bool driver_init_ok: bool
finish_status: str finish_status: str
@@ -199,10 +194,6 @@ hplc.agilent:
properties: properties:
could_run: could_run:
type: boolean type: boolean
data_file:
items:
type: string
type: array
device_status: device_status:
type: string type: string
driver_init_ok: driver_init_ok:
@@ -216,14 +207,13 @@ hplc.agilent:
success: success:
type: boolean type: boolean
required: required:
- status_text
- device_status
- could_run - could_run
- device_status
- driver_init_ok - driver_init_ok
- is_running
- success
- finish_status - finish_status
- data_file - is_running
- status_text
- success
type: object type: object
version: 1.0.0 version: 1.0.0
hplc.agilent-zhida: hplc.agilent-zhida:
@@ -236,26 +226,25 @@ hplc.agilent-zhida:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -315,21 +304,18 @@ hplc.agilent-zhida:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -341,35 +327,35 @@ hplc.agilent-zhida:
feedback: {} feedback: {}
goal: goal:
string: string string: string
text: text
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -407,7 +393,7 @@ hplc.agilent-zhida:
status: status:
type: object type: object
required: required:
- status
- methods - methods
- status
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -120,42 +120,41 @@ raman.home_made:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
raman_cmd: raman_cmd:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:

View File

@@ -19,7 +19,8 @@ separator.chinwe:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: connect参数 title: connect参数
@@ -65,135 +66,145 @@ separator.chinwe:
required: required:
- command_dict - command_dict
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: execute_command_from_outer参数 title: execute_command_from_outer参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
motor_rotate_quarter: motor_rotate_quarter:
feedback: {}
goal: goal:
direction: 顺时针 direction: 顺时针
motor_id: 4 motor_id: 4
speed: 60 speed: 60
goal_default:
direction: 顺时针
motor_id: null
speed: 60
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 电机旋转 1/4 圈 description: 电机旋转 1/4 圈
properties: properties:
feedback: {}
goal: goal:
properties: properties:
direction: direction:
default: 顺时针 default: 顺时针
description: 旋转方向 description: 旋转方向
enum:
- 顺时针
- 逆时针
type: string type: string
motor_id: motor_id:
default: '4'
description: 选择电机 (4:搅拌, 5:旋钮) description: 选择电机 (4:搅拌, 5:旋钮)
enum: type: integer
- '4'
- '5'
type: string
speed: speed:
default: 60 default: 60
description: 速度 (RPM) description: 速度 (RPM)
type: integer type: integer
required: required:
- motor_id - motor_id
- speed
type: object type: object
result: {}
required:
- goal
title: motor_rotate_quarter参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
motor_run_continuous: motor_run_continuous:
feedback: {}
goal: goal:
direction: 顺时针 direction: 顺时针
motor_id: 4 motor_id: 4
speed: 60 speed: 60
goal_default:
direction: 顺时针
motor_id: null
speed: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 电机一直旋转 (速度模式) description: 电机一直旋转 (速度模式)
properties: properties:
feedback: {}
goal: goal:
properties: properties:
direction: direction:
default: 顺时针 default: 顺时针
description: 旋转方向 description: 旋转方向
enum:
- 顺时针
- 逆时针
type: string type: string
motor_id: motor_id:
default: '4'
description: 选择电机 (4:搅拌, 5:旋钮) description: 选择电机 (4:搅拌, 5:旋钮)
enum: type: integer
- '4'
- '5'
type: string
speed: speed:
default: 60
description: 速度 (RPM) description: 速度 (RPM)
type: integer type: integer
required: required:
- motor_id - motor_id
- speed - speed
type: object type: object
result: {}
required:
- goal
title: motor_run_continuous参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
motor_stop: motor_stop:
feedback: {}
goal: goal:
motor_id: 4 motor_id: 4
goal_default:
motor_id: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 停止指定步进电机 description: 停止指定步进电机
properties: properties:
feedback: {}
goal: goal:
properties: properties:
motor_id: motor_id:
default: '4'
description: 选择电机 description: 选择电机
enum:
- '4'
- '5'
title: '注: 4=搅拌, 5=旋钮' title: '注: 4=搅拌, 5=旋钮'
type: string type: integer
required: required:
- motor_id - motor_id
type: object type: object
result: {}
required:
- goal
title: motor_stop参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pump_aspirate: pump_aspirate:
feedback: {}
goal: goal:
pump_id: 1 pump_id: 1
valve_port: 1 valve_port: 1
volume: 1000 volume: 1000
goal_default:
pump_id: null
valve_port: null
volume: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 注射泵吸液 description: 注射泵吸液
properties: properties:
feedback: {}
goal: goal:
properties: properties:
pump_id: pump_id:
default: '1'
description: 选择泵 description: 选择泵
enum: type: integer
- '1'
- '2'
- '3'
type: string
valve_port: valve_port:
default: '1'
description: 阀门端口 description: 阀门端口
enum: type: integer
- '1'
- '2'
- '3'
- '4'
- '5'
- '6'
- '7'
- '8'
type: string
volume: volume:
default: 1000
description: 吸液步数 description: 吸液步数
type: integer type: integer
required: required:
@@ -201,41 +212,38 @@ separator.chinwe:
- volume - volume
- valve_port - valve_port
type: object type: object
result: {}
required:
- goal
title: pump_aspirate参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pump_dispense: pump_dispense:
feedback: {}
goal: goal:
pump_id: 1 pump_id: 1
valve_port: 1 valve_port: 1
volume: 1000 volume: 1000
goal_default:
pump_id: null
valve_port: null
volume: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 注射泵排液 description: 注射泵排液
properties: properties:
feedback: {}
goal: goal:
properties: properties:
pump_id: pump_id:
default: '1'
description: 选择泵 description: 选择泵
enum: type: integer
- '1'
- '2'
- '3'
type: string
valve_port: valve_port:
default: '1'
description: 阀门端口 description: 阀门端口
enum: type: integer
- '1'
- '2'
- '3'
- '4'
- '5'
- '6'
- '7'
- '8'
type: string
volume: volume:
default: 1000
description: 排液步数 description: 排液步数
type: integer type: integer
required: required:
@@ -243,121 +251,152 @@ separator.chinwe:
- volume - volume
- valve_port - valve_port
type: object type: object
result: {}
required:
- goal
title: pump_dispense参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pump_initialize: pump_initialize:
feedback: {}
goal: goal:
drain_port: 0 drain_port: 0
output_port: 0 output_port: 0
pump_id: 1 pump_id: 1
speed: 10 speed: 10
goal_default:
drain_port: 0
output_port: 0
pump_id: null
speed: 10
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 初始化指定注射泵 description: 初始化指定注射泵
properties: properties:
feedback: {}
goal: goal:
properties: properties:
drain_port: drain_port:
default: 0 default: 0
description: 排液口索引 description: 排液口索引
type: integer type: string
output_port: output_port:
default: 0 default: 0
description: 输出口索引 description: 输出口索引
type: integer
pump_id:
default: '1'
description: 选择泵
enum:
- '1'
- '2'
- '3'
title: '注: 1号泵, 2号泵, 3号泵'
type: string type: string
pump_id:
description: 选择泵
title: '注: 1号泵, 2号泵, 3号泵'
type: integer
speed: speed:
default: 10 default: 10
description: 运动速度 description: 运动速度
type: integer type: string
required: required:
- pump_id - pump_id
type: object type: object
result: {}
required:
- goal
title: pump_initialize参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pump_valve: pump_valve:
feedback: {}
goal: goal:
port: 1 port: 1
pump_id: 1 pump_id: 1
goal_default:
port: null
pump_id: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 切换指定泵的阀门端口 description: 切换指定泵的阀门端口
properties: properties:
feedback: {}
goal: goal:
properties: properties:
port: port:
default: '1'
description: 阀门端口号 (1-8) description: 阀门端口号 (1-8)
enum: type: integer
- '1'
- '2'
- '3'
- '4'
- '5'
- '6'
- '7'
- '8'
type: string
pump_id: pump_id:
default: '1'
description: 选择泵 description: 选择泵
enum: type: integer
- '1'
- '2'
- '3'
type: string
required: required:
- pump_id - pump_id
- port - port
type: object type: object
result: {}
required:
- goal
title: pump_valve参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
wait_sensor_level: wait_sensor_level:
feedback: {}
goal: goal:
target_state: 有液 target_state: 有液
timeout: 30 timeout: 30
goal_default:
target_state: 有液
timeout: 30
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 等待传感器液位条件 description: 等待传感器液位条件
properties: properties:
feedback: {}
goal: goal:
properties: properties:
target_state: target_state:
default: 有液 default: 有液
description: 目标液位状态 description: 目标液位状态
enum:
- 有液
- 无液
type: string type: string
timeout: timeout:
default: 30 default: 30
description: 超时时间 (秒) description: 超时时间 (秒)
type: integer type: integer
required: required: []
- target_state
type: object type: object
result:
type: boolean
required:
- goal
title: wait_sensor_level参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
wait_time: wait_time:
feedback: {}
goal: goal:
duration: 10 duration: 10
goal_default:
duration: null
handles: {} handles: {}
placeholder_keys: {}
result: {}
schema: schema:
description: 等待指定时间 description: 等待指定时间
properties: properties:
feedback: {}
goal: goal:
properties: properties:
duration: duration:
default: 10
description: 等待时间 (秒) description: 等待时间 (秒)
type: integer type: integer
required: required:
- duration - duration
type: object type: object
result:
type: boolean
required:
- goal
title: wait_time参数
type: object
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.separator.chinwe:ChinweDevice module: unilabos.devices.separator.chinwe:ChinweDevice
status_types: status_types:
@@ -406,8 +445,8 @@ separator.chinwe:
sensor_rssi: sensor_rssi:
type: integer type: integer
required: required:
- is_connected
- sensor_level - sensor_level
- sensor_rssi - sensor_rssi
- is_connected
type: object type: object
version: 2.1.0 version: 2.1.0

View File

@@ -64,7 +64,8 @@ coincellassemblyworkstation_device:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: fun_wuliao_test参数 title: fun_wuliao_test参数
@@ -109,7 +110,8 @@ coincellassemblyworkstation_device:
- elec_num - elec_num
- elec_use_num - elec_use_num
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: func_allpack_cmd参数 title: func_allpack_cmd参数
@@ -220,7 +222,8 @@ coincellassemblyworkstation_device:
- elec_num - elec_num
- elec_use_num - elec_use_num
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: func_allpack_cmd_simp参数 title: func_allpack_cmd_simp参数
@@ -309,7 +312,8 @@ coincellassemblyworkstation_device:
type: boolean type: boolean
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: func_pack_device_init_auto_start_combined参数 title: func_pack_device_init_auto_start_combined参数
@@ -351,7 +355,8 @@ coincellassemblyworkstation_device:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: func_pack_device_stop参数 title: func_pack_device_stop参数
@@ -376,7 +381,8 @@ coincellassemblyworkstation_device:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: func_pack_get_msg_cmd参数 title: func_pack_get_msg_cmd参数
@@ -430,7 +436,8 @@ coincellassemblyworkstation_device:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: func_pack_send_finished_cmd参数 title: func_pack_send_finished_cmd参数
@@ -467,7 +474,8 @@ coincellassemblyworkstation_device:
- assembly_type - assembly_type
- assembly_pressure - assembly_pressure
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: func_pack_send_msg_cmd参数 title: func_pack_send_msg_cmd参数
@@ -611,7 +619,8 @@ coincellassemblyworkstation_device:
- elec_num - elec_num
- elec_use_num - elec_use_num
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: func_sendbottle_allpack_multi参数 title: func_sendbottle_allpack_multi参数
@@ -663,31 +672,6 @@ coincellassemblyworkstation_device:
title: modify_deck_name参数 title: modify_deck_name参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: object
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-qiming_coin_cell_code: auto-qiming_coin_cell_code:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -735,7 +719,8 @@ coincellassemblyworkstation_device:
required: required:
- fujipian_panshu - fujipian_panshu
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: qiming_coin_cell_code参数 title: qiming_coin_cell_code参数
@@ -826,25 +811,24 @@ coincellassemblyworkstation_device:
sys_status: sys_status:
type: string type: string
required: required:
- sys_status
- sys_mode
- request_rec_msg_status
- request_send_msg_status
- data_assembly_coin_cell_num - data_assembly_coin_cell_num
- data_assembly_pressure
- data_assembly_time - data_assembly_time
- data_open_circuit_voltage
- data_axis_x_pos - data_axis_x_pos
- data_axis_y_pos - data_axis_y_pos
- data_axis_z_pos - data_axis_z_pos
- data_pole_weight
- data_assembly_pressure
- data_electrolyte_volume
- data_coin_num
- data_coin_cell_code - data_coin_cell_code
- data_coin_num
- data_electrolyte_code - data_electrolyte_code
- data_glove_box_pressure - data_electrolyte_volume
- data_glove_box_o2_content - data_glove_box_o2_content
- data_glove_box_pressure
- data_glove_box_water_content - data_glove_box_water_content
- data_open_circuit_voltage
- data_pole_weight
- request_rec_msg_status
- request_send_msg_status
- sys_mode
- sys_status
type: object type: object
registry_type: device
version: 1.0.0 version: 1.0.0

View File

@@ -50,26 +50,25 @@ gas_source.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -82,26 +81,25 @@ gas_source.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -116,32 +114,31 @@ gas_source.mock:
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -232,26 +229,25 @@ vacuum_pump.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -264,26 +260,25 @@ vacuum_pump.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -298,32 +293,31 @@ vacuum_pump.mock:
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:

View File

@@ -5,7 +5,7 @@ hotel.thermo_orbitor_rs2_hotel:
action_value_mappings: {} action_value_mappings: {}
module: unilabos.devices.resource_container.container:HotelContainer module: unilabos.devices.resource_container.container:HotelContainer
status_types: status_types:
rotation: String rotation: ''
type: python type: python
config_info: [] config_info: []
description: Thermo Orbitor RS2 Hotel容器设备用于实验室样品的存储和管理。该设备通过HotelContainer类实现容器的旋转控制和状态监控主要用于存储实验样品、试剂瓶或其他实验器具支持旋转功能以便于样品的自动化存取。适用于需要有序存储和快速访问大量样品的实验室自动化场景。 description: Thermo Orbitor RS2 Hotel容器设备用于实验室样品的存储和管理。该设备通过HotelContainer类实现容器的旋转控制和状态监控主要用于存储实验样品、试剂瓶或其他实验器具支持旋转功能以便于样品的自动化存取。适用于需要有序存储和快速访问大量样品的实验室自动化场景。

View File

@@ -22,7 +22,8 @@ xyz_stepper_controller:
required: required:
- degrees - degrees
type: object type: object
result: {} result:
type: integer
required: required:
- goal - goal
title: degrees_to_steps参数 title: degrees_to_steps参数
@@ -47,7 +48,8 @@ xyz_stepper_controller:
required: required:
- axis - axis
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: emergency_stop参数 title: emergency_stop参数
@@ -72,7 +74,10 @@ xyz_stepper_controller:
type: boolean type: boolean
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: enable_all_axes参数 title: enable_all_axes参数
@@ -101,7 +106,8 @@ xyz_stepper_controller:
required: required:
- axis - axis
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: enable_motor参数 title: enable_motor参数
@@ -122,7 +128,10 @@ xyz_stepper_controller:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: home_all_axes参数 title: home_all_axes参数
@@ -147,7 +156,8 @@ xyz_stepper_controller:
required: required:
- axis - axis
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: home_axis参数 title: home_axis参数
@@ -188,7 +198,8 @@ xyz_stepper_controller:
- axis - axis
- position - position
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: move_to_position参数 title: move_to_position参数
@@ -229,7 +240,8 @@ xyz_stepper_controller:
- axis - axis
- degrees - degrees
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: move_to_position_degrees参数 title: move_to_position_degrees参数
@@ -270,7 +282,8 @@ xyz_stepper_controller:
- axis - axis
- revolutions - revolutions
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: move_to_position_revolutions参数 title: move_to_position_revolutions参数
@@ -301,14 +314,17 @@ xyz_stepper_controller:
default: 5000 default: 5000
type: integer type: integer
x: x:
type: string type: integer
y: y:
type: string type: integer
z: z:
type: string type: integer
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: move_xyz参数 title: move_xyz参数
@@ -339,14 +355,17 @@ xyz_stepper_controller:
default: 5000 default: 5000
type: integer type: integer
x_deg: x_deg:
type: string type: number
y_deg: y_deg:
type: string type: number
z_deg: z_deg:
type: string type: number
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: move_xyz_degrees参数 title: move_xyz_degrees参数
@@ -377,14 +396,17 @@ xyz_stepper_controller:
default: 5000 default: 5000
type: integer type: integer
x_rev: x_rev:
type: string type: number
y_rev: y_rev:
type: string type: number
z_rev: z_rev:
type: string type: number
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: move_xyz_revolutions参数 title: move_xyz_revolutions参数
@@ -409,7 +431,8 @@ xyz_stepper_controller:
required: required:
- revolutions - revolutions
type: object type: object
result: {} result:
type: integer
required: required:
- goal - goal
title: revolutions_to_steps参数 title: revolutions_to_steps参数
@@ -442,7 +465,8 @@ xyz_stepper_controller:
- axis - axis
- speed - speed
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: set_speed_mode参数 title: set_speed_mode参数
@@ -467,7 +491,8 @@ xyz_stepper_controller:
required: required:
- steps - steps
type: object type: object
result: {} result:
type: number
required: required:
- goal - goal
title: steps_to_degrees参数 title: steps_to_degrees参数
@@ -492,7 +517,8 @@ xyz_stepper_controller:
required: required:
- steps - steps
type: object type: object
result: {} result:
type: number
required: required:
- goal - goal
title: steps_to_revolutions参数 title: steps_to_revolutions参数
@@ -513,7 +539,10 @@ xyz_stepper_controller:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
additionalProperties:
type: boolean
type: object
required: required:
- goal - goal
title: stop_all_axes参数 title: stop_all_axes参数
@@ -542,7 +571,8 @@ xyz_stepper_controller:
required: required:
- axis - axis
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: wait_for_completion参数 title: wait_for_completion参数
@@ -550,8 +580,7 @@ xyz_stepper_controller:
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.liquid_handling.laiyu.drivers.xyz_stepper_driver:XYZStepperController module: unilabos.devices.liquid_handling.laiyu.drivers.xyz_stepper_driver:XYZStepperController
status_types: status_types:
all_positions: dict all_positions: Dict[MotorAxis, MotorPosition]
motor_status: unilabos.devices.liquid_handling.laiyu.drivers.xyz_stepper_driver:MotorPosition
type: python type: python
config_info: [] config_info: []
description: 新XYZ控制器 description: 新XYZ控制器
@@ -574,12 +603,10 @@ xyz_stepper_controller:
data: data:
properties: properties:
all_positions: all_positions:
type: object additionalProperties:
motor_status: type: object
type: object type: object
required: required:
- motor_status
- all_positions - all_positions
type: object type: object
registry_type: device
version: 1.0.0 version: 1.0.0

File diff suppressed because it is too large Load Diff

View File

@@ -5,31 +5,6 @@ neware_battery_test_system:
- battery_test - battery_test
class: class:
action_value_mappings: action_value_mappings:
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: string
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-print_status_summary: auto-print_status_summary:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -66,7 +41,8 @@ neware_battery_test_system:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: boolean
required: required:
- goal - goal
title: test_connection参数 title: test_connection参数
@@ -77,9 +53,8 @@ neware_battery_test_system:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
success: success
schema: schema:
description: 调试方法:显示所有资源的实际名称 description: 调试方法:显示所有资源的实际名称
properties: properties:
@@ -89,19 +64,10 @@ neware_battery_test_system:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 资源调试信息
type: string
success:
description: 是否成功
type: boolean
required:
- return_info
- success
type: object type: object
required: required:
- goal - goal
title: debug_resource_names参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
export_status_json: export_status_json:
@@ -111,9 +77,8 @@ neware_battery_test_system:
goal_default: goal_default:
filepath: bts_status.json filepath: bts_status.json
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
success: success
schema: schema:
description: 导出当前状态数据到JSON文件 description: 导出当前状态数据到JSON文件
properties: properties:
@@ -127,19 +92,10 @@ neware_battery_test_system:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 导出操作结果信息
type: string
success:
description: 导出是否成功
type: boolean
required:
- return_info
- success
type: object type: object
required: required:
- goal - goal
title: export_status_json参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
get_device_summary: get_device_summary:
@@ -181,10 +137,8 @@ neware_battery_test_system:
goal_default: goal_default:
plate_num: null plate_num: null
handles: {} handles: {}
result: placeholder_keys: {}
plate_data: plate_data result: {}
return_info: return_info
success: success
schema: schema:
description: 获取指定盘或所有盘的状态信息 description: 获取指定盘或所有盘的状态信息
properties: properties:
@@ -193,29 +147,14 @@ neware_battery_test_system:
properties: properties:
plate_num: plate_num:
description: 盘号 (1 或 2)如果为null则返回所有盘的状态 description: 盘号 (1 或 2)如果为null则返回所有盘的状态
maximum: 2
minimum: 1
type: integer type: integer
required: [] required: []
type: object type: object
result: result:
properties:
plate_data:
description: 盘状态数据(单盘或所有盘)
type: object
return_info:
description: 操作结果信息
type: string
success:
description: 查询是否成功
type: boolean
required:
- return_info
- success
- plate_data
type: object type: object
required: required:
- goal - goal
title: get_plate_status参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
print_status_summary_action: print_status_summary_action:
@@ -223,9 +162,8 @@ neware_battery_test_system:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
success: success
schema: schema:
description: 打印通道状态摘要信息到控制台 description: 打印通道状态摘要信息到控制台
properties: properties:
@@ -235,28 +173,21 @@ neware_battery_test_system:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 打印操作结果信息
type: string
success:
description: 打印是否成功
type: boolean
required:
- return_info
- success
type: object type: object
required: required:
- goal - goal
title: print_status_summary_action参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
query_plate_action: query_plate_action:
feedback: {} feedback: {}
goal: goal:
string: plate_id plate_id: plate_id
string: string
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info return_info: return_info
success: success success: success
@@ -264,27 +195,23 @@ neware_battery_test_system:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -298,13 +225,11 @@ neware_battery_test_system:
csv_path: string csv_path: string
output_dir: string output_dir: string
goal_default: goal_default:
csv_path: '' csv_path: null
output_dir: . output_dir: .
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
submitted_count: submitted_count
success: success
schema: schema:
description: 从CSV文件批量提交Neware测试任务 description: 从CSV文件批量提交Neware测试任务
properties: properties:
@@ -315,31 +240,17 @@ neware_battery_test_system:
description: 输入CSV文件的绝对路径 description: 输入CSV文件的绝对路径
type: string type: string
output_dir: output_dir:
default: .
description: 输出目录用于存储XML和备份文件默认当前目录 description: 输出目录用于存储XML和备份文件默认当前目录
type: string type: string
required: required:
- csv_path - csv_path
type: object type: object
result: result:
properties:
return_info:
description: 执行结果详细信息
type: string
submitted_count:
description: 成功提交的任务数量
type: integer
success:
description: 是否成功
type: boolean
total_count:
description: CSV文件中的总行数
type: integer
required:
- return_info
- success
type: object type: object
required: required:
- goal - goal
title: submit_from_csv参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
test_connection_action: test_connection_action:
@@ -347,9 +258,8 @@ neware_battery_test_system:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
success: success
schema: schema:
description: 测试与电池测试系统的TCP连接 description: 测试与电池测试系统的TCP连接
properties: properties:
@@ -359,19 +269,10 @@ neware_battery_test_system:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 连接测试结果信息
type: string
success:
description: 连接测试是否成功
type: boolean
required:
- return_info
- success
type: object type: object
required: required:
- goal - goal
title: test_connection_action参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
upload_backup_to_oss: upload_backup_to_oss:
@@ -392,12 +293,8 @@ neware_battery_test_system:
handler_key: uploaded_files handler_key: uploaded_files
io_type: sink io_type: sink
label: Uploaded Files (with standard flow info) label: Uploaded Files (with standard flow info)
result: placeholder_keys: {}
failed_files: failed_files result: {}
return_info: return_info
success: success
total_count: total_count
uploaded_count: uploaded_count
schema: schema:
description: 上传备份文件到阿里云OSS description: 上传备份文件到阿里云OSS
properties: properties:
@@ -417,65 +314,17 @@ neware_battery_test_system:
required: [] required: []
type: object type: object
result: result:
properties:
failed_files:
description: 上传失败的文件名列表
items:
type: string
type: array
return_info:
description: 上传操作结果信息
type: string
success:
description: 上传是否成功
type: boolean
total_count:
description: 总文件数
type: integer
uploaded_count:
description: 成功上传的文件数
type: integer
uploaded_files:
description: 成功上传的文件详情列表
items:
properties:
Battery_Code:
description: 电池编码
type: string
Electrolyte_Code:
description: 电解液编码
type: string
filename:
description: 文件名
type: string
url:
description: OSS下载链接
type: string
required:
- filename
- url
- Battery_Code
- Electrolyte_Code
type: object
type: array
required:
- return_info
- success
- uploaded_count
- total_count
- failed_files
- uploaded_files
type: object type: object
required: required:
- goal - goal
title: upload_backup_to_oss参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.neware_battery_test_system.neware_battery_test_system:NewareBatteryTestSystem module: unilabos.devices.neware_battery_test_system.neware_battery_test_system:NewareBatteryTestSystem
status_types: status_types:
channel_status: dict channel_status: Dict[int, Dict]
connection_info: dict connection_info: Dict[str, str]
device_summary: dict device_summary: dict
plate_status: dict
status: str status: str
total_channels: int total_channels: int
type: python type: python
@@ -517,23 +366,24 @@ neware_battery_test_system:
data: data:
properties: properties:
channel_status: channel_status:
additionalProperties:
type: object
type: object type: object
connection_info: connection_info:
additionalProperties:
type: string
type: object type: object
device_summary: device_summary:
type: object type: object
plate_status:
type: object
status: status:
type: string type: string
total_channels: total_channels:
type: integer type: integer
required: required:
- status
- channel_status - channel_status
- connection_info - connection_info
- total_channels
- plate_status
- device_summary - device_summary
- status
- total_channels
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -142,8 +142,7 @@ opcua_example:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.device_comms.opcua_client.client:OpcUaClient module: unilabos.device_comms.opcua_client.client:OpcUaClient
status_types: status_types: {}
node_value: String
type: python type: python
config_info: [] config_info: []
description: null description: null
@@ -167,10 +166,7 @@ opcua_example:
- url - url
type: object type: object
data: data:
properties: properties: {}
node_value: required: []
type: string
required:
- node_value
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -80,7 +80,8 @@ opsky_ATR30007:
type: string type: string
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: run_once参数 title: run_once参数

View File

@@ -100,42 +100,41 @@ rotavap.one:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
set_timer: set_timer:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -250,9 +249,13 @@ separator.homemade:
feedback: feedback:
status: status status: status
goal: goal:
event: event
settling_time: settling_time settling_time: settling_time
stir_speed: stir_speed stir_speed: stir_speed
stir_time: stir_time, stir_time: stir_time
time: time
time_spec: time_spec
vessel: vessel
goal_default: goal_default:
event: '' event: ''
settling_time: '' settling_time: ''
@@ -281,34 +284,42 @@ separator.homemade:
sample_id: '' sample_id: ''
type: '' type: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
message: message
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: Stir_Feedback title: Stir_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
event: event:
type: string type: string
settling_time: settling_time:
type: string type: string
stir_speed: stir_speed:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
stir_time: stir_time:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
time: time:
type: string type: string
time_spec: time_spec:
type: string type: string
vessel: vessel:
additionalProperties: false
properties: properties:
category: category:
type: string type: string
@@ -327,16 +338,26 @@ separator.homemade:
parent: parent:
type: string type: string
pose: pose:
additionalProperties: false
properties: properties:
orientation: orientation:
additionalProperties: false
properties: properties:
w: w:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -346,12 +367,19 @@ separator.homemade:
title: orientation title: orientation
type: object type: object
position: position:
additionalProperties: false
properties: properties:
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -381,17 +409,10 @@ separator.homemade:
- data - data
title: vessel title: vessel
type: object type: object
required:
- vessel
- time
- event
- time_spec
- stir_time
- stir_speed
- settling_time
title: Stir_Goal title: Stir_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
message: message:
type: string type: string
@@ -399,10 +420,6 @@ separator.homemade:
type: string type: string
success: success:
type: boolean type: boolean
required:
- success
- message
- return_info
title: Stir_Result title: Stir_Result
type: object type: object
required: required:
@@ -418,36 +435,34 @@ separator.homemade:
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:

View File

@@ -28,31 +28,6 @@ post_process_station:
title: load_config参数 title: load_config参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: string
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-print_cache_stats: auto-print_cache_stats:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -104,42 +79,41 @@ post_process_station:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
disconnect: disconnect:
feedback: {} feedback:
status: status
goal: goal:
command: {} command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -149,42 +123,41 @@ post_process_station:
type: SendCmd type: SendCmd
read_node: read_node:
feedback: feedback:
result: result status: status
goal: goal:
command: node_name command: command
node_name: node_name
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -283,17 +256,19 @@ post_process_station:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: PostProcessTriggerClean_Feedback title: PostProcessTriggerClean_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
acetone_inner_wall_cleaning_count: acetone_inner_wall_cleaning_count:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
acetone_inner_wall_cleaning_injection: acetone_inner_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
acetone_inner_wall_cleaning_waste_time: acetone_inner_wall_cleaning_waste_time:
maximum: 2147483647 maximum: 2147483647
@@ -304,6 +279,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
acetone_outer_wall_cleaning_injection: acetone_outer_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
acetone_outer_wall_cleaning_wait_time: acetone_outer_wall_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -322,6 +299,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
acetone_stirrer_cleaning_injection: acetone_stirrer_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
acetone_stirrer_cleaning_wait_time: acetone_stirrer_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -348,6 +327,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
nmp_inner_wall_cleaning_injection: nmp_inner_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
nmp_inner_wall_cleaning_waste_time: nmp_inner_wall_cleaning_waste_time:
maximum: 2147483647 maximum: 2147483647
@@ -358,6 +339,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
nmp_outer_wall_cleaning_injection: nmp_outer_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
nmp_outer_wall_cleaning_wait_time: nmp_outer_wall_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -376,6 +359,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
nmp_stirrer_cleaning_injection: nmp_stirrer_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
nmp_stirrer_cleaning_wait_time: nmp_stirrer_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -394,6 +379,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
water_inner_wall_cleaning_injection: water_inner_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
water_inner_wall_cleaning_waste_time: water_inner_wall_cleaning_waste_time:
maximum: 2147483647 maximum: 2147483647
@@ -404,6 +391,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
water_outer_wall_cleaning_injection: water_outer_wall_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
water_outer_wall_cleaning_wait_time: water_outer_wall_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -422,6 +411,8 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
water_stirrer_cleaning_injection: water_stirrer_cleaning_injection:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
water_stirrer_cleaning_wait_time: water_stirrer_cleaning_wait_time:
maximum: 2147483647 maximum: 2147483647
@@ -431,55 +422,13 @@ post_process_station:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
required:
- nmp_outer_wall_cleaning_injection
- nmp_outer_wall_cleaning_count
- nmp_outer_wall_cleaning_wait_time
- nmp_outer_wall_cleaning_waste_time
- nmp_inner_wall_cleaning_injection
- nmp_inner_wall_cleaning_count
- nmp_pump_cleaning_suction_count
- nmp_inner_wall_cleaning_waste_time
- nmp_stirrer_cleaning_injection
- nmp_stirrer_cleaning_count
- nmp_stirrer_cleaning_wait_time
- nmp_stirrer_cleaning_waste_time
- water_outer_wall_cleaning_injection
- water_outer_wall_cleaning_count
- water_outer_wall_cleaning_wait_time
- water_outer_wall_cleaning_waste_time
- water_inner_wall_cleaning_injection
- water_inner_wall_cleaning_count
- water_pump_cleaning_suction_count
- water_inner_wall_cleaning_waste_time
- water_stirrer_cleaning_injection
- water_stirrer_cleaning_count
- water_stirrer_cleaning_wait_time
- water_stirrer_cleaning_waste_time
- acetone_outer_wall_cleaning_injection
- acetone_outer_wall_cleaning_count
- acetone_outer_wall_cleaning_wait_time
- acetone_outer_wall_cleaning_waste_time
- acetone_inner_wall_cleaning_injection
- acetone_inner_wall_cleaning_count
- acetone_pump_cleaning_suction_count
- acetone_inner_wall_cleaning_waste_time
- acetone_stirrer_cleaning_injection
- acetone_stirrer_cleaning_count
- acetone_stirrer_cleaning_wait_time
- acetone_stirrer_cleaning_waste_time
- pipe_blowing_time
- injection_pump_forward_empty_suction_count
- injection_pump_reverse_empty_suction_count
- filtration_liquid_selection
title: PostProcessTriggerClean_Goal title: PostProcessTriggerClean_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: PostProcessTriggerClean_Result title: PostProcessTriggerClean_Result
type: object type: object
required: required:
@@ -502,11 +451,11 @@ post_process_station:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: PostProcessGrab_Feedback title: PostProcessGrab_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
raw_tank_number: raw_tank_number:
maximum: 2147483647 maximum: 2147483647
@@ -516,17 +465,13 @@ post_process_station:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
required:
- reaction_tank_number
- raw_tank_number
title: PostProcessGrab_Goal title: PostProcessGrab_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: PostProcessGrab_Result title: PostProcessGrab_Result
type: object type: object
required: required:
@@ -573,13 +518,15 @@ post_process_station:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: PostProcessTriggerPostPro_Feedback title: PostProcessTriggerPostPro_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
atomization_fast_speed: atomization_fast_speed:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
atomization_pressure_kpa: atomization_pressure_kpa:
maximum: 2147483647 maximum: 2147483647
@@ -594,8 +541,12 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
first_wash_water_amount: first_wash_water_amount:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
initial_water_amount: initial_water_amount:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
injection_pump_push_speed: injection_pump_push_speed:
maximum: 2147483647 maximum: 2147483647
@@ -622,32 +573,20 @@ post_process_station:
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
second_wash_water_amount: second_wash_water_amount:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
wash_slow_speed: wash_slow_speed:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required:
- atomization_fast_speed
- wash_slow_speed
- injection_pump_suction_speed
- injection_pump_push_speed
- raw_liquid_suction_count
- first_wash_water_amount
- second_wash_water_amount
- first_powder_mixing_tim
- second_powder_mixing_time
- first_powder_wash_count
- second_powder_wash_count
- initial_water_amount
- pre_filtration_mixing_time
- atomization_pressure_kpa
title: PostProcessTriggerPostPro_Goal title: PostProcessTriggerPostPro_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: PostProcessTriggerPostPro_Result title: PostProcessTriggerPostPro_Result
type: object type: object
required: required:
@@ -669,30 +608,26 @@ post_process_station:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -702,8 +637,7 @@ post_process_station:
type: SendCmd type: SendCmd
module: unilabos.devices.workstation.post_process.post_process:OpcUaClient module: unilabos.devices.workstation.post_process.post_process:OpcUaClient
status_types: status_types:
cache_stats: dict cache_stats: Dict[str, Any]
node_value: String
type: python type: python
config_info: [] config_info: []
description: 后处理站 description: 后处理站
@@ -718,7 +652,9 @@ post_process_station:
config_path: config_path:
type: string type: string
deck: deck:
type: string anyOf:
- type: object
- type: object
password: password:
type: string type: string
subscription_interval: subscription_interval:
@@ -738,10 +674,7 @@ post_process_station:
properties: properties:
cache_stats: cache_stats:
type: object type: object
node_value:
type: string
required: required:
- node_value
- cache_stats - cache_stats
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -136,36 +136,36 @@ solenoid_valve:
set_valve_position: set_valve_position:
feedback: {} feedback: {}
goal: goal:
string: position position: position
string: string
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -278,26 +278,25 @@ solenoid_valve.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -310,26 +309,25 @@ solenoid_valve.mock:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -422,6 +420,27 @@ syringe_pump_with_valve.runze.SY03B-T06:
title: initialize参数 title: initialize参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-list:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: list的参数schema
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: list参数
type: object
type: UniLabJsonCommand
auto-pull_plunger: auto-pull_plunger:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -695,7 +714,10 @@ syringe_pump_with_valve.runze.SY03B-T06:
goal: goal:
properties: properties:
position: position:
type: string anyOf:
- type: integer
- type: string
- type: number
required: required:
- position - position
type: object type: object
@@ -720,7 +742,9 @@ syringe_pump_with_valve.runze.SY03B-T06:
goal: goal:
properties: properties:
velocity: velocity:
type: string anyOf:
- type: integer
- type: string
required: required:
- velocity - velocity
type: object type: object
@@ -780,13 +804,13 @@ syringe_pump_with_valve.runze.SY03B-T06:
status_types: status_types:
max_velocity: float max_velocity: float
mode: int mode: int
plunger_position: String plunger_position: ''
position: float position: float
status: str status: str
valve_position: str valve_position: str
velocity_end: String velocity_end: ''
velocity_grade: String velocity_grade: ''
velocity_init: String velocity_init: ''
type: python type: python
config_info: [] config_info: []
description: 润泽精密注射泵设备,集成阀门控制的高精度流体输送系统。该设备通过串口通信控制,支持多种运行模式和精确的体积控制。具备可变速度控制、精密定位、阀门切换、实时状态监控等功能。适用于微量液体输送、精密进样、流速控制、化学反应进料等需要高精度流体操作的实验室自动化应用。 description: 润泽精密注射泵设备,集成阀门控制的高精度流体输送系统。该设备通过串口通信控制,支持多种运行模式和精确的体积控制。具备可变速度控制、精密定位、阀门切换、实时状态监控等功能。适用于微量液体输送、精密进样、流速控制、化学反应进料等需要高精度流体操作的实验室自动化应用。
@@ -885,15 +909,15 @@ syringe_pump_with_valve.runze.SY03B-T06:
velocity_init: velocity_init:
type: string type: string
required: required:
- status
- mode
- max_velocity - max_velocity
- mode
- plunger_position
- position
- status
- valve_position
- velocity_end
- velocity_grade - velocity_grade
- velocity_init - velocity_init
- velocity_end
- valve_position
- position
- plunger_position
type: object type: object
version: 1.0.0 version: 1.0.0
syringe_pump_with_valve.runze.SY03B-T08: syringe_pump_with_valve.runze.SY03B-T08:
@@ -943,6 +967,27 @@ syringe_pump_with_valve.runze.SY03B-T08:
title: initialize参数 title: initialize参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-list:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: list的参数schema
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: list参数
type: object
type: UniLabJsonCommand
auto-pull_plunger: auto-pull_plunger:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -1216,7 +1261,10 @@ syringe_pump_with_valve.runze.SY03B-T08:
goal: goal:
properties: properties:
position: position:
type: string anyOf:
- type: integer
- type: string
- type: number
required: required:
- position - position
type: object type: object
@@ -1241,7 +1289,9 @@ syringe_pump_with_valve.runze.SY03B-T08:
goal: goal:
properties: properties:
velocity: velocity:
type: string anyOf:
- type: integer
- type: string
required: required:
- velocity - velocity
type: object type: object
@@ -1301,13 +1351,13 @@ syringe_pump_with_valve.runze.SY03B-T08:
status_types: status_types:
max_velocity: float max_velocity: float
mode: int mode: int
plunger_position: String plunger_position: ''
position: float position: float
status: str status: str
valve_position: str valve_position: str
velocity_end: String velocity_end: ''
velocity_grade: String velocity_grade: ''
velocity_init: String velocity_init: ''
type: python type: python
config_info: [] config_info: []
description: 润泽精密注射泵设备,集成阀门控制的高精度流体输送系统。该设备通过串口通信控制,支持多种运行模式和精确的体积控制。具备可变速度控制、精密定位、阀门切换、实时状态监控等功能。适用于微量液体输送、精密进样、流速控制、化学反应进料等需要高精度流体操作的实验室自动化应用。 description: 润泽精密注射泵设备,集成阀门控制的高精度流体输送系统。该设备通过串口通信控制,支持多种运行模式和精确的体积控制。具备可变速度控制、精密定位、阀门切换、实时状态监控等功能。适用于微量液体输送、精密进样、流速控制、化学反应进料等需要高精度流体操作的实验室自动化应用。
@@ -1422,14 +1472,14 @@ syringe_pump_with_valve.runze.SY03B-T08:
velocity_init: velocity_init:
type: string type: string
required: required:
- status
- mode
- max_velocity - max_velocity
- mode
- plunger_position
- position
- status
- valve_position
- velocity_end
- velocity_grade - velocity_grade
- velocity_init - velocity_init
- velocity_end
- valve_position
- position
- plunger_position
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -13,12 +13,13 @@ reaction_station.bioyond:
start_point: start_point start_point: start_point
start_step_key: start_step_key start_step_key: start_step_key
goal_default: goal_default:
duration: 0 duration: null
end_point: 0 end_point: 0
end_step_key: '' end_step_key: ''
start_point: 0 start_point: 0
start_step_key: '' start_step_key: ''
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 添加时间约束 - 在两个工作流之间添加时间约束 description: 添加时间约束 - 在两个工作流之间添加时间约束
@@ -30,23 +31,19 @@ reaction_station.bioyond:
description: 时间(秒) description: 时间(秒)
type: integer type: integer
end_point: end_point:
default: Start default: 0
description: 终点计时点 (Start=开始前, End=结束后) description: 终点计时点 (Start=开始前, End=结束后)
enum: type: integer
- Start
- End
type: string
end_step_key: end_step_key:
default: ''
description: 终点步骤Key (可选, 默认为空则自动选择) description: 终点步骤Key (可选, 默认为空则自动选择)
type: string type: string
start_point: start_point:
default: Start default: 0
description: 起点计时点 (Start=开始前, End=结束后) description: 起点计时点 (Start=开始前, End=结束后)
enum: type: integer
- Start
- End
type: string
start_step_key: start_step_key:
default: ''
description: 起点步骤Key (例如 "feeding", "liquid", 可选, 默认为空则自动选择) description: 起点步骤Key (例如 "feeding", "liquid", 可选, 默认为空则自动选择)
type: string type: string
required: required:
@@ -98,7 +95,8 @@ reaction_station.bioyond:
required: required:
- json_str - json_str
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: create_order参数 title: create_order参数
@@ -125,7 +123,8 @@ reaction_station.bioyond:
required: required:
- workflow_ids - workflow_ids
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: hard_delete_merged_workflows参数 title: hard_delete_merged_workflows参数
@@ -150,7 +149,8 @@ reaction_station.bioyond:
required: required:
- json_str - json_str
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: merge_workflow_with_parameters参数 title: merge_workflow_with_parameters参数
@@ -175,7 +175,8 @@ reaction_station.bioyond:
required: required:
- report_request - report_request
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: process_temperature_cutoff_report参数 title: process_temperature_cutoff_report参数
@@ -200,7 +201,12 @@ reaction_station.bioyond:
required: required:
- web_workflow_json - web_workflow_json
type: object type: object
result: {} result:
items:
additionalProperties:
type: string
type: object
type: array
required: required:
- goal - goal
title: process_web_workflows参数 title: process_web_workflows参数
@@ -229,7 +235,8 @@ reaction_station.bioyond:
- reactor_id - reactor_id
- temperature - temperature
type: object type: object
result: {} result:
type: string
required: required:
- goal - goal
title: set_reactor_temperature参数 title: set_reactor_temperature参数
@@ -254,7 +261,8 @@ reaction_station.bioyond:
required: required:
- preintake_id - preintake_id
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: skip_titration_steps参数 title: skip_titration_steps参数
@@ -275,7 +283,8 @@ reaction_station.bioyond:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: sync_workflow_sequence_from_bioyond参数 title: sync_workflow_sequence_from_bioyond参数
@@ -307,7 +316,8 @@ reaction_station.bioyond:
type: integer type: integer
required: [] required: []
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: wait_for_multiple_orders_and_get_reports参数 title: wait_for_multiple_orders_and_get_reports参数
@@ -359,7 +369,8 @@ reaction_station.bioyond:
required: required:
- workflow_id - workflow_id
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: workflow_step_query参数 title: workflow_step_query参数
@@ -370,9 +381,8 @@ reaction_station.bioyond:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
code: code result: {}
message: message
schema: schema:
description: 清空服务端所有非核心工作流 (保留核心流程) description: 清空服务端所有非核心工作流 (保留核心流程)
properties: properties:
@@ -382,13 +392,6 @@ reaction_station.bioyond:
required: [] required: []
type: object type: object
result: result:
properties:
code:
description: 操作结果代码(1表示成功)
type: integer
message:
description: 结果描述
type: string
type: object type: object
required: required:
- goal - goal
@@ -405,13 +408,14 @@ reaction_station.bioyond:
torque_variation: torque_variation torque_variation: torque_variation
volume: volume volume: volume
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
temperature: '' temperature: 25.0
time: '' time: '90'
titration_type: '' titration_type: '1'
torque_variation: '' torque_variation: 2
volume: '' volume: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 滴回去 description: 滴回去
@@ -423,33 +427,27 @@ reaction_station.bioyond:
description: 物料名称(不能为空) description: 物料名称(不能为空)
type: string type: string
temperature: temperature:
default: 25.0
description: 温度设定(°C) description: 温度设定(°C)
type: string type: number
time: time:
default: '90'
description: 观察时间(分钟) description: 观察时间(分钟)
type: string type: string
titration_type: titration_type:
default: '1'
description: 是否滴定(NO=否, YES=是) description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string type: string
torque_variation: torque_variation:
default: 2
description: 是否观察 (NO=否, YES=是) description: 是否观察 (NO=否, YES=是)
enum: type: integer
- 'NO'
- 'YES'
type: string
volume: volume:
description: 分液公式(mL) description: 分液公式(mL)
type: string type: string
required: required:
- volume
- assign_material_name - assign_material_name
- time - volume
- torque_variation
- titration_type
- temperature
type: object type: object
result: {} result: {}
required: required:
@@ -462,7 +460,7 @@ reaction_station.bioyond:
goal: goal:
batch_reports_result: batch_reports_result batch_reports_result: batch_reports_result
goal_default: goal_default:
batch_reports_result: '' batch_reports_result: null
handles: handles:
input: input:
- data_key: batch_reports_result - data_key: batch_reports_result
@@ -478,8 +476,8 @@ reaction_station.bioyond:
handler_key: ACTUALS_EXTRACTED handler_key: ACTUALS_EXTRACTED
io_type: sink io_type: sink
label: Extracted Actuals label: Extracted Actuals
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 从批量任务完成报告中提取每个订单的实际加料量输出extracted列表。 description: 从批量任务完成报告中提取每个订单的实际加料量输出extracted列表。
properties: properties:
@@ -493,13 +491,6 @@ reaction_station.bioyond:
- batch_reports_result - batch_reports_result
type: object type: object
result: result:
properties:
return_info:
description: JSON字符串包含actuals数组每项含order_code, order_id, actualTargetWeigh,
actualVolume
type: string
required:
- return_info
title: extract_actuals_from_batch_reports结果 title: extract_actuals_from_batch_reports结果
type: object type: object
required: required:
@@ -517,13 +508,14 @@ reaction_station.bioyond:
torque_variation: torque_variation torque_variation: torque_variation
volume: volume volume: volume
goal_default: goal_default:
assign_material_name: '' assign_material_name: BAPP
temperature: '' temperature: 25.0
time: '' time: '0'
titration_type: '' titration_type: '1'
torque_variation: '' torque_variation: 1
volume: '' volume: '350'
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 液体进料烧杯 description: 液体进料烧杯
@@ -532,36 +524,30 @@ reaction_station.bioyond:
goal: goal:
properties: properties:
assign_material_name: assign_material_name:
default: BAPP
description: 物料名称 description: 物料名称
type: string type: string
temperature: temperature:
default: 25.0
description: 温度设定(°C) description: 温度设定(°C)
type: string type: number
time: time:
default: '0'
description: 观察时间(分钟) description: 观察时间(分钟)
type: string type: string
titration_type: titration_type:
default: '1'
description: 是否滴定(NO=否, YES=是) description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string type: string
torque_variation: torque_variation:
default: 1
description: 是否观察 (NO=否, YES=是) description: 是否观察 (NO=否, YES=是)
enum: type: integer
- 'NO'
- 'YES'
type: string
volume: volume:
default: '350'
description: 分液公式(mL) description: 分液公式(mL)
type: string type: string
required: required: []
- volume
- assign_material_name
- time
- torque_variation
- titration_type
- temperature
type: object type: object
result: {} result: {}
required: required:
@@ -580,13 +566,13 @@ reaction_station.bioyond:
torque_variation: torque_variation torque_variation: torque_variation
volume: volume volume: volume
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
solvents: '' solvents: null
temperature: '25.00' temperature: 25.0
time: '360' time: '360'
titration_type: '1' titration_type: '1'
torque_variation: '2' torque_variation: 2
volume: '' volume: null
handles: handles:
input: input:
- data_key: solvents - data_key: solvents
@@ -595,6 +581,7 @@ reaction_station.bioyond:
handler_key: solvents handler_key: solvents
io_type: source io_type: source
label: Solvents Data From Calculation Node label: Solvents Data From Calculation Node
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 液体投料-溶剂。可以直接提供volume(mL),或通过solvents对象自动从additional_solvent(mL)计算volume。 description: 液体投料-溶剂。可以直接提供volume(mL),或通过solvents对象自动从additional_solvent(mL)计算volume。
@@ -609,27 +596,21 @@ reaction_station.bioyond:
description: '溶剂信息对象(可选),包含: additional_solvent(溶剂体积mL), total_liquid_volume(总液体体积mL)。如果提供,将自动计算volume' description: '溶剂信息对象(可选),包含: additional_solvent(溶剂体积mL), total_liquid_volume(总液体体积mL)。如果提供,将自动计算volume'
type: string type: string
temperature: temperature:
default: '25.00' default: 25.0
description: 温度设定(°C),默认25.00 description: 温度设定(°C),默认25.00
type: string type: number
time: time:
default: '360' default: '360'
description: 观察时间(分钟),默认360 description: 观察时间(分钟),默认360
type: string type: string
titration_type: titration_type:
default: 'NO' default: '1'
description: 是否滴定(NO=否, YES=是),默认NO description: 是否滴定(NO=否, YES=是),默认NO
enum:
- 'NO'
- 'YES'
type: string type: string
torque_variation: torque_variation:
default: 'YES' default: 2
description: 是否观察 (NO=否, YES=是),默认YES description: 是否观察 (NO=否, YES=是),默认YES
enum: type: integer
- 'NO'
- 'YES'
type: string
volume: volume:
description: 分液量(mL)。可直接提供,或通过solvents参数自动计算 description: 分液量(mL)。可直接提供,或通过solvents参数自动计算
type: string type: string
@@ -655,15 +636,15 @@ reaction_station.bioyond:
volume_formula: volume_formula volume_formula: volume_formula
x_value: x_value x_value: x_value
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
extracted_actuals: '' extracted_actuals: null
feeding_order_data: '' feeding_order_data: null
temperature: '25.00' temperature: 25.0
time: '90' time: '90'
titration_type: '2' titration_type: '2'
torque_variation: '2' torque_variation: 2
volume_formula: '' volume_formula: null
x_value: '' x_value: null
handles: handles:
input: input:
- data_key: extracted_actuals - data_key: extracted_actuals
@@ -678,6 +659,7 @@ reaction_station.bioyond:
handler_key: feeding_order handler_key: feeding_order
io_type: source io_type: source
label: Feeding Order Data From Calculation Node label: Feeding Order Data From Calculation Node
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 液体进料(滴定)。支持两种模式:1)直接提供volume_formula;2)自动计算-提供x_value+feeding_order_data+extracted_actuals,系统自动生成公式"1000*(m二酐-x)*V二酐滴定/m二酐滴定" description: 液体进料(滴定)。支持两种模式:1)直接提供volume_formula;2)自动计算-提供x_value+feeding_order_data+extracted_actuals,系统自动生成公式"1000*(m二酐-x)*V二酐滴定/m二酐滴定"
@@ -696,27 +678,21 @@ reaction_station.bioyond:
{"feeding_order": [{"type": "main_anhydride", "amount": 1.915}]}' {"feeding_order": [{"type": "main_anhydride", "amount": 1.915}]}'
type: string type: string
temperature: temperature:
default: '25.00' default: 25.0
description: 温度设定(°C),默认25.00 description: 温度设定(°C),默认25.00
type: string type: number
time: time:
default: '90' default: '90'
description: 观察时间(分钟),默认90 description: 观察时间(分钟),默认90
type: string type: string
titration_type: titration_type:
default: 'YES' default: '2'
description: 是否滴定(NO=否, YES=是),默认YES description: 是否滴定(NO=否, YES=是),默认YES
enum:
- 'NO'
- 'YES'
type: string type: string
torque_variation: torque_variation:
default: 'YES' default: 2
description: 是否观察 (NO=否, YES=是),默认YES description: 是否观察 (NO=否, YES=是),默认YES
enum: type: integer
- 'NO'
- 'YES'
type: string
volume_formula: volume_formula:
description: 分液公式(mL)。可直接提供固定公式,或留空由系统根据x_value、feeding_order_data、extracted_actuals自动生成 description: 分液公式(mL)。可直接提供固定公式,或留空由系统根据x_value、feeding_order_data、extracted_actuals自动生成
type: string type: string
@@ -742,13 +718,14 @@ reaction_station.bioyond:
torque_variation: torque_variation torque_variation: torque_variation
volume_formula: volume_formula volume_formula: volume_formula
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
temperature: '' temperature: 25.0
time: '' time: '0'
titration_type: '' titration_type: '1'
torque_variation: '' torque_variation: 1
volume_formula: '' volume_formula: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 液体进料小瓶(非滴定) description: 液体进料小瓶(非滴定)
@@ -760,33 +737,27 @@ reaction_station.bioyond:
description: 物料名称 description: 物料名称
type: string type: string
temperature: temperature:
default: 25.0
description: 温度设定(°C) description: 温度设定(°C)
type: string type: number
time: time:
default: '0'
description: 观察时间(分钟) description: 观察时间(分钟)
type: string type: string
titration_type: titration_type:
default: '1'
description: 是否滴定(NO=否, YES=是) description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string type: string
torque_variation: torque_variation:
default: 1
description: 是否观察 (NO=否, YES=是) description: 是否观察 (NO=否, YES=是)
enum: type: integer
- 'NO'
- 'YES'
type: string
volume_formula: volume_formula:
description: 分液公式(mL) description: 分液公式(mL)
type: string type: string
required: required:
- volume_formula - volume_formula
- assign_material_name - assign_material_name
- time
- torque_variation
- titration_type
- temperature
type: object type: object
result: {} result: {}
required: required:
@@ -800,9 +771,10 @@ reaction_station.bioyond:
task_name: task_name task_name: task_name
workflow_name: workflow_name workflow_name: workflow_name
goal_default: goal_default:
task_name: '' task_name: null
workflow_name: '' workflow_name: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 处理并执行工作流 description: 处理并执行工作流
@@ -820,7 +792,8 @@ reaction_station.bioyond:
- workflow_name - workflow_name
- task_name - task_name
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: process_and_execute_workflow参数 title: process_and_execute_workflow参数
@@ -833,10 +806,11 @@ reaction_station.bioyond:
cutoff: cutoff cutoff: cutoff
temperature: temperature temperature: temperature
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
cutoff: '' cutoff: '900000'
temperature: '' temperature: -10.0
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 反应器放入 - 将反应器放入工作站,配置物料名称、粘度上限和温度参数 description: 反应器放入 - 将反应器放入工作站,配置物料名称、粘度上限和温度参数
@@ -848,14 +822,14 @@ reaction_station.bioyond:
description: 物料名称 description: 物料名称
type: string type: string
cutoff: cutoff:
default: '900000'
description: 粘度上限 description: 粘度上限
type: string type: string
temperature: temperature:
default: -10.0
description: 温度设定(°C) description: 温度设定(°C)
type: string type: number
required: required:
- cutoff
- temperature
- assign_material_name - assign_material_name
type: object type: object
result: {} result: {}
@@ -869,6 +843,7 @@ reaction_station.bioyond:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 反应器取出 - 从工作站中取出反应器,无需参数的简单操作 description: 反应器取出 - 从工作站中取出反应器,无需参数的简单操作
@@ -878,15 +853,7 @@ reaction_station.bioyond:
properties: {} properties: {}
required: [] required: []
type: object type: object
result: result: {}
properties:
code:
description: 操作结果代码(1表示成功,0表示失败)
type: integer
return_info:
description: 操作结果详细信息
type: string
type: object
required: required:
- goal - goal
title: reactor_taken_out参数 title: reactor_taken_out参数
@@ -897,8 +864,8 @@ reaction_station.bioyond:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: placeholder_keys: {}
return_info: return_info result: {}
schema: schema:
description: 启动调度器 - 启动Bioyond工作站的任务调度器开始执行队列中的任务 description: 启动调度器 - 启动Bioyond工作站的任务调度器开始执行队列中的任务
properties: properties:
@@ -908,12 +875,6 @@ reaction_station.bioyond:
required: [] required: []
type: object type: object
result: result:
properties:
return_info:
description: 调度器启动结果成功返回1失败返回0
type: integer
required:
- return_info
title: scheduler_start结果 title: scheduler_start结果
type: object type: object
required: required:
@@ -930,12 +891,13 @@ reaction_station.bioyond:
time: time time: time
torque_variation: torque_variation torque_variation: torque_variation
goal_default: goal_default:
assign_material_name: '' assign_material_name: null
material_id: '' material_id: null
temperature: '' temperature: 25.0
time: '' time: '0'
torque_variation: '' torque_variation: 1
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 固体进料小瓶 - 通过小瓶向反应器中添加固体物料,支持多种粉末类型(盐、面粉、BTDA) description: 固体进料小瓶 - 通过小瓶向反应器中添加固体物料,支持多种粉末类型(盐、面粉、BTDA)
@@ -948,29 +910,21 @@ reaction_station.bioyond:
type: string type: string
material_id: material_id:
description: 粉末类型IDSalt=盐21分钟Flour=面粉27分钟BTDA=BTDA38分钟 description: 粉末类型IDSalt=盐21分钟Flour=面粉27分钟BTDA=BTDA38分钟
enum:
- Salt
- Flour
- BTDA
type: string type: string
temperature: temperature:
default: 25.0
description: 温度设定(°C) description: 温度设定(°C)
type: string type: number
time: time:
default: '0'
description: 观察时间(分钟) description: 观察时间(分钟)
type: string type: string
torque_variation: torque_variation:
default: 1
description: 是否观察 (NO=否, YES=是) description: 是否观察 (NO=否, YES=是)
enum: type: integer
- 'NO'
- 'YES'
type: string
required: required:
- assign_material_name
- material_id - material_id
- time
- torque_variation
- temperature
type: object type: object
result: {} result: {}
required: required:

View File

@@ -37,42 +37,41 @@ agv.SEER:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
send_nav_task: send_nav_task:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:

View File

@@ -122,31 +122,6 @@ robotic_arm.SCARA_with_slider.moveit.virtual:
title: moveit_task参数 title: moveit_task参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: post_init的参数schema
properties:
feedback: {}
goal:
properties:
ros_node:
type: object
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-resource_manager: auto-resource_manager:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -198,41 +173,41 @@ robotic_arm.SCARA_with_slider.moveit.virtual:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pick_and_place: pick_and_place:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -241,41 +216,41 @@ robotic_arm.SCARA_with_slider.moveit.virtual:
type: object type: object
type: SendCmd type: SendCmd
set_position: set_position:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -284,41 +259,41 @@ robotic_arm.SCARA_with_slider.moveit.virtual:
type: object type: object
type: SendCmd type: SendCmd
set_status: set_status:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -455,42 +430,41 @@ robotic_arm.UR:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
move_pos_task: move_pos_task:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -532,8 +506,8 @@ robotic_arm.UR:
type: string type: string
required: required:
- arm_pose - arm_pose
- gripper_pose
- arm_status - arm_status
- gripper_pose
- gripper_status - gripper_status
type: object type: object
version: 1.0.0 version: 1.0.0
@@ -726,41 +700,41 @@ robotic_arm.elite:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
modbus_task_cmd: modbus_task_cmd:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -770,8 +744,8 @@ robotic_arm.elite:
type: SendCmd type: SendCmd
module: unilabos.devices.arm.elite_robot:EliteRobot module: unilabos.devices.arm.elite_robot:EliteRobot
status_types: status_types:
actual_joint_positions: String actual_joint_positions: ''
arm_pose: String arm_pose: list[float]
type: python type: python
config_info: [] config_info: []
description: Elite robot arm description: Elite robot arm
@@ -797,8 +771,8 @@ robotic_arm.elite:
type: number type: number
type: array type: array
required: required:
- arm_pose
- actual_joint_positions - actual_joint_positions
- arm_pose
type: object type: object
model: model:
mesh: elite_robot mesh: elite_robot

View File

@@ -114,11 +114,12 @@ gripper.misumi_rz:
goal: goal:
properties: properties:
data: data:
type: string type: object
required: required:
- data - data
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: modbus_crc参数 title: modbus_crc参数
@@ -398,30 +399,26 @@ gripper.misumi_rz:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -504,71 +501,82 @@ gripper.mock:
type: UniLabJsonCommand type: UniLabJsonCommand
push_to: push_to:
feedback: feedback:
effort: torque effort: effort
position: position position: position
reached_goal: reached_goal
stalled: stalled
goal: goal:
command.max_effort: torque command: command
command.position: position position: position
torque: torque
velocity: velocity
goal_default: goal_default:
command: command:
max_effort: 0.0 max_effort: 0.0
position: 0.0 position: 0.0
handles: {} handles: {}
placeholder_keys: {}
result: result:
effort: torque effort: effort
position: position position: position
reached_goal: reached_goal
stalled: stalled
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
effort: effort:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
position: position:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
reached_goal: reached_goal:
type: boolean type: boolean
stalled: stalled:
type: boolean type: boolean
required:
- position
- effort
- stalled
- reached_goal
title: GripperCommand_Feedback title: GripperCommand_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
additionalProperties: false
properties: properties:
max_effort: max_effort:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
position: position:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- position - position
- max_effort - max_effort
title: command title: command
type: object type: object
required:
- command
title: GripperCommand_Goal title: GripperCommand_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
effort: effort:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
position: position:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
reached_goal: reached_goal:
type: boolean type: boolean
stalled: stalled:
type: boolean type: boolean
required:
- position
- effort
- stalled
- reached_goal
title: GripperCommand_Result title: GripperCommand_Result
type: object type: object
required: required:
@@ -604,8 +612,8 @@ gripper.mock:
type: number type: number
required: required:
- position - position
- velocity
- torque
- status - status
- torque
- velocity
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -24,6 +24,27 @@ linear_motion.grbl:
title: initialize参数 title: initialize参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-list:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: list的参数schema
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: list参数
type: object
type: UniLabJsonCommand
auto-set_position: auto-set_position:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -93,44 +114,39 @@ linear_motion.grbl:
type: UniLabJsonCommandAsync type: UniLabJsonCommandAsync
move_through_points: move_through_points:
feedback: feedback:
current_pose.pose.position: position current_pose: current_pose
estimated_time_remaining.sec: time_remaining distance_remaining: distance_remaining
navigation_time.sec: time_spent estimated_time_remaining: estimated_time_remaining
number_of_poses_remaining: pose_number_remaining navigation_time: navigation_time
number_of_poses_remaining: number_of_poses_remaining
number_of_recoveries: number_of_recoveries
goal: goal:
poses[].pose.position: positions[] behavior_tree: behavior_tree
poses: poses
positions: positions
goal_default: goal_default:
behavior_tree: '' behavior_tree: ''
poses: poses: []
- header:
frame_id: ''
stamp:
nanosec: 0
sec: 0
pose:
orientation:
w: 1.0
x: 0.0
y: 0.0
z: 0.0
position:
x: 0.0
y: 0.0
z: 0.0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
result: result
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
current_pose: current_pose:
additionalProperties: false
properties: properties:
header: header:
additionalProperties: false
properties: properties:
frame_id: frame_id:
type: string type: string
stamp: stamp:
additionalProperties: false
properties: properties:
nanosec: nanosec:
maximum: 4294967295 maximum: 4294967295
@@ -151,16 +167,26 @@ linear_motion.grbl:
title: header title: header
type: object type: object
pose: pose:
additionalProperties: false
properties: properties:
orientation: orientation:
additionalProperties: false
properties: properties:
w: w:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -170,12 +196,19 @@ linear_motion.grbl:
title: orientation title: orientation
type: object type: object
position: position:
additionalProperties: false
properties: properties:
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -194,8 +227,11 @@ linear_motion.grbl:
title: current_pose title: current_pose
type: object type: object
distance_remaining: distance_remaining:
maximum: 3.4028235e+38
minimum: -3.4028235e+38
type: number type: number
estimated_time_remaining: estimated_time_remaining:
additionalProperties: false
properties: properties:
nanosec: nanosec:
maximum: 4294967295 maximum: 4294967295
@@ -211,6 +247,7 @@ linear_motion.grbl:
title: estimated_time_remaining title: estimated_time_remaining
type: object type: object
navigation_time: navigation_time:
additionalProperties: false
properties: properties:
nanosec: nanosec:
maximum: 4294967295 maximum: 4294967295
@@ -233,16 +270,10 @@ linear_motion.grbl:
maximum: 32767 maximum: 32767
minimum: -32768 minimum: -32768
type: integer type: integer
required:
- current_pose
- navigation_time
- estimated_time_remaining
- number_of_recoveries
- distance_remaining
- number_of_poses_remaining
title: NavigateThroughPoses_Feedback title: NavigateThroughPoses_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
behavior_tree: behavior_tree:
type: string type: string
@@ -256,12 +287,8 @@ linear_motion.grbl:
stamp: stamp:
properties: properties:
nanosec: nanosec:
maximum: 4294967295
minimum: 0
type: integer type: integer
sec: sec:
maximum: 2147483647
minimum: -2147483648
type: integer type: integer
required: required:
- sec - sec
@@ -314,23 +341,17 @@ linear_motion.grbl:
required: required:
- header - header
- pose - pose
title: poses
type: object type: object
type: array type: array
required:
- poses
- behavior_tree
title: NavigateThroughPoses_Goal title: NavigateThroughPoses_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
result: result:
properties: {} additionalProperties: true
required: []
title: result title: result
type: object type: object
required:
- result
title: NavigateThroughPoses_Result title: NavigateThroughPoses_Result
type: object type: object
required: required:
@@ -340,9 +361,15 @@ linear_motion.grbl:
type: NavigateThroughPoses type: NavigateThroughPoses
set_spindle_speed: set_spindle_speed:
feedback: feedback:
position: spindle_speed error: error
header: header
position: position
velocity: velocity
goal: goal:
position: spindle_speed max_velocity: max_velocity
min_duration: min_duration
position: position
spindle_speed: spindle_speed
goal_default: goal_default:
max_velocity: 0.0 max_velocity: 0.0
min_duration: min_duration:
@@ -350,19 +377,25 @@ linear_motion.grbl:
sec: 0 sec: 0
position: 0.0 position: 0.0
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
error: error:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
header: header:
additionalProperties: false
properties: properties:
frame_id: frame_id:
type: string type: string
stamp: stamp:
additionalProperties: false
properties: properties:
nanosec: nanosec:
maximum: 4294967295 maximum: 4294967295
@@ -383,21 +416,24 @@ linear_motion.grbl:
title: header title: header
type: object type: object
position: position:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
velocity: velocity:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required:
- header
- position
- velocity
- error
title: SingleJointPosition_Feedback title: SingleJointPosition_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
max_velocity: max_velocity:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
min_duration: min_duration:
additionalProperties: false
properties: properties:
nanosec: nanosec:
maximum: 4294967295 maximum: 4294967295
@@ -413,16 +449,13 @@ linear_motion.grbl:
title: min_duration title: min_duration
type: object type: object
position: position:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required:
- position
- min_duration
- max_velocity
title: SingleJointPosition_Goal title: SingleJointPosition_Goal
type: object type: object
result: result:
properties: {} additionalProperties: true
required: []
title: SingleJointPosition_Result title: SingleJointPosition_Result
type: object type: object
required: required:
@@ -432,7 +465,7 @@ linear_motion.grbl:
type: SingleJointPosition type: SingleJointPosition
module: unilabos.devices.cnc.grbl_sync:GrblCNC module: unilabos.devices.cnc.grbl_sync:GrblCNC
status_types: status_types:
position: unilabos.messages:Point3D position: Point3D
spindle_speed: float spindle_speed: float
status: str status: str
type: python type: python
@@ -471,9 +504,9 @@ linear_motion.grbl:
status: status:
type: string type: string
required: required:
- status
- position - position
- spindle_speed - spindle_speed
- status
type: object type: object
version: 1.0.0 version: 1.0.0
linear_motion.toyo_xyz.sim: linear_motion.toyo_xyz.sim:
@@ -600,31 +633,6 @@ linear_motion.toyo_xyz.sim:
title: moveit_task参数 title: moveit_task参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: post_init的参数schema
properties:
feedback: {}
goal:
properties:
ros_node:
type: object
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-resource_manager: auto-resource_manager:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -676,41 +684,41 @@ linear_motion.toyo_xyz.sim:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
pick_and_place: pick_and_place:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -719,41 +727,41 @@ linear_motion.toyo_xyz.sim:
type: object type: object
type: SendCmd type: SendCmd
set_position: set_position:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -762,41 +770,41 @@ linear_motion.toyo_xyz.sim:
type: object type: object
type: SendCmd type: SendCmd
set_status: set_status:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -939,30 +947,26 @@ motor.iCL42:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -1000,8 +1004,8 @@ motor.iCL42:
success: success:
type: boolean type: boolean
required: required:
- motor_position
- is_executing_run - is_executing_run
- motor_position
- success - success
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -14,19 +14,24 @@ solid_dispenser.laiyu:
powder_tube_number: 0 powder_tube_number: 0
target_tube_position: '' target_tube_position: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
actual_mass_mg: actual_mass_mg actual_mass_mg: actual_mass_mg
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: SolidDispenseAddPowderTube_Feedback title: SolidDispenseAddPowderTube_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
compound_mass: compound_mass:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
powder_tube_number: powder_tube_number:
maximum: 2147483647 maximum: 2147483647
@@ -34,24 +39,19 @@ solid_dispenser.laiyu:
type: integer type: integer
target_tube_position: target_tube_position:
type: string type: string
required:
- powder_tube_number
- target_tube_position
- compound_mass
title: SolidDispenseAddPowderTube_Goal title: SolidDispenseAddPowderTube_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
actual_mass_mg: actual_mass_mg:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- actual_mass_mg
- success
title: SolidDispenseAddPowderTube_Result title: SolidDispenseAddPowderTube_Result
type: object type: object
required: required:
@@ -74,11 +74,12 @@ solid_dispenser.laiyu:
goal: goal:
properties: properties:
data: data:
type: string type: object
required: required:
- data - data
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: calculate_crc参数 title: calculate_crc参数
@@ -99,11 +100,12 @@ solid_dispenser.laiyu:
goal: goal:
properties: properties:
command: command:
type: string type: object
required: required:
- command - command
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: send_command参数 title: send_command参数
@@ -112,36 +114,37 @@ solid_dispenser.laiyu:
discharge: discharge:
feedback: {} feedback: {}
goal: goal:
float_input: float_input float_in: float_in
goal_default: goal_default:
float_in: 0.0 float_in: 0.0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: FloatSingleInput_Feedback title: FloatSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
float_in: float_in:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required:
- float_in
title: FloatSingleInput_Goal title: FloatSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: FloatSingleInput_Result title: FloatSingleInput_Result
type: object type: object
required: required:
@@ -156,32 +159,31 @@ solid_dispenser.laiyu:
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -200,38 +202,41 @@ solid_dispenser.laiyu:
y: 0.0 y: 0.0
z: 0.0 z: 0.0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: Point3DSeparateInput_Feedback title: Point3DSeparateInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required:
- x
- y
- z
title: Point3DSeparateInput_Goal title: Point3DSeparateInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: Point3DSeparateInput_Result title: Point3DSeparateInput_Result
type: object type: object
required: required:
@@ -246,34 +251,33 @@ solid_dispenser.laiyu:
goal_default: goal_default:
int_input: 0 int_input: 0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: IntSingleInput_Feedback title: IntSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
int_input: int_input:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
required:
- int_input
title: IntSingleInput_Goal title: IntSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: IntSingleInput_Result title: IntSingleInput_Result
type: object type: object
required: required:
@@ -288,34 +292,33 @@ solid_dispenser.laiyu:
goal_default: goal_default:
int_input: 0 int_input: 0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: IntSingleInput_Feedback title: IntSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
int_input: int_input:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
required:
- int_input
title: IntSingleInput_Goal title: IntSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: IntSingleInput_Result title: IntSingleInput_Result
type: object type: object
required: required:
@@ -328,26 +331,25 @@ solid_dispenser.laiyu:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:

View File

@@ -34,7 +34,8 @@ chiller:
- register_address - register_address
- value - value
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: build_modbus_frame参数 title: build_modbus_frame参数
@@ -63,7 +64,8 @@ chiller:
required: required:
- temperature - temperature
type: object type: object
result: {} result:
type: integer
required: required:
- goal - goal
title: convert_temperature_to_modbus_value参数 title: convert_temperature_to_modbus_value参数
@@ -84,11 +86,12 @@ chiller:
goal: goal:
properties: properties:
data: data:
type: string type: object
required: required:
- data - data
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: modbus_crc参数 title: modbus_crc参数
@@ -116,42 +119,41 @@ chiller:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
set_temperature: set_temperature:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -266,9 +268,15 @@ heaterstirrer.dalong:
feedback: feedback:
status: status status: status
goal: goal:
pressure: pressure
purpose: purpose purpose: purpose
reflux_solvent: reflux_solvent
stir: stir
stir_speed: stir_speed
temp: temp temp: temp
temp_spec: temp_spec
time: time time: time
time_spec: time_spec
vessel: vessel vessel: vessel
goal_default: goal_default:
pressure: '' pressure: ''
@@ -301,20 +309,23 @@ heaterstirrer.dalong:
sample_id: '' sample_id: ''
type: '' type: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
message: message
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: HeatChill_Feedback title: HeatChill_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
pressure: pressure:
type: string type: string
@@ -325,8 +336,12 @@ heaterstirrer.dalong:
stir: stir:
type: boolean type: boolean
stir_speed: stir_speed:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
temp: temp:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
temp_spec: temp_spec:
type: string type: string
@@ -335,6 +350,7 @@ heaterstirrer.dalong:
time_spec: time_spec:
type: string type: string
vessel: vessel:
additionalProperties: false
properties: properties:
category: category:
type: string type: string
@@ -353,16 +369,26 @@ heaterstirrer.dalong:
parent: parent:
type: string type: string
pose: pose:
additionalProperties: false
properties: properties:
orientation: orientation:
additionalProperties: false
properties: properties:
w: w:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -372,12 +398,19 @@ heaterstirrer.dalong:
title: orientation title: orientation
type: object type: object
position: position:
additionalProperties: false
properties: properties:
x: x:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
y: y:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
z: z:
maximum: 1.7976931348623157e+308
minimum: -1.7976931348623157e+308
type: number type: number
required: required:
- x - x
@@ -407,20 +440,10 @@ heaterstirrer.dalong:
- data - data
title: vessel title: vessel
type: object type: object
required:
- vessel
- temp
- time
- temp_spec
- time_spec
- pressure
- reflux_solvent
- stir
- stir_speed
- purpose
title: HeatChill_Goal title: HeatChill_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
message: message:
type: string type: string
@@ -428,10 +451,6 @@ heaterstirrer.dalong:
type: string type: string
success: success:
type: boolean type: boolean
required:
- success
- message
- return_info
title: HeatChill_Result title: HeatChill_Result
type: object type: object
required: required:
@@ -440,42 +459,42 @@ heaterstirrer.dalong:
type: object type: object
type: HeatChill type: HeatChill
set_temp_target: set_temp_target:
feedback: {} feedback:
status: status
goal: goal:
command: temp command: command
temp: temp
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -484,42 +503,42 @@ heaterstirrer.dalong:
type: object type: object
type: SendCmd type: SendCmd
set_temp_warning: set_temp_warning:
feedback: {} feedback:
status: status
goal: goal:
command: temp command: command
temp: temp
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:
@@ -569,8 +588,8 @@ heaterstirrer.dalong:
- status - status
- stir_speed - stir_speed
- temp - temp
- temp_warning
- temp_target - temp_target
- temp_warning
type: object type: object
version: 1.0.0 version: 1.0.0
tempsensor: tempsensor:
@@ -691,42 +710,41 @@ tempsensor:
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
set_warning: set_warning:
feedback: {} feedback:
status: status
goal: goal:
command: command command: command
goal_default: goal_default:
command: '' command: ''
handles: {} handles: {}
placeholder_keys: {}
result: result:
return_info: return_info
success: success success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
additionalProperties: false
properties: properties:
status: status:
type: string type: string
required:
- status
title: SendCmd_Feedback title: SendCmd_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
command: command:
type: string type: string
required:
- command
title: SendCmd_Goal title: SendCmd_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: SendCmd_Result title: SendCmd_Result
type: object type: object
required: required:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -45,31 +45,6 @@ xrd_d7mate:
title: connect参数 title: connect参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: string
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
auto-start_from_string: auto-start_from_string:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -85,11 +60,14 @@ xrd_d7mate:
goal: goal:
properties: properties:
params: params:
type: string anyOf:
- type: string
- type: object
required: required:
- params - params
type: object type: object
result: {} result:
type: object
required: required:
- goal - goal
title: start_from_string参数 title: start_from_string参数
@@ -105,21 +83,18 @@ xrd_d7mate:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -130,38 +105,38 @@ xrd_d7mate:
get_sample_down: get_sample_down:
feedback: {} feedback: {}
goal: goal:
sample_station: 1 int_input: int_input
sample_station: sample_station
goal_default: goal_default:
int_input: 0 int_input: 0
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: IntSingleInput_Feedback title: IntSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
int_input: int_input:
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: -2147483648
type: integer type: integer
required:
- int_input
title: IntSingleInput_Goal title: IntSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: IntSingleInput_Result title: IntSingleInput_Result
type: object type: object
required: required:
@@ -179,21 +154,18 @@ xrd_d7mate:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -211,21 +183,18 @@ xrd_d7mate:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -238,26 +207,25 @@ xrd_d7mate:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -274,42 +242,35 @@ xrd_d7mate:
sample_id: '' sample_id: ''
start_theta: 10.0 start_theta: 10.0
goal_default: goal_default:
end_theta: 80.0 end_theta: null
exp_time: 0.5 exp_time: null
increment: 0.02 increment: null
sample_id: Sample001 sample_id: null
start_theta: 10.0 start_theta: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 送样完成后,发送样品信息和采集参数 description: 送样完成后,发送样品信息和采集参数
properties: properties:
feedback: feedback:
properties: {}
required: []
title: SampleReadyInput_Feedback title: SampleReadyInput_Feedback
type: object
goal: goal:
properties: properties:
end_theta: end_theta:
description: 结束角度≥5.5°且必须大于start_theta description: 结束角度≥5.5°且必须大于start_theta
minimum: 5.5
type: number type: number
exp_time: exp_time:
description: 曝光时间0.1-5.0秒) description: 曝光时间0.1-5.0秒)
maximum: 5.0
minimum: 0.1
type: number type: number
increment: increment:
description: 角度增量≥0.005 description: 角度增量≥0.005
minimum: 0.005
type: number type: number
sample_id: sample_id:
description: 样品标识符 description: 样品标识符
type: string type: string
start_theta: start_theta:
description: 起始角度≥5° description: 起始角度≥5°
minimum: 5.0
type: number type: number
required: required:
- sample_id - sample_id
@@ -320,19 +281,11 @@ xrd_d7mate:
title: SampleReadyInput_Goal title: SampleReadyInput_Goal
type: object type: object
result: result:
properties:
return_info:
type: string
success:
type: boolean
required:
- return_info
- success
title: SampleReadyInput_Result title: SampleReadyInput_Result
type: object type: object
required: required:
- goal - goal
title: SampleReadyInput title: send_sample_ready参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
set_power_off: set_power_off:
@@ -340,26 +293,25 @@ xrd_d7mate:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -372,26 +324,25 @@ xrd_d7mate:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -405,18 +356,16 @@ xrd_d7mate:
current: 30.0 current: 30.0
voltage: 40.0 voltage: 40.0
goal_default: goal_default:
current: 30.0 current: null
voltage: 40.0 voltage: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 设置高压电源电压和电流 description: 设置高压电源电压和电流
properties: properties:
feedback: feedback:
properties: {}
required: []
title: VoltageCurrentInput_Feedback title: VoltageCurrentInput_Feedback
type: object
goal: goal:
properties: properties:
current: current:
@@ -431,19 +380,11 @@ xrd_d7mate:
title: VoltageCurrentInput_Goal title: VoltageCurrentInput_Goal
type: object type: object
result: result:
properties:
return_info:
type: string
success:
type: boolean
required:
- return_info
- success
title: VoltageCurrentInput_Result title: VoltageCurrentInput_Result
type: object type: object
required: required:
- goal - goal
title: VoltageCurrentInput title: set_voltage_current参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
start: start:
@@ -453,11 +394,12 @@ xrd_d7mate:
end_theta: 80.0 end_theta: 80.0
exp_time: 0.1 exp_time: 0.1
increment: 0.05 increment: 0.05
sample_id: 样品名称 sample_id: ''
start_theta: 10.0 start_theta: 10.0
string: '' string: ''
wait_minutes: 3.0 wait_minutes: 3.0
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 启动自动模式→上样→等待→样品准备→监控→检测下样位→执行下样流程。 description: 启动自动模式→上样→等待→样品准备→监控→检测下样位→执行下样流程。
@@ -466,54 +408,42 @@ xrd_d7mate:
goal: goal:
properties: properties:
end_theta: end_theta:
default: 80.0
description: 结束角度≥5.5°且必须大于start_theta description: 结束角度≥5.5°且必须大于start_theta
minimum: 5.5 type: number
type: string
exp_time: exp_time:
default: 0.1
description: 曝光时间0.1-5.0秒) description: 曝光时间0.1-5.0秒)
maximum: 5.0 type: number
minimum: 0.1
type: string
increment: increment:
default: 0.05
description: 角度增量≥0.005 description: 角度增量≥0.005
minimum: 0.005 type: number
type: string
sample_id: sample_id:
default: ''
description: 样品标识符 description: 样品标识符
type: string type: string
start_theta: start_theta:
default: 10.0
description: 起始角度≥5° description: 起始角度≥5°
minimum: 5.0 type: number
type: string
string: string:
default: ''
description: 字符串格式的参数输入,如果提供则优先解析使用 description: 字符串格式的参数输入,如果提供则优先解析使用
type: string type: string
wait_minutes: wait_minutes:
default: 3.0
description: 允许上样后等待分钟数 description: 允许上样后等待分钟数
minimum: 0.0
type: number type: number
required: required: []
- sample_id
- start_theta
- end_theta
- increment
- exp_time
title: StartWorkflow_Goal title: StartWorkflow_Goal
type: object type: object
result: result:
properties:
return_info:
type: string
success:
type: boolean
required:
- return_info
- success
title: StartWorkflow_Result title: StartWorkflow_Result
type: object type: object
required: required:
- goal - goal
title: StartWorkflow title: start参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
start_auto_mode: start_auto_mode:
@@ -521,17 +451,15 @@ xrd_d7mate:
goal: goal:
status: true status: true
goal_default: goal_default:
status: true status: null
handles: {} handles: {}
placeholder_keys: {}
result: {} result: {}
schema: schema:
description: 启动或停止自动模式 description: 启动或停止自动模式
properties: properties:
feedback: feedback:
properties: {}
required: []
title: BoolSingleInput_Feedback title: BoolSingleInput_Feedback
type: object
goal: goal:
properties: properties:
status: status:
@@ -542,25 +470,16 @@ xrd_d7mate:
title: BoolSingleInput_Goal title: BoolSingleInput_Goal
type: object type: object
result: result:
properties:
return_info:
type: string
success:
type: boolean
required:
- return_info
- success
title: BoolSingleInput_Result title: BoolSingleInput_Result
type: object type: object
required: required:
- goal - goal
title: BoolSingleInput title: start_auto_mode参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
module: unilabos.devices.xrd_d7mate.xrd_d7mate:XRDClient module: unilabos.devices.xrd_d7mate.xrd_d7mate:XRDClient
status_types: status_types:
current_acquire_data: dict current_acquire_data: dict
sample_down: dict
sample_request: dict sample_request: dict
sample_status: dict sample_status: dict
type: python type: python
@@ -586,16 +505,13 @@ xrd_d7mate:
properties: properties:
current_acquire_data: current_acquire_data:
type: object type: object
sample_down:
type: object
sample_request: sample_request:
type: object type: object
sample_status: sample_status:
type: object type: object
required: required:
- sample_request
- current_acquire_data - current_acquire_data
- sample_request
- sample_status - sample_status
- sample_down
type: object type: object
version: 1.0.0 version: 1.0.0

View File

@@ -8,26 +8,25 @@ zhida_gcms:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -77,31 +76,6 @@ zhida_gcms:
title: connect参数 title: connect参数
type: object type: object
type: UniLabJsonCommand type: UniLabJsonCommand
auto-post_init:
feedback: {}
goal: {}
goal_default:
ros_node: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
ros_node:
type: string
required:
- ros_node
type: object
result: {}
required:
- goal
title: post_init参数
type: object
type: UniLabJsonCommand
get_methods: get_methods:
feedback: {} feedback: {}
goal: {} goal: {}
@@ -112,21 +86,18 @@ zhida_gcms:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -144,21 +115,18 @@ zhida_gcms:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -176,21 +144,18 @@ zhida_gcms:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -203,26 +168,25 @@ zhida_gcms:
goal: {} goal: {}
goal_default: {} goal_default: {}
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Feedback title: EmptyIn_Feedback
type: object type: object
goal: goal:
properties: {} additionalProperties: true
required: []
title: EmptyIn_Goal title: EmptyIn_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
required:
- return_info
title: EmptyIn_Result title: EmptyIn_Result
type: object type: object
required: required:
@@ -234,35 +198,35 @@ zhida_gcms:
feedback: {} feedback: {}
goal: goal:
string: string string: string
text: text
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -273,36 +237,36 @@ zhida_gcms:
start_with_csv_file: start_with_csv_file:
feedback: {} feedback: {}
goal: goal:
csv_file_path: csv_file_path
string: string string: string
goal_default: goal_default:
string: '' string: ''
handles: {} handles: {}
result: {} placeholder_keys: {}
result:
return_info: return_info
success: success
schema: schema:
description: '' description: ''
properties: properties:
feedback: feedback:
properties: {} additionalProperties: true
required: []
title: StrSingleInput_Feedback title: StrSingleInput_Feedback
type: object type: object
goal: goal:
additionalProperties: false
properties: properties:
string: string:
type: string type: string
required:
- string
title: StrSingleInput_Goal title: StrSingleInput_Goal
type: object type: object
result: result:
additionalProperties: false
properties: properties:
return_info: return_info:
type: string type: string
success: success:
type: boolean type: boolean
required:
- return_info
- success
title: StrSingleInput_Result title: StrSingleInput_Result
type: object type: object
required: required:
@@ -343,8 +307,8 @@ zhida_gcms:
version: version:
type: object type: object
required: required:
- status
- methods - methods
- status
- version - version
type: object type: object
version: 1.0.0 version: 1.0.0

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,6 @@ YB_20ml_fenyeping:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_5ml_fenyeping: YB_5ml_fenyeping:
category: category:
@@ -22,7 +21,6 @@ YB_5ml_fenyeping:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_jia_yang_tou_da: YB_jia_yang_tou_da:
category: category:
@@ -35,7 +33,6 @@ YB_jia_yang_tou_da:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_pei_ye_da_Bottle: YB_pei_ye_da_Bottle:
category: category:
@@ -48,7 +45,6 @@ YB_pei_ye_da_Bottle:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_pei_ye_xiao_Bottle: YB_pei_ye_xiao_Bottle:
category: category:
@@ -61,7 +57,6 @@ YB_pei_ye_xiao_Bottle:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_qiang_tou: YB_qiang_tou:
category: category:
@@ -74,7 +69,6 @@ YB_qiang_tou:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_ye_Bottle: YB_ye_Bottle:
category: category:
@@ -88,5 +82,4 @@ YB_ye_Bottle:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,7 +9,6 @@ YB_100ml_yeti:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_20ml_fenyepingban: YB_20ml_fenyepingban:
category: category:
@@ -22,7 +21,6 @@ YB_20ml_fenyepingban:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_5ml_fenyepingban: YB_5ml_fenyepingban:
category: category:
@@ -35,7 +33,6 @@ YB_5ml_fenyepingban:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_6StockCarrier: YB_6StockCarrier:
category: category:
@@ -48,7 +45,6 @@ YB_6StockCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_6VialCarrier: YB_6VialCarrier:
category: category:
@@ -61,7 +57,6 @@ YB_6VialCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_gao_nian_ye_Bottle: YB_gao_nian_ye_Bottle:
category: category:
@@ -74,7 +69,6 @@ YB_gao_nian_ye_Bottle:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_gaonianye: YB_gaonianye:
category: category:
@@ -87,7 +81,6 @@ YB_gaonianye:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_jia_yang_tou_da_Carrier: YB_jia_yang_tou_da_Carrier:
category: category:
@@ -100,7 +93,6 @@ YB_jia_yang_tou_da_Carrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_peiyepingdaban: YB_peiyepingdaban:
category: category:
@@ -113,7 +105,6 @@ YB_peiyepingdaban:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_peiyepingxiaoban: YB_peiyepingxiaoban:
category: category:
@@ -126,7 +117,6 @@ YB_peiyepingxiaoban:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_qiang_tou_he: YB_qiang_tou_he:
category: category:
@@ -139,7 +129,6 @@ YB_qiang_tou_he:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_shi_pei_qi_kuai: YB_shi_pei_qi_kuai:
category: category:
@@ -152,7 +141,6 @@ YB_shi_pei_qi_kuai:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_ye: YB_ye:
category: category:
@@ -165,7 +153,6 @@ YB_ye:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
YB_ye_100ml_Bottle: YB_ye_100ml_Bottle:
category: category:
@@ -178,5 +165,4 @@ YB_ye_100ml_Bottle:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ BIOYOND_PolymerStation_1BottleCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
BIOYOND_PolymerStation_1FlaskCarrier: BIOYOND_PolymerStation_1FlaskCarrier:
category: category:
@@ -20,7 +19,6 @@ BIOYOND_PolymerStation_1FlaskCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
BIOYOND_PolymerStation_6StockCarrier: BIOYOND_PolymerStation_6StockCarrier:
category: category:
@@ -32,7 +30,6 @@ BIOYOND_PolymerStation_6StockCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
BIOYOND_PolymerStation_8StockCarrier: BIOYOND_PolymerStation_8StockCarrier:
category: category:
@@ -44,5 +41,4 @@ BIOYOND_PolymerStation_8StockCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ BIOYOND_PolymerPreparationStation_Deck:
handles: [] handles: []
icon: 配液站.webp icon: 配液站.webp
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
BIOYOND_PolymerReactionStation_Deck: BIOYOND_PolymerReactionStation_Deck:
category: category:
@@ -20,7 +19,6 @@ BIOYOND_PolymerReactionStation_Deck:
handles: [] handles: []
icon: 反应站.webp icon: 反应站.webp
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
BIOYOND_YB_Deck: BIOYOND_YB_Deck:
category: category:
@@ -32,7 +30,6 @@ BIOYOND_YB_Deck:
handles: [] handles: []
icon: 配液站.webp icon: 配液站.webp
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
CoincellDeck: CoincellDeck:
category: category:
@@ -44,5 +41,4 @@ CoincellDeck:
handles: [] handles: []
icon: koudian.webp icon: koudian.webp
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -1,24 +1,3 @@
disposal:
category:
- disposal
- waste
- resource_container
class:
module: unilabos.resources.disposal:Disposal
type: unilabos
description: 废料处理位置,用于处理实验废料
handles:
- data_key: disposal_access
data_source: handle
data_type: fluid
handler_key: access
io_type: target
label: access
side: NORTH
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
hplc_plate: hplc_plate:
category: category:
- resource_container - resource_container
@@ -40,56 +19,6 @@ hplc_plate:
- 3.1416 - 3.1416
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/hplc_plate/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/hplc_plate/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0
maintenance:
category:
- maintenance
- position
- resource_container
class:
module: unilabos.resources.maintenance:Maintenance
type: unilabos
description: 维护位置,用于设备维护和校准
handles:
- data_key: maintenance_access
data_source: handle
data_type: mechanical
handler_key: access
io_type: target
label: access
side: NORTH
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
plate:
category:
- plate
- labware
- resource_container
class:
module: unilabos.resources.plate:Plate
type: unilabos
description: 实验板,用于放置样品和试剂
handles:
- data_key: plate_access
data_source: handle
data_type: mechanical
handler_key: access
io_type: target
label: access
side: NORTH
- data_key: sample_wells
data_source: handle
data_type: fluid
handler_key: wells
io_type: target
label: wells
side: CENTER
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
plate_96: plate_96:
category: category:
@@ -112,7 +41,6 @@ plate_96:
- 0 - 0
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/plate_96/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/plate_96/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
plate_96_high: plate_96_high:
category: category:
@@ -135,35 +63,6 @@ plate_96_high:
- 1.5708 - 1.5708
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/plate_96_high/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/plate_96_high/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0
tip_rack:
category:
- tip_rack
- labware
- resource_container
class:
module: unilabos.resources.tip_rack:TipRack
type: unilabos
description: 枪头架资源,用于存放和管理移液器枪头
handles:
- data_key: tip_access
data_source: handle
data_type: mechanical
handler_key: access
io_type: target
label: access
side: NORTH
- data_key: tip_pickup
data_source: handle
data_type: mechanical
handler_key: pickup
io_type: target
label: pickup
side: SOUTH
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
tiprack_96_high: tiprack_96_high:
category: category:
@@ -195,7 +94,6 @@ tiprack_96_high:
- 1.5708 - 1.5708
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tiprack_96_high/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tiprack_96_high/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
tiprack_box: tiprack_box:
category: category:
@@ -227,5 +125,4 @@ tiprack_box:
- 0 - 0
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tiprack_box/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tiprack_box/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -29,7 +29,6 @@ bottle_container:
- 0 - 0
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/bottle_container/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/bottle_container/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
tube_container: tube_container:
category: category:
@@ -62,5 +61,4 @@ tube_container:
- 0 - 0
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tube_container/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tube_container/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -12,5 +12,4 @@ TransformXYZDeck:
mesh: liquid_transform_xyz mesh: liquid_transform_xyz
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/liquid_transform_xyz/macro_device.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/liquid_transform_xyz/macro_device.xacro
type: device type: device
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -12,7 +12,6 @@ OTDeck:
mesh: opentrons_liquid_handler mesh: opentrons_liquid_handler
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/opentrons_liquid_handler/macro_device.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/opentrons_liquid_handler/macro_device.xacro
type: device type: device
registry_type: resource
version: 1.0.0 version: 1.0.0
hplc_station: hplc_station:
category: category:
@@ -28,5 +27,4 @@ hplc_station:
mesh: hplc_station mesh: hplc_station
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/hplc_station/macro_device.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/devices/hplc_station/macro_device.xacro
type: device type: device
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,5 +8,4 @@ Opentrons_96_adapter_Vb:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ appliedbiosystemsmicroamp_384_wellplate_40ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
biorad_384_wellplate_50ul: biorad_384_wellplate_50ul:
category: category:
@@ -20,7 +19,6 @@ biorad_384_wellplate_50ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
biorad_96_wellplate_200ul_pcr: biorad_96_wellplate_200ul_pcr:
category: category:
@@ -32,7 +30,6 @@ biorad_96_wellplate_200ul_pcr:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_12_wellplate_6point9ml_flat: corning_12_wellplate_6point9ml_flat:
category: category:
@@ -44,7 +41,6 @@ corning_12_wellplate_6point9ml_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_24_wellplate_3point4ml_flat: corning_24_wellplate_3point4ml_flat:
category: category:
@@ -56,7 +52,6 @@ corning_24_wellplate_3point4ml_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_384_wellplate_112ul_flat: corning_384_wellplate_112ul_flat:
category: category:
@@ -68,7 +63,6 @@ corning_384_wellplate_112ul_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_48_wellplate_1point6ml_flat: corning_48_wellplate_1point6ml_flat:
category: category:
@@ -80,7 +74,6 @@ corning_48_wellplate_1point6ml_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_6_wellplate_16point8ml_flat: corning_6_wellplate_16point8ml_flat:
category: category:
@@ -92,7 +85,6 @@ corning_6_wellplate_16point8ml_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
corning_96_wellplate_360ul_flat: corning_96_wellplate_360ul_flat:
category: category:
@@ -104,7 +96,6 @@ corning_96_wellplate_360ul_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_96_wellplate_100ul_pcr_full_skirt: nest_96_wellplate_100ul_pcr_full_skirt:
category: category:
@@ -136,7 +127,6 @@ nest_96_wellplate_100ul_pcr_full_skirt:
- 1.5708 - 1.5708
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_96_wellplate_200ul_flat: nest_96_wellplate_200ul_flat:
category: category:
@@ -148,7 +138,6 @@ nest_96_wellplate_200ul_flat:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_96_wellplate_2ml_deep: nest_96_wellplate_2ml_deep:
category: category:
@@ -171,7 +160,6 @@ nest_96_wellplate_2ml_deep:
- 1.5708 - 1.5708
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
thermoscientificnunc_96_wellplate_1300ul: thermoscientificnunc_96_wellplate_1300ul:
category: category:
@@ -183,7 +171,6 @@ thermoscientificnunc_96_wellplate_1300ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
thermoscientificnunc_96_wellplate_2000ul: thermoscientificnunc_96_wellplate_2000ul:
category: category:
@@ -195,7 +182,6 @@ thermoscientificnunc_96_wellplate_2000ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
usascientific_96_wellplate_2point4ml_deep: usascientific_96_wellplate_2point4ml_deep:
category: category:
@@ -207,5 +193,4 @@ usascientific_96_wellplate_2point4ml_deep:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ agilent_1_reservoir_290ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
axygen_1_reservoir_90ml: axygen_1_reservoir_90ml:
category: category:
@@ -20,7 +19,6 @@ axygen_1_reservoir_90ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_12_reservoir_15ml: nest_12_reservoir_15ml:
category: category:
@@ -32,7 +30,6 @@ nest_12_reservoir_15ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_1_reservoir_195ml: nest_1_reservoir_195ml:
category: category:
@@ -44,7 +41,6 @@ nest_1_reservoir_195ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
nest_1_reservoir_290ml: nest_1_reservoir_290ml:
category: category:
@@ -56,7 +52,6 @@ nest_1_reservoir_290ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
usascientific_12_reservoir_22ml: usascientific_12_reservoir_22ml:
category: category:
@@ -68,5 +63,4 @@ usascientific_12_reservoir_22ml:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ eppendorf_96_tiprack_1000ul_eptips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
eppendorf_96_tiprack_10ul_eptips: eppendorf_96_tiprack_10ul_eptips:
category: category:
@@ -20,7 +19,6 @@ eppendorf_96_tiprack_10ul_eptips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
geb_96_tiprack_1000ul: geb_96_tiprack_1000ul:
category: category:
@@ -32,7 +30,6 @@ geb_96_tiprack_1000ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
geb_96_tiprack_10ul: geb_96_tiprack_10ul:
category: category:
@@ -44,7 +41,6 @@ geb_96_tiprack_10ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_filtertiprack_1000ul: opentrons_96_filtertiprack_1000ul:
category: category:
@@ -75,7 +71,6 @@ opentrons_96_filtertiprack_1000ul:
- 1.5708 - 1.5708
path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro path: https://uni-lab.oss-cn-zhangjiakou.aliyuncs.com/uni-lab/resources/tecan_nested_tip_rack/modal.xacro
type: resource type: resource
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_filtertiprack_10ul: opentrons_96_filtertiprack_10ul:
category: category:
@@ -87,7 +82,6 @@ opentrons_96_filtertiprack_10ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_filtertiprack_200ul: opentrons_96_filtertiprack_200ul:
category: category:
@@ -99,7 +93,6 @@ opentrons_96_filtertiprack_200ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_filtertiprack_20ul: opentrons_96_filtertiprack_20ul:
category: category:
@@ -111,7 +104,6 @@ opentrons_96_filtertiprack_20ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_tiprack_1000ul: opentrons_96_tiprack_1000ul:
category: category:
@@ -123,7 +115,6 @@ opentrons_96_tiprack_1000ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_tiprack_10ul: opentrons_96_tiprack_10ul:
category: category:
@@ -135,7 +126,6 @@ opentrons_96_tiprack_10ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_tiprack_20ul: opentrons_96_tiprack_20ul:
category: category:
@@ -147,7 +137,6 @@ opentrons_96_tiprack_20ul:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_tiprack_300ul: opentrons_96_tiprack_300ul:
category: category:

View File

@@ -8,7 +8,6 @@ opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical_acrylic: opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical_acrylic:
category: category:
@@ -20,7 +19,6 @@ opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical_acrylic:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_10_tuberack_nest_4x50ml_6x15ml_conical: opentrons_10_tuberack_nest_4x50ml_6x15ml_conical:
category: category:
@@ -32,7 +30,6 @@ opentrons_10_tuberack_nest_4x50ml_6x15ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_15_tuberack_falcon_15ml_conical: opentrons_15_tuberack_falcon_15ml_conical:
category: category:
@@ -44,7 +41,6 @@ opentrons_15_tuberack_falcon_15ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_15_tuberack_nest_15ml_conical: opentrons_15_tuberack_nest_15ml_conical:
category: category:
@@ -56,7 +52,6 @@ opentrons_15_tuberack_nest_15ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_aluminumblock_generic_2ml_screwcap: opentrons_24_aluminumblock_generic_2ml_screwcap:
category: category:
@@ -68,7 +63,6 @@ opentrons_24_aluminumblock_generic_2ml_screwcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_aluminumblock_nest_1point5ml_snapcap: opentrons_24_aluminumblock_nest_1point5ml_snapcap:
category: category:
@@ -80,7 +74,6 @@ opentrons_24_aluminumblock_nest_1point5ml_snapcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_eppendorf_1point5ml_safelock_snapcap: opentrons_24_tuberack_eppendorf_1point5ml_safelock_snapcap:
category: category:
@@ -92,7 +85,6 @@ opentrons_24_tuberack_eppendorf_1point5ml_safelock_snapcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap: opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap:
category: category:
@@ -104,7 +96,6 @@ opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap_acrylic: opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap_acrylic:
category: category:
@@ -116,7 +107,6 @@ opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap_acrylic:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_generic_0point75ml_snapcap_acrylic: opentrons_24_tuberack_generic_0point75ml_snapcap_acrylic:
category: category:
@@ -128,7 +118,6 @@ opentrons_24_tuberack_generic_0point75ml_snapcap_acrylic:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_generic_2ml_screwcap: opentrons_24_tuberack_generic_2ml_screwcap:
category: category:
@@ -140,7 +129,6 @@ opentrons_24_tuberack_generic_2ml_screwcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_nest_0point5ml_screwcap: opentrons_24_tuberack_nest_0point5ml_screwcap:
category: category:
@@ -152,7 +140,6 @@ opentrons_24_tuberack_nest_0point5ml_screwcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_nest_1point5ml_screwcap: opentrons_24_tuberack_nest_1point5ml_screwcap:
category: category:
@@ -164,7 +151,6 @@ opentrons_24_tuberack_nest_1point5ml_screwcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_nest_1point5ml_snapcap: opentrons_24_tuberack_nest_1point5ml_snapcap:
category: category:
@@ -176,7 +162,6 @@ opentrons_24_tuberack_nest_1point5ml_snapcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_nest_2ml_screwcap: opentrons_24_tuberack_nest_2ml_screwcap:
category: category:
@@ -188,7 +173,6 @@ opentrons_24_tuberack_nest_2ml_screwcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_24_tuberack_nest_2ml_snapcap: opentrons_24_tuberack_nest_2ml_snapcap:
category: category:
@@ -200,7 +184,6 @@ opentrons_24_tuberack_nest_2ml_snapcap:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_6_tuberack_falcon_50ml_conical: opentrons_6_tuberack_falcon_50ml_conical:
category: category:
@@ -212,7 +195,6 @@ opentrons_6_tuberack_falcon_50ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_6_tuberack_nest_50ml_conical: opentrons_6_tuberack_nest_50ml_conical:
category: category:
@@ -224,7 +206,6 @@ opentrons_6_tuberack_nest_50ml_conical:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
opentrons_96_well_aluminum_block: opentrons_96_well_aluminum_block:
category: category:
@@ -236,5 +217,4 @@ opentrons_96_well_aluminum_block:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -29,5 +29,4 @@ container:
side: WEST side: WEST
icon: Flask.webp icon: Flask.webp
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -8,7 +8,6 @@ POST_PROCESS_Raw_1BottleCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
POST_PROCESS_Reaction_1BottleCarrier: POST_PROCESS_Reaction_1BottleCarrier:
category: category:
@@ -20,5 +19,4 @@ POST_PROCESS_Reaction_1BottleCarrier:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,5 +9,4 @@ post_process_deck:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,7 +9,6 @@ PRCXI_30mm_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Adapter: PRCXI_Adapter:
category: category:
@@ -22,7 +21,6 @@ PRCXI_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Deep10_Adapter: PRCXI_Deep10_Adapter:
category: category:
@@ -35,7 +33,6 @@ PRCXI_Deep10_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Deep300_Adapter: PRCXI_Deep300_Adapter:
category: category:
@@ -48,7 +45,6 @@ PRCXI_Deep300_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_PCR_Adapter: PRCXI_PCR_Adapter:
category: category:
@@ -61,7 +57,6 @@ PRCXI_PCR_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Reservoir_Adapter: PRCXI_Reservoir_Adapter:
category: category:
@@ -74,7 +69,6 @@ PRCXI_Reservoir_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Tip10_Adapter: PRCXI_Tip10_Adapter:
category: category:
@@ -87,7 +81,6 @@ PRCXI_Tip10_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Tip1250_Adapter: PRCXI_Tip1250_Adapter:
category: category:
@@ -100,7 +93,6 @@ PRCXI_Tip1250_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_Tip300_Adapter: PRCXI_Tip300_Adapter:
category: category:
@@ -113,5 +105,4 @@ PRCXI_Tip300_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,7 +9,6 @@ PRCXI_48_DeepWell:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_96_DeepWell: PRCXI_96_DeepWell:
category: category:
@@ -22,7 +21,6 @@ PRCXI_96_DeepWell:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_AGenBio_4_troughplate: PRCXI_AGenBio_4_troughplate:
category: category:
@@ -35,7 +33,6 @@ PRCXI_AGenBio_4_troughplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_BioER_96_wellplate: PRCXI_BioER_96_wellplate:
category: category:
@@ -48,7 +45,6 @@ PRCXI_BioER_96_wellplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_BioRad_384_wellplate: PRCXI_BioRad_384_wellplate:
category: category:
@@ -61,7 +57,6 @@ PRCXI_BioRad_384_wellplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_CellTreat_96_wellplate: PRCXI_CellTreat_96_wellplate:
category: category:
@@ -74,7 +69,6 @@ PRCXI_CellTreat_96_wellplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_PCR_Plate_200uL_nonskirted: PRCXI_PCR_Plate_200uL_nonskirted:
category: category:
@@ -87,7 +81,6 @@ PRCXI_PCR_Plate_200uL_nonskirted:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_PCR_Plate_200uL_semiskirted: PRCXI_PCR_Plate_200uL_semiskirted:
category: category:
@@ -100,7 +93,6 @@ PRCXI_PCR_Plate_200uL_semiskirted:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_PCR_Plate_200uL_skirted: PRCXI_PCR_Plate_200uL_skirted:
category: category:
@@ -113,7 +105,6 @@ PRCXI_PCR_Plate_200uL_skirted:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_nest_12_troughplate: PRCXI_nest_12_troughplate:
category: category:
@@ -126,7 +117,6 @@ PRCXI_nest_12_troughplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_nest_1_troughplate: PRCXI_nest_1_troughplate:
category: category:
@@ -139,5 +129,4 @@ PRCXI_nest_1_troughplate:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,7 +9,6 @@ PRCXI_1000uL_Tips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_10uL_Tips: PRCXI_10uL_Tips:
category: category:
@@ -22,7 +21,6 @@ PRCXI_10uL_Tips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_10ul_eTips: PRCXI_10ul_eTips:
category: category:
@@ -35,7 +33,6 @@ PRCXI_10ul_eTips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_1250uL_Tips: PRCXI_1250uL_Tips:
category: category:
@@ -48,7 +45,6 @@ PRCXI_1250uL_Tips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_200uL_Tips: PRCXI_200uL_Tips:
category: category:
@@ -61,7 +57,6 @@ PRCXI_200uL_Tips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0
PRCXI_300ul_Tips: PRCXI_300ul_Tips:
category: category:
@@ -74,5 +69,4 @@ PRCXI_300ul_Tips:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,5 +9,4 @@ PRCXI_trash:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -9,5 +9,4 @@ PRCXI_EP_Adapter:
handles: [] handles: []
icon: '' icon: ''
init_param_schema: {} init_param_schema: {}
registry_type: resource
version: 1.0.0 version: 1.0.0

View File

@@ -599,14 +599,39 @@ def wrap_action_schema(
def preserve_field_descriptions(new_schema: Dict[str, Any], prev_schema: Dict[str, Any]): def preserve_field_descriptions(new_schema: Dict[str, Any], prev_schema: Dict[str, Any]):
"""保留之前 schema 中的 field descriptions""" """递归保留之前 schema 中各字段的 description / title。
覆盖顶层以及嵌套 properties如 goal.properties.xxx.description
"""
if not prev_schema or not new_schema: if not prev_schema or not new_schema:
return return
prev_props = prev_schema.get("properties", {}) prev_props = prev_schema.get("properties", {})
new_props = new_schema.get("properties", {}) new_props = new_schema.get("properties", {})
for field_name, prev_field in prev_props.items(): for field_name, prev_field in prev_props.items():
if field_name in new_props and "title" in prev_field: if field_name not in new_props:
new_props[field_name].setdefault("title", prev_field["title"]) continue
new_field = new_props[field_name]
if not isinstance(prev_field, dict) or not isinstance(new_field, dict):
continue
if "title" in prev_field:
new_field.setdefault("title", prev_field["title"])
if "description" in prev_field:
new_field.setdefault("description", prev_field["description"])
if "properties" in prev_field and "properties" in new_field:
preserve_field_descriptions(new_field, prev_field)
def strip_ros_descriptions(schema: Any):
"""递归清除 ROS schema 中自动生成的无意义 description含 rosidl_parser 内存地址)。"""
if isinstance(schema, dict):
desc = schema.get("description", "")
if isinstance(desc, str) and "rosidl_parser" in desc:
del schema["description"]
for v in schema.values():
strip_ros_descriptions(v)
elif isinstance(schema, list):
for item in schema:
strip_ros_descriptions(item)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@@ -717,6 +717,19 @@ def ros_field_type_to_json_schema(
# return {'type': 'object', 'description': f'未知类型: {field_type}'} # return {'type': 'object', 'description': f'未知类型: {field_type}'}
def _strip_rosidl_descriptions(schema: Any) -> None:
"""递归清除 rosidl_parser 自动生成的无意义 description含内存地址"""
if isinstance(schema, dict):
desc = schema.get("description", "")
if isinstance(desc, str) and "rosidl_parser" in desc:
del schema["description"]
for v in schema.values():
_strip_rosidl_descriptions(v)
elif isinstance(schema, list):
for item in schema:
_strip_rosidl_descriptions(item)
def ros_message_to_json_schema(msg_class: Any, field_name: str) -> Dict[str, Any]: def ros_message_to_json_schema(msg_class: Any, field_name: str) -> Dict[str, Any]:
""" """
将 ROS 消息类转换为 JSON Schema 将 ROS 消息类转换为 JSON Schema
@@ -730,7 +743,8 @@ def ros_message_to_json_schema(msg_class: Any, field_name: str) -> Dict[str, Any
""" """
schema = ROS2MessageInstance(msg_class()).get_json_schema() schema = ROS2MessageInstance(msg_class()).get_json_schema()
schema["title"] = field_name schema["title"] = field_name
schema.pop("description") schema.pop("description", None)
_strip_rosidl_descriptions(schema)
return schema return schema
@@ -777,6 +791,8 @@ def ros_action_to_json_schema(
"required": ["goal"], "required": ["goal"],
} }
_strip_rosidl_descriptions(schema)
# 保留之前 schema 中 goal/feedback/result 下一级字段的 description # 保留之前 schema 中 goal/feedback/result 下一级字段的 description
if previous_schema: if previous_schema:
_preserve_field_descriptions(schema, previous_schema) _preserve_field_descriptions(schema, previous_schema)

View File

@@ -1884,7 +1884,8 @@ class BaseROS2DeviceNode(Node, Generic[T]):
continue continue
# 处理单个 ResourceSlot # 处理单个 ResourceSlot
if arg_type == "unilabos.registry.placeholder_type:ResourceSlot": _is_resource_slot = isinstance(arg_type, str) and arg_type.endswith(":ResourceSlot")
if _is_resource_slot:
resource_data = function_args[arg_name] resource_data = function_args[arg_name]
if isinstance(resource_data, dict) and "id" in resource_data: if isinstance(resource_data, dict) and "id" in resource_data:
try: try:
@@ -1898,8 +1899,7 @@ class BaseROS2DeviceNode(Node, Generic[T]):
# 处理 ResourceSlot 列表 # 处理 ResourceSlot 列表
elif isinstance(arg_type, tuple) and len(arg_type) == 2: elif isinstance(arg_type, tuple) and len(arg_type) == 2:
resource_slot_type = "unilabos.registry.placeholder_type:ResourceSlot" if arg_type[0] == "list" and isinstance(arg_type[1], str) and arg_type[1].endswith(":ResourceSlot"):
if arg_type[0] == "list" and arg_type[1] == resource_slot_type:
resource_list = function_args[arg_name] resource_list = function_args[arg_name]
if isinstance(resource_list, list): if isinstance(resource_list, list):
try: try:

View File

@@ -6,20 +6,180 @@
import argparse import argparse
import importlib import importlib
import locale import locale
import shutil
import subprocess import subprocess
import sys import sys
from pathlib import Path
from typing import List, Optional
from unilabos.utils.banner_print import print_status from unilabos.utils.banner_print import print_status
# ---------------------------------------------------------------------------
# 底层安装工具
# ---------------------------------------------------------------------------
def _is_chinese_locale() -> bool:
try:
lang = locale.getdefaultlocale()[0]
return bool(lang and ("zh" in lang.lower() or "chinese" in lang.lower()))
except Exception:
return False
_USE_UV: Optional[bool] = None
def _has_uv() -> bool:
global _USE_UV
if _USE_UV is None:
_USE_UV = shutil.which("uv") is not None
return _USE_UV
def _install_packages(
packages: List[str],
upgrade: bool = False,
label: str = "",
) -> bool:
"""
安装/升级一组包。优先 uv pip install回退 sys pip。
逐个安装,任意一个失败不影响后续包。
Returns:
True if all succeeded, False otherwise.
"""
if not packages:
return True
is_chinese = _is_chinese_locale()
use_uv = _has_uv()
failed: List[str] = []
for pkg in packages:
action_word = "升级" if upgrade else "安装"
if label:
print_status(f"[{label}] 正在{action_word} {pkg}...", "info")
else:
print_status(f"正在{action_word} {pkg}...", "info")
if use_uv:
cmd = ["uv", "pip", "install"]
if upgrade:
cmd.append("--upgrade")
cmd.append(pkg)
if is_chinese:
cmd.extend(["--index-url", "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"])
else:
cmd = [sys.executable, "-m", "pip", "install"]
if upgrade:
cmd.append("--upgrade")
cmd.append(pkg)
if is_chinese:
cmd.extend(["-i", "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"])
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
if result.returncode == 0:
installer = "uv" if use_uv else "pip"
print_status(f"{pkg} {action_word}成功 (via {installer})", "success")
else:
stderr_short = result.stderr.strip().split("\n")[-1] if result.stderr else "unknown error"
print_status(f"× {pkg} {action_word}失败: {stderr_short}", "error")
failed.append(pkg)
except subprocess.TimeoutExpired:
print_status(f"× {pkg} {action_word}超时 (300s)", "error")
failed.append(pkg)
except Exception as e:
print_status(f"× {pkg} {action_word}异常: {e}", "error")
failed.append(pkg)
if failed:
print_status(f"{len(failed)} 个包操作失败: {', '.join(failed)}", "error")
return False
return True
# ---------------------------------------------------------------------------
# requirements.txt 安装(可多次调用)
# ---------------------------------------------------------------------------
def install_requirements_txt(req_path: str | Path, label: str = "") -> bool:
"""
读取一个 requirements.txt 文件,检查缺失的包并安装。
Args:
req_path: requirements.txt 文件路径
label: 日志前缀标签(如 "device_package_sim"
Returns:
True if all ok, False if any install failed.
"""
req_path = Path(req_path)
if not req_path.exists():
return True
tag = label or req_path.parent.name
print_status(f"[{tag}] 检查依赖: {req_path}", "info")
reqs: List[str] = []
with open(req_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#") and not line.startswith("-"):
reqs.append(line)
if not reqs:
return True
missing: List[str] = []
for req in reqs:
pkg_import = req.split(">=")[0].split("==")[0].split("<")[0].split("[")[0].split(">")[0].strip()
pkg_import = pkg_import.replace("-", "_")
try:
importlib.import_module(pkg_import)
except ImportError:
missing.append(req)
if not missing:
print_status(f"[{tag}] ✓ 依赖检查通过 ({len(reqs)} 个包)", "success")
return True
print_status(f"[{tag}] 缺失 {len(missing)} 个依赖: {', '.join(missing)}", "warning")
return _install_packages(missing, label=tag)
def check_device_package_requirements(devices_dirs: list[str]) -> bool:
"""
检查 --devices 指定的所有外部设备包目录中的 requirements.txt。
对每个目录查找 requirements.txt先在目录内找再在父目录找
"""
if not devices_dirs:
return True
all_ok = True
for d in devices_dirs:
d_path = Path(d).resolve()
req_file = d_path / "requirements.txt"
if not req_file.exists():
req_file = d_path.parent / "requirements.txt"
if not req_file.exists():
continue
if not install_requirements_txt(req_file, label=d_path.name):
all_ok = False
return all_ok
# ---------------------------------------------------------------------------
# UniLabOS 核心环境检查
# ---------------------------------------------------------------------------
class EnvironmentChecker: class EnvironmentChecker:
"""环境检查器""" """环境检查器"""
def __init__(self): def __init__(self):
# 定义必需的包及其安装名称的映射
self.required_packages = { self.required_packages = {
# 包导入名 : pip安装名
# "pymodbus.framer.FramerType": "pymodbus==3.9.2",
"websockets": "websockets", "websockets": "websockets",
"msgcenterpy": "msgcenterpy", "msgcenterpy": "msgcenterpy",
"orjson": "orjson", "orjson": "orjson",
@@ -28,33 +188,17 @@ class EnvironmentChecker:
"crcmod": "crcmod-plus", "crcmod": "crcmod-plus",
} }
# 特殊安装包(需要特殊处理的包)
self.special_packages = {"pylabrobot": "git+https://github.com/Xuwznln/pylabrobot.git"} self.special_packages = {"pylabrobot": "git+https://github.com/Xuwznln/pylabrobot.git"}
# 包版本要求(包名: 最低版本)
self.version_requirements = { self.version_requirements = {
"msgcenterpy": "0.1.7", # msgcenterpy 最低版本要求 "msgcenterpy": "0.1.8",
} }
self.missing_packages = [] self.missing_packages: List[tuple] = []
self.failed_installs = [] self.failed_installs: List[tuple] = []
self.packages_need_upgrade = [] self.packages_need_upgrade: List[tuple] = []
# 检测系统语言
self.is_chinese = self._is_chinese_locale()
def _is_chinese_locale(self) -> bool:
"""检测系统是否为中文环境"""
try:
lang = locale.getdefaultlocale()[0]
if lang and ("zh" in lang.lower() or "chinese" in lang.lower()):
return True
except Exception:
pass
return False
def check_package_installed(self, package_name: str) -> bool: def check_package_installed(self, package_name: str) -> bool:
"""检查包是否已安装"""
try: try:
importlib.import_module(package_name) importlib.import_module(package_name)
return True return True
@@ -62,7 +206,6 @@ class EnvironmentChecker:
return False return False
def get_package_version(self, package_name: str) -> str | None: def get_package_version(self, package_name: str) -> str | None:
"""获取已安装包的版本"""
try: try:
module = importlib.import_module(package_name) module = importlib.import_module(package_name)
return getattr(module, "__version__", None) return getattr(module, "__version__", None)
@@ -70,88 +213,32 @@ class EnvironmentChecker:
return None return None
def compare_version(self, current: str, required: str) -> bool: def compare_version(self, current: str, required: str) -> bool:
"""
比较版本号
Returns:
True: current >= required
False: current < required
"""
try: try:
current_parts = [int(x) for x in current.split(".")] current_parts = [int(x) for x in current.split(".")]
required_parts = [int(x) for x in required.split(".")] required_parts = [int(x) for x in required.split(".")]
# 补齐长度
max_len = max(len(current_parts), len(required_parts)) max_len = max(len(current_parts), len(required_parts))
current_parts.extend([0] * (max_len - len(current_parts))) current_parts.extend([0] * (max_len - len(current_parts)))
required_parts.extend([0] * (max_len - len(required_parts))) required_parts.extend([0] * (max_len - len(required_parts)))
return current_parts >= required_parts return current_parts >= required_parts
except Exception: except Exception:
return True # 如果无法比较,假设版本满足要求 return True
def install_package(self, package_name: str, pip_name: str, upgrade: bool = False) -> bool:
"""安装包"""
try:
action = "升级" if upgrade else "安装"
print_status(f"正在{action} {package_name} ({pip_name})...", "info")
# 构建安装命令
cmd = [sys.executable, "-m", "pip", "install"]
# 如果是升级操作,添加 --upgrade 参数
if upgrade:
cmd.append("--upgrade")
cmd.append(pip_name)
# 如果是中文环境,使用清华镜像源
if self.is_chinese:
cmd.extend(["-i", "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"])
# 执行安装
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) # 5分钟超时
if result.returncode == 0:
print_status(f"{package_name} {action}成功", "success")
return True
else:
print_status(f"× {package_name} {action}失败: {result.stderr}", "error")
return False
except subprocess.TimeoutExpired:
print_status(f"× {package_name} {action}超时", "error")
return False
except Exception as e:
print_status(f"× {package_name} {action}异常: {str(e)}", "error")
return False
def upgrade_package(self, package_name: str, pip_name: str) -> bool:
"""升级包"""
return self.install_package(package_name, pip_name, upgrade=True)
def check_all_packages(self) -> bool: def check_all_packages(self) -> bool:
"""检查所有必需的包"""
print_status("开始检查环境依赖...", "info") print_status("开始检查环境依赖...", "info")
# 检查常规包
for import_name, pip_name in self.required_packages.items(): for import_name, pip_name in self.required_packages.items():
if not self.check_package_installed(import_name): if not self.check_package_installed(import_name):
self.missing_packages.append((import_name, pip_name)) self.missing_packages.append((import_name, pip_name))
else: elif import_name in self.version_requirements:
# 检查版本要求 current_version = self.get_package_version(import_name)
if import_name in self.version_requirements: required_version = self.version_requirements[import_name]
current_version = self.get_package_version(import_name) if current_version and not self.compare_version(current_version, required_version):
required_version = self.version_requirements[import_name] print_status(
f"{import_name} 版本过低 (当前: {current_version}, 需要: >={required_version})",
"warning",
)
self.packages_need_upgrade.append((import_name, pip_name))
if current_version:
if not self.compare_version(current_version, required_version):
print_status(
f"{import_name} 版本过低 (当前: {current_version}, 需要: >={required_version})",
"warning",
)
self.packages_need_upgrade.append((import_name, pip_name))
# 检查特殊包
for package_name, install_url in self.special_packages.items(): for package_name, install_url in self.special_packages.items():
if not self.check_package_installed(package_name): if not self.check_package_installed(package_name):
self.missing_packages.append((package_name, install_url)) self.missing_packages.append((package_name, install_url))
@@ -170,7 +257,6 @@ class EnvironmentChecker:
return False return False
def install_missing_packages(self, auto_install: bool = True) -> bool: def install_missing_packages(self, auto_install: bool = True) -> bool:
"""安装缺失的包"""
if not self.missing_packages and not self.packages_need_upgrade: if not self.missing_packages and not self.packages_need_upgrade:
return True return True
@@ -178,62 +264,36 @@ class EnvironmentChecker:
if self.missing_packages: if self.missing_packages:
print_status("缺失以下包:", "warning") print_status("缺失以下包:", "warning")
for import_name, pip_name in self.missing_packages: for import_name, pip_name in self.missing_packages:
print_status(f" - {import_name} (pip install {pip_name})", "warning") print_status(f" - {import_name} ({pip_name})", "warning")
if self.packages_need_upgrade: if self.packages_need_upgrade:
print_status("需要升级以下包:", "warning") print_status("需要升级以下包:", "warning")
for import_name, pip_name in self.packages_need_upgrade: for import_name, pip_name in self.packages_need_upgrade:
print_status(f" - {import_name} (pip install --upgrade {pip_name})", "warning") print_status(f" - {import_name} ({pip_name})", "warning")
return False return False
# 安装缺失的包
if self.missing_packages: if self.missing_packages:
print_status(f"开始自动安装 {len(self.missing_packages)} 个缺失的包...", "info") pkgs = [pip_name for _, pip_name in self.missing_packages]
if not _install_packages(pkgs, label="unilabos"):
self.failed_installs.extend(self.missing_packages)
success_count = 0
for import_name, pip_name in self.missing_packages:
if self.install_package(import_name, pip_name):
success_count += 1
else:
self.failed_installs.append((import_name, pip_name))
print_status(f"✓ 成功安装 {success_count}/{len(self.missing_packages)} 个包", "success")
# 升级需要更新的包
if self.packages_need_upgrade: if self.packages_need_upgrade:
print_status(f"开始自动升级 {len(self.packages_need_upgrade)} 个包...", "info") pkgs = [pip_name for _, pip_name in self.packages_need_upgrade]
if not _install_packages(pkgs, upgrade=True, label="unilabos"):
self.failed_installs.extend(self.packages_need_upgrade)
upgrade_success_count = 0 return not self.failed_installs
for import_name, pip_name in self.packages_need_upgrade:
if self.upgrade_package(import_name, pip_name):
upgrade_success_count += 1
else:
self.failed_installs.append((import_name, pip_name))
print_status(f"✓ 成功升级 {upgrade_success_count}/{len(self.packages_need_upgrade)} 个包", "success")
if self.failed_installs:
print_status(f"{len(self.failed_installs)} 个包操作失败:", "error")
for import_name, pip_name in self.failed_installs:
print_status(f" - {import_name} ({pip_name})", "error")
return False
return True
def verify_installation(self) -> bool: def verify_installation(self) -> bool:
"""验证安装结果"""
if not self.missing_packages and not self.packages_need_upgrade: if not self.missing_packages and not self.packages_need_upgrade:
return True return True
print_status("验证安装结果...", "info") print_status("验证安装结果...", "info")
failed_verification = [] failed_verification = []
# 验证新安装的包
for import_name, pip_name in self.missing_packages: for import_name, pip_name in self.missing_packages:
if not self.check_package_installed(import_name): if not self.check_package_installed(import_name):
failed_verification.append((import_name, pip_name)) failed_verification.append((import_name, pip_name))
# 验证升级的包
for import_name, pip_name in self.packages_need_upgrade: for import_name, pip_name in self.packages_need_upgrade:
if not self.check_package_installed(import_name): if not self.check_package_installed(import_name):
failed_verification.append((import_name, pip_name)) failed_verification.append((import_name, pip_name))
@@ -270,17 +330,14 @@ def check_environment(auto_install: bool = True, show_details: bool = True) -> b
""" """
checker = EnvironmentChecker() checker = EnvironmentChecker()
# 检查包
if checker.check_all_packages(): if checker.check_all_packages():
return True return True
# 安装缺失的包
if not checker.install_missing_packages(auto_install): if not checker.install_missing_packages(auto_install):
if show_details: if show_details:
print_status("请手动安装缺失的包后重新启动程序", "error") print_status("请手动安装缺失的包后重新启动程序", "error")
return False return False
# 验证安装
if not checker.verify_installation(): if not checker.verify_installation():
if show_details: if show_details:
print_status("安装验证失败,请检查网络连接或手动安装", "error") print_status("安装验证失败,请检查网络连接或手动安装", "error")
@@ -290,14 +347,12 @@ def check_environment(auto_install: bool = True, show_details: bool = True) -> b
if __name__ == "__main__": if __name__ == "__main__":
# 命令行参数解析
parser = argparse.ArgumentParser(description="UniLabOS 环境依赖检查工具") parser = argparse.ArgumentParser(description="UniLabOS 环境依赖检查工具")
parser.add_argument("--no-auto-install", action="store_true", help="仅检查环境,不自动安装缺失的包") parser.add_argument("--no-auto-install", action="store_true", help="仅检查环境,不自动安装缺失的包")
parser.add_argument("--silent", action="store_true", help="静默模式,不显示详细信息") parser.add_argument("--silent", action="store_true", help="静默模式,不显示详细信息")
args = parser.parse_args() args = parser.parse_args()
# 执行环境检查
auto_install = not args.no_auto_install auto_install = not args.no_auto_install
show_details = not args.silent show_details = not args.silent

View File

@@ -21,15 +21,11 @@ __all__ = [
"get_class", "get_class",
"get_module", "get_module",
"init_from_list", "init_from_list",
"get_class_info_static", "get_enhanced_class_info",
"get_registry_class_info",
] ]
from ast import Constant
from unilabos.resources.resource_tracker import PARAM_SAMPLE_UUIDS from unilabos.resources.resource_tracker import PARAM_SAMPLE_UUIDS
from unilabos.utils import logger from unilabos.utils import logger
from unilabos.registry.decorators import is_not_action, is_always_free
class ImportManager: class ImportManager:
@@ -45,6 +41,7 @@ class ImportManager:
self._modules: Dict[str, Any] = {} self._modules: Dict[str, Any] = {}
self._classes: Dict[str, Type] = {} self._classes: Dict[str, Type] = {}
self._functions: Dict[str, Callable] = {} self._functions: Dict[str, Callable] = {}
self._search_miss: set = set()
if module_list: if module_list:
for module_path in module_list: for module_path in module_list:
@@ -159,193 +156,113 @@ class ImportManager:
Returns: Returns:
找到的类对象如果未找到则返回None 找到的类对象如果未找到则返回None
""" """
# 如果cls_name是builtins中的关键字则返回对应类
if class_name in builtins.__dict__: if class_name in builtins.__dict__:
return builtins.__dict__[class_name] return builtins.__dict__[class_name]
# 首先在已索引的类中查找
if class_name in self._classes: if class_name in self._classes:
return self._classes[class_name] return self._classes[class_name]
cache_key = class_name.lower() if search_lower else class_name
if cache_key in self._search_miss:
return None
if search_lower: if search_lower:
classes = {name.lower(): obj for name, obj in self._classes.items()} classes = {name.lower(): obj for name, obj in self._classes.items()}
if class_name in classes: if class_name in classes:
return classes[class_name] return classes[class_name]
# 遍历所有已加载的模块进行搜索
for module_path, module in self._modules.items(): for module_path, module in self._modules.items():
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
if inspect.isclass(obj) and ( if inspect.isclass(obj) and (
(name.lower() == class_name.lower()) if search_lower else (name == class_name) (name.lower() == class_name.lower()) if search_lower else (name == class_name)
): ):
# 将找到的类添加到索引中
self._classes[name] = obj self._classes[name] = obj
self._classes[f"{module_path}:{name}"] = obj self._classes[f"{module_path}:{name}"] = obj
return obj return obj
self._search_miss.add(cache_key)
return None return None
def get_enhanced_class_info(self, module_path: str, use_dynamic: bool = True) -> Dict[str, Any]: def get_enhanced_class_info(self, module_path: str, **_kwargs) -> Dict[str, Any]:
""" """通过 AST 分析获取类的增强信息。
获取增强的类信息,支持动态导入和静态分析
复用 ``ast_registry_scanner`` 的 ``_collect_imports`` / ``_extract_class_body``
与 AST 扫描注册表完全一致。
Args: Args:
module_path: 模块路径,格式为 "module.path""module.path:ClassName" module_path: 格式 ``"module.path:ClassName"``
use_dynamic: 是否优先使用动态导入
Returns: Returns:
包含详细类信息的字典 ``{"module_path", "ast_analysis_success", "import_map",
"init_params", "status_methods", "action_methods"}``
""" """
result = { from unilabos.registry.ast_registry_scanner import (
_collect_imports,
_extract_class_body,
_filepath_to_module,
)
result: Dict[str, Any] = {
"module_path": module_path, "module_path": module_path,
"dynamic_import_success": False, "ast_analysis_success": False,
"static_analysis_success": False, "import_map": {},
"init_params": {}, "init_params": [],
"status_methods": {}, # get_ 开头和 @property 方法
"action_methods": {}, # set_ 开头和其他非_开头方法
}
# 尝试动态导入
dynamic_info = None
static_info = None
if use_dynamic:
try:
dynamic_info = self._get_dynamic_class_info(module_path)
result["dynamic_import_success"] = True
logger.debug(f"[ImportManager] 动态导入类 {module_path} 成功")
except Exception as e:
logger.warning(
f"[UniLab Registry] 在补充注册表时,动态导入类 "
f"{module_path} 失败(将使用静态分析,"
f"建议修复导入错误,以实现更好的注册表识别效果!): {e}"
)
use_dynamic = False
if not use_dynamic:
# 尝试静态分析
try:
static_info = self._get_static_class_info(module_path)
result["static_analysis_success"] = True
logger.debug(f"[ImportManager] 静态分析类 {module_path} 成功")
except Exception as e:
logger.warning(f"[ImportManager] 静态分析类 {module_path} 失败: {e}")
# 合并信息(优先使用动态导入的信息)
if dynamic_info:
result.update(dynamic_info)
elif static_info:
result.update(static_info)
return result
def _get_dynamic_class_info(self, class_path: str) -> Dict[str, Any]:
"""使用inspect模块动态获取类信息"""
cls = get_class(class_path)
class_name = cls.__name__
result = {
"class_name": class_name,
"init_params": self._analyze_method_signature(cls.__init__)["args"],
"status_methods": {}, "status_methods": {},
"action_methods": {}, "action_methods": {},
} }
# 分析类的所有成员
for name, method in cls.__dict__.items():
if name.startswith("_"):
continue
# 检查是否是property
if isinstance(method, property):
# @property 装饰的方法
# noinspection PyTypeChecker
return_type = self._get_return_type_from_method(method.fget) if method.fget else "Any"
prop_info = {
"name": name,
"return_type": return_type,
}
result["status_methods"][name] = prop_info
# 检查是否有对应的setter
if method.fset:
setter_info = self._analyze_method_signature(method.fset)
result["action_methods"][name] = setter_info
elif inspect.ismethod(method) or inspect.isfunction(method):
if name.startswith("get_"):
actual_name = name[4:] # 去掉get_前缀
if actual_name in result["status_methods"]:
continue
# get_ 开头的方法归类为status
method_info = self._analyze_method_signature(method)
result["status_methods"][actual_name] = method_info
elif not name.startswith("_"):
# 检查是否被 @not_action 装饰器标记
if is_not_action(method):
continue
# 其他非_开头的方法归类为action
method_info = self._analyze_method_signature(method)
# 检查是否被 @always_free 装饰器标记
if is_always_free(method):
method_info["always_free"] = True
result["action_methods"][name] = method_info
return result
def _get_static_class_info(self, module_path: str) -> Dict[str, Any]:
"""使用AST静态分析获取类信息"""
module_name, class_name = module_path.rsplit(":", 1) module_name, class_name = module_path.rsplit(":", 1)
# 将模块路径转换为文件路径
file_path = self._module_path_to_file_path(module_name) file_path = self._module_path_to_file_path(module_name)
if not file_path or not os.path.exists(file_path): if not file_path or not os.path.exists(file_path):
raise FileNotFoundError(f"找不到模块文件: {module_name} -> {file_path}") logger.warning(f"[ImportManager] 找不到模块文件: {module_name} -> {file_path}")
return result
with open(file_path, "r", encoding="utf-8") as f: try:
source_code = f.read() with open(file_path, "r", encoding="utf-8") as f:
tree = ast.parse(f.read(), filename=file_path)
except Exception as e:
logger.warning(f"[ImportManager] 解析文件 {file_path} 失败: {e}")
return result
tree = ast.parse(source_code) # 推导 module dotted path → 构建 import_map
python_path = Path(file_path)
for sp in sorted(sys.path, key=len, reverse=True):
try:
Path(file_path).relative_to(sp)
python_path = Path(sp)
break
except ValueError:
continue
module_dotted = _filepath_to_module(Path(file_path), python_path)
import_map = _collect_imports(tree, module_dotted)
result["import_map"] = import_map
# 查找目标类 # 定位目标类 AST 节点
target_class = None target_class = None
for node in ast.walk(tree): for node in ast.walk(tree):
if isinstance(node, ast.ClassDef): if isinstance(node, ast.ClassDef) and node.name == class_name:
if node.name == class_name: target_class = node
target_class = node break
break
if target_class is None: if target_class is None:
raise AttributeError(f"在文件 {file_path} 中找不到类 {class_name}") logger.warning(f"[ImportManager] 在文件 {file_path} 中找不到类 {class_name}")
return result
result = { body = _extract_class_body(target_class, import_map)
"class_name": class_name,
"init_params": {}, # 映射到统一字段名(与 registry.py complete_registry 消费端一致)
"status_methods": {}, result["init_params"] = body.get("init_params", [])
"action_methods": {}, result["status_methods"] = body.get("status_properties", {})
result["action_methods"] = {
k: {
"args": v.get("params", []),
"return_type": v.get("return_type", ""),
"is_async": v.get("is_async", False),
"always_free": v.get("always_free", False),
"docstring": v.get("docstring"),
}
for k, v in body.get("auto_methods", {}).items()
} }
result["ast_analysis_success"] = True
# 分析类的方法
for node in target_class.body:
if isinstance(node, ast.FunctionDef):
method_info = self._analyze_method_node(node)
method_name = node.name
if method_name == "__init__":
result["init_params"] = method_info["args"]
elif method_name.startswith("_"):
continue
elif self._is_property_method(node):
# @property 装饰的方法
result["status_methods"][method_name] = method_info
elif method_name.startswith("get_"):
# get_ 开头的方法归类为status
actual_name = method_name[4:] # 去掉get_前缀
if actual_name not in result["status_methods"]:
result["status_methods"][actual_name] = method_info
else:
# 检查是否被 @not_action 装饰器标记
if self._is_not_action_method(node):
continue
# 其他非_开头的方法归类为action
# 检查是否被 @always_free 装饰器标记
if self._is_always_free_method(node):
method_info["always_free"] = True
result["action_methods"][method_name] = method_info
return result return result
def _analyze_method_signature(self, method, skip_unilabos_params: bool = True) -> Dict[str, Any]: def _analyze_method_signature(self, method, skip_unilabos_params: bool = True) -> Dict[str, Any]:
@@ -401,23 +318,26 @@ class ImportManager:
"name": method.__name__, "name": method.__name__,
"args": args, "args": args,
"return_type": self._get_type_string(signature.return_annotation), "return_type": self._get_type_string(signature.return_annotation),
"return_annotation": signature.return_annotation, # 保留原始类型注解用于TypedDict等特殊处理
"is_async": inspect.iscoroutinefunction(method), "is_async": inspect.iscoroutinefunction(method),
} }
def _get_return_type_from_method(self, method) -> str: def _get_return_type_from_method(self, method) -> Union[str, Tuple[str, Any]]:
"""从方法中获取返回类型""" """从方法中获取返回类型"""
signature = inspect.signature(method) signature = inspect.signature(method)
return self._get_type_string(signature.return_annotation) return self._get_type_string(signature.return_annotation)
def _get_type_string(self, annotation) -> Union[str, Tuple[str, Any]]: def _get_type_string(self, annotation) -> Union[str, Tuple[str, Any]]:
"""将类型注解转换为Class Library中可搜索的类名""" """将类型注解转换为类型字符串。
非内建类返回 ``module:ClassName`` 全路径(如
``"unilabos.registry.placeholder_type:ResourceSlot"``
避免短名冲突;内建类型直接返回短名(如 ``"str"``、``"int"``)。
"""
if annotation == inspect.Parameter.empty: if annotation == inspect.Parameter.empty:
return "Any" # 如果没有注解返回Any return "Any"
if annotation is None: if annotation is None:
return "None" # 明确的None类型 return "None"
if hasattr(annotation, "__origin__"): if hasattr(annotation, "__origin__"):
# 处理typing模块的类型
origin = annotation.__origin__ origin = annotation.__origin__
if origin in (list, set, tuple): if origin in (list, set, tuple):
if hasattr(annotation, "__args__") and annotation.__args__: if hasattr(annotation, "__args__") and annotation.__args__:
@@ -432,132 +352,26 @@ class ImportManager:
return "dict" return "dict"
elif origin is Optional: elif origin is Optional:
return "Unknown" return "Unknown"
return f"Unknown" return "Unknown"
annotation_str = str(annotation) annotation_str = str(annotation)
# 处理typing模块的复杂类型
if "typing." in annotation_str: if "typing." in annotation_str:
# 简化typing类型显示
return ( return (
annotation_str.replace("typing.", "") annotation_str.replace("typing.", "")
if getattr(annotation, "_name", None) is None if getattr(annotation, "_name", None) is None
else annotation._name.lower() else annotation._name.lower()
) )
# 如果是类型对象
if hasattr(annotation, "__name__"): if hasattr(annotation, "__name__"):
# 如果是内置类型 module = getattr(annotation, "__module__", None)
if annotation.__module__ == "builtins": if module and module != "builtins":
return annotation.__name__ return f"{module}:{annotation.__name__}"
else: return annotation.__name__
# 如果是自定义类,返回完整路径
return f"{annotation.__module__}:{annotation.__name__}"
# 如果是typing模块的类型
elif hasattr(annotation, "_name"): elif hasattr(annotation, "_name"):
return annotation._name return annotation._name
# 如果是字符串形式的类型注解
elif isinstance(annotation, str): elif isinstance(annotation, str):
return annotation return annotation
else: else:
return annotation_str return annotation_str
def _is_property_method(self, node: ast.FunctionDef) -> bool:
"""检查是否是@property装饰的方法"""
for decorator in node.decorator_list:
if isinstance(decorator, ast.Name) and decorator.id == "property":
return True
return False
def _is_setter_method(self, node: ast.FunctionDef) -> bool:
"""检查是否是@xxx.setter装饰的方法"""
for decorator in node.decorator_list:
if isinstance(decorator, ast.Attribute) and decorator.attr == "setter":
return True
return False
def _is_not_action_method(self, node: ast.FunctionDef) -> bool:
"""检查是否是@not_action装饰的方法"""
for decorator in node.decorator_list:
if isinstance(decorator, ast.Name) and decorator.id == "not_action":
return True
return False
def _is_always_free_method(self, node: ast.FunctionDef) -> bool:
"""检查是否是@always_free装饰的方法或 @action(always_free=True) 装饰的方法"""
for decorator in node.decorator_list:
# 检查 @action(always_free=True)
if isinstance(decorator, ast.Call):
func = decorator.func
if isinstance(func, ast.Name) and func.id == "action":
for keyword in decorator.keywords:
if keyword.arg == "always_free":
if isinstance(keyword.value, Constant) and keyword.value.value is True:
return True
return False
def _get_property_name_from_setter(self, node: ast.FunctionDef) -> str:
"""从setter装饰器中获取属性名"""
for decorator in node.decorator_list:
if isinstance(decorator, ast.Attribute) and decorator.attr == "setter":
if isinstance(decorator.value, ast.Name):
return decorator.value.id
return node.name
def get_class_info_static(self, module_class_path: str) -> Dict[str, Any]:
"""
静态分析获取类的方法信息,不需要实际导入模块
Args:
module_class_path: 格式为 "module.path:ClassName" 的字符串
Returns:
包含类方法信息的字典
"""
try:
if ":" not in module_class_path:
raise ValueError("module_class_path必须是 'module.path:ClassName' 格式")
module_path, class_name = module_class_path.rsplit(":", 1)
# 将模块路径转换为文件路径
file_path = self._module_path_to_file_path(module_path)
if not file_path or not os.path.exists(file_path):
logger.warning(f"找不到模块文件: {module_path} -> {file_path}")
return {}
# 解析源码
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = ast.parse(source_code)
# 查找目标类
class_node = None
for node in ast.walk(tree):
if isinstance(node, ast.ClassDef) and node.name == class_name:
class_node = node
break
if not class_node:
logger.warning(f"在模块 {module_path} 中找不到类 {class_name}")
return {}
# 分析类的方法
methods_info = {}
for node in class_node.body:
if isinstance(node, ast.FunctionDef):
method_info = self._analyze_method_node(node)
methods_info[node.name] = method_info
return {
"class_name": class_name,
"module_path": module_path,
"file_path": file_path,
"methods": methods_info,
}
except Exception as e:
logger.error(f"静态分析类 {module_class_path} 时出错: {str(e)}")
return {}
def _module_path_to_file_path(self, module_path: str) -> Optional[str]: def _module_path_to_file_path(self, module_path: str) -> Optional[str]:
for path in sys.path: for path in sys.path:
potential_path = Path(path) / module_path.replace(".", "/") potential_path = Path(path) / module_path.replace(".", "/")
@@ -572,222 +386,6 @@ class ImportManager:
return None return None
def _analyze_method_node(self, node: ast.FunctionDef) -> Dict[str, Any]:
"""分析方法节点,提取参数和返回类型信息"""
method_info = {
"name": node.name,
"args": [],
"return_type": None,
"is_async": isinstance(node, ast.AsyncFunctionDef),
}
# 获取默认值列表
defaults = node.args.defaults
num_defaults = len(defaults)
# 计算必需参数数量
total_args = len(node.args.args)
num_required = total_args - num_defaults
# 提取参数信息
for i, arg in enumerate(node.args.args):
if arg.arg == "self":
continue
# 跳过 sample_uuids 参数(由系统自动注入)
if arg.arg == PARAM_SAMPLE_UUIDS:
continue
arg_info = {
"name": arg.arg,
"type": None,
"default": None,
"required": i < num_required,
}
# 提取类型注解
if arg.annotation:
arg_info["type"] = ast.unparse(arg.annotation) if hasattr(ast, "unparse") else str(arg.annotation)
# 提取默认值并推断类型
if i >= num_required:
default_index = i - num_required
if default_index < len(defaults):
default_value: Constant = defaults[default_index] # type: ignore
assert isinstance(default_value, Constant), "暂不支持对非常量类型进行推断,可反馈开源仓库"
arg_info["default"] = default_value.value
# 如果没有类型注解,尝试从默认值推断类型
if not arg_info["type"]:
arg_info["type"] = self._get_type_string(type(arg_info["default"]))
method_info["args"].append(arg_info)
# 提取返回类型
if node.returns:
method_info["return_type"] = ast.unparse(node.returns) if hasattr(ast, "unparse") else str(node.returns)
return method_info
def _infer_type_from_default(self, node: ast.AST) -> Optional[str]:
"""从默认值推断参数类型"""
if isinstance(node, ast.Constant):
value = node.value
if isinstance(value, bool):
return "bool"
elif isinstance(value, int):
return "int"
elif isinstance(value, float):
return "float"
elif isinstance(value, str):
return "str"
elif value is None:
return "Optional[Any]"
elif isinstance(node, ast.List):
return "List"
elif isinstance(node, ast.Dict):
return "Dict"
elif isinstance(node, ast.Tuple):
return "Tuple"
elif isinstance(node, ast.Set):
return "Set"
elif isinstance(node, ast.Name):
# 常见的默认值模式
if node.id in ["None"]:
return "Optional[Any]"
elif node.id in ["True", "False"]:
return "bool"
return None
def _infer_types_from_docstring(self, method_info: Dict[str, Any]) -> None:
"""从docstring中推断参数类型"""
docstring = method_info.get("docstring", "")
if not docstring:
return
lines = docstring.split("\n")
in_args_section = False
for line in lines:
line = line.strip()
# 检测Args或Arguments段落
if line.lower().startswith(("args:", "arguments:")):
in_args_section = True
continue
elif line.startswith(("returns:", "return:", "yields:", "raises:")):
in_args_section = False
continue
elif not line or not in_args_section:
continue
# 解析参数行,格式通常是: param_name (type): description 或 param_name: description
if ":" in line:
parts = line.split(":", 1)
param_part = parts[0].strip()
# 提取参数名和类型
param_name = None
param_type = None
if "(" in param_part and ")" in param_part:
# 格式: param_name (type)
param_name = param_part.split("(")[0].strip()
type_part = param_part.split("(")[1].split(")")[0].strip()
param_type = type_part
else:
# 格式: param_name
param_name = param_part
# 更新对应参数的类型信息
if param_name:
for arg_info in method_info["args"]:
if arg_info["name"] == param_name and not arg_info["type"]:
if param_type:
arg_info["inferred_type"] = param_type
elif not arg_info["inferred_type"]:
# 从描述中推断类型
description = parts[1].strip().lower()
if any(word in description for word in ["path", "file", "directory", "filename"]):
arg_info["inferred_type"] = "str"
elif any(
word in description for word in ["port", "number", "count", "size", "length"]
):
arg_info["inferred_type"] = "int"
elif any(
word in description for word in ["rate", "ratio", "percentage", "temperature"]
):
arg_info["inferred_type"] = "float"
elif any(word in description for word in ["flag", "enable", "disable", "option"]):
arg_info["inferred_type"] = "bool"
def get_registry_class_info(self, module_class_path: str) -> Dict[str, Any]:
"""
获取适用于注册表的类信息,包含完整的类型推断
Args:
module_class_path: 格式为 "module.path:ClassName" 的字符串
Returns:
适用于注册表的类信息字典
"""
class_info = self.get_class_info_static(module_class_path)
if not class_info:
return {}
registry_info = {
"class_name": class_info["class_name"],
"module_path": class_info["module_path"],
"file_path": class_info["file_path"],
"methods": {},
"properties": [],
"init_params": {},
"action_methods": {},
}
for method_name, method_info in class_info["methods"].items():
# 分类处理不同类型的方法
if method_info["is_property"]:
registry_info["properties"].append(
{
"name": method_name,
"return_type": method_info.get("return_type"),
"docstring": method_info.get("docstring"),
}
)
elif method_name == "__init__":
# 处理初始化参数
init_params = {}
for arg in method_info["args"]:
if arg["name"] != "self":
param_info = {
"name": arg["name"],
"type": arg.get("type") or arg.get("inferred_type"),
"required": arg.get("is_required", True),
"default": arg.get("default"),
}
init_params[arg["name"]] = param_info
registry_info["init_params"] = init_params
elif not method_name.startswith("_"):
# 处理公共方法可能的action方法
action_info = {
"name": method_name,
"params": {},
"return_type": method_info.get("return_type"),
"docstring": method_info.get("docstring"),
"num_required": method_info.get("num_required", 0) - 1, # 减去self
"num_defaults": method_info.get("num_defaults", 0),
}
for arg in method_info["args"]:
if arg["name"] != "self":
param_info = {
"name": arg["name"],
"type": arg.get("type") or arg.get("inferred_type"),
"required": arg.get("is_required", True),
"default": arg.get("default"),
}
action_info["params"][arg["name"]] = param_info
registry_info["action_methods"][method_name] = action_info
return registry_info
# 全局实例,便于直接使用 # 全局实例,便于直接使用
@@ -815,16 +413,6 @@ def init_from_list(module_list: List[str]) -> None:
default_manager = ImportManager(module_list) default_manager = ImportManager(module_list)
def get_class_info_static(module_class_path: str) -> Dict[str, Any]: def get_enhanced_class_info(module_path: str, **kwargs) -> Dict[str, Any]:
"""静态分析获取类信息的便捷函数"""
return default_manager.get_class_info_static(module_class_path)
def get_registry_class_info(module_class_path: str) -> Dict[str, Any]:
"""获取适用于注册表的类信息的便捷函数"""
return default_manager.get_registry_class_info(module_class_path)
def get_enhanced_class_info(module_path: str, use_dynamic: bool = True) -> Dict[str, Any]:
"""获取增强的类信息的便捷函数""" """获取增强的类信息的便捷函数"""
return default_manager.get_enhanced_class_info(module_path, use_dynamic) return default_manager.get_enhanced_class_info(module_path, **kwargs)

View File

@@ -1,7 +1,7 @@
networkx networkx
typing_extensions typing_extensions
websockets websockets
msgcenterpy>=0.1.7 msgcenterpy>=0.1.8
orjson>=3.11 orjson>=3.11
opentrons_shared_data opentrons_shared_data
pint pint

View File

@@ -1,4 +1,39 @@
import json
from unilabos.utils.type_check import TypeEncoder, json_default
try:
import orjson
def fast_dumps(obj, **kwargs) -> bytes:
"""JSON 序列化为 bytes优先使用 orjson。"""
return orjson.dumps(obj, option=orjson.OPT_NON_STR_KEYS, default=json_default)
def fast_dumps_pretty(obj, **kwargs) -> bytes:
"""JSON 序列化为 bytes带缩进优先使用 orjson。"""
return orjson.dumps(
obj,
option=orjson.OPT_NON_STR_KEYS | orjson.OPT_INDENT_2,
default=json_default,
)
def normalize_json(info: dict) -> dict:
"""经 JSON 序列化/反序列化一轮来清理非标准类型。"""
return orjson.loads(orjson.dumps(info, default=json_default))
except ImportError:
def fast_dumps(obj, **kwargs) -> bytes: # type: ignore[misc]
return json.dumps(obj, ensure_ascii=False, cls=TypeEncoder).encode("utf-8")
def fast_dumps_pretty(obj, **kwargs) -> bytes: # type: ignore[misc]
return json.dumps(obj, indent=2, ensure_ascii=False, cls=TypeEncoder).encode("utf-8")
def normalize_json(info: dict) -> dict: # type: ignore[misc]
return json.loads(json.dumps(info, ensure_ascii=False, cls=TypeEncoder))
# 辅助函数将UUID数组转换为字符串 # 辅助函数将UUID数组转换为字符串
def uuid_to_str(uuid_array) -> str: def uuid_to_str(uuid_array) -> str:
"""将UUID字节数组转换为十六进制字符串""" """将UUID字节数组转换为十六进制字符串"""
return "".join(format(byte, "02x") for byte in uuid_array) return "".join(format(byte, "02x") for byte in uuid_array)

View File

@@ -15,14 +15,21 @@ def get_type_class(type_hint):
return final_type return final_type
def json_default(obj):
"""将 type 对象序列化为类名,其余 fallback 到 str()。"""
if isinstance(obj, type):
return str(obj)[8:-2]
return str(obj)
class TypeEncoder(json.JSONEncoder): class TypeEncoder(json.JSONEncoder):
"""自定义JSON编码器处理特殊类型""" """自定义JSON编码器处理特殊类型"""
def default(self, obj): def default(self, obj):
# 优先处理类型对象 try:
if isinstance(obj, type): return json_default(obj)
return str(obj)[8:-2] except Exception:
return super().default(obj) return super().default(obj)
class NoAliasDumper(yaml.SafeDumper): class NoAliasDumper(yaml.SafeDumper):
@@ -43,13 +50,10 @@ class ResultInfoEncoder(json.JSONEncoder):
"""专门用于处理任务执行结果信息的JSON编码器""" """专门用于处理任务执行结果信息的JSON编码器"""
def default(self, obj): def default(self, obj):
# 优先处理类型对象
if isinstance(obj, type): if isinstance(obj, type):
return str(obj)[8:-2] return json_default(obj)
# 对于无法序列化的对象,统一转换为字符串
try: try:
# 尝试调用 __dict__ 或者其他序列化方法
if hasattr(obj, "__dict__"): if hasattr(obj, "__dict__"):
return obj.__dict__ return obj.__dict__
elif hasattr(obj, "_asdict"): # namedtuple elif hasattr(obj, "_asdict"): # namedtuple
@@ -59,10 +63,8 @@ class ResultInfoEncoder(json.JSONEncoder):
elif hasattr(obj, "dict"): elif hasattr(obj, "dict"):
return obj.dict() return obj.dict()
else: else:
# 如果都不行,转换为字符串
return str(obj) return str(obj)
except Exception: except Exception:
# 如果转换失败,直接返回字符串表示
return str(obj) return str(obj)
@@ -80,7 +82,7 @@ def get_result_info_str(error: str, suc: bool, return_value=None) -> str:
""" """
samples = None samples = None
if isinstance(return_value, dict): if isinstance(return_value, dict):
if "samples" in return_value: if "samples" in return_value and type(return_value["samples"]) in [list, tuple] and type(return_value["samples"][0]) == dict:
samples = return_value.pop("samples") samples = return_value.pop("samples")
result_info = {"error": error, "suc": suc, "return_value": return_value, "samples": samples} result_info = {"error": error, "suc": suc, "return_value": return_value, "samples": samples}

View File

@@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"> <package format="3">
<name>unilabos_msgs</name> <name>unilabos_msgs</name>
<version>0.10.18</version> <version>0.10.19</version>
<description>ROS2 Messages package for unilabos devices</description> <description>ROS2 Messages package for unilabos devices</description>
<maintainer email="changjh@pku.edu.cn">Junhan Chang</maintainer> <maintainer email="changjh@pku.edu.cn">Junhan Chang</maintainer>
<maintainer email="18435084+Xuwznln@users.noreply.github.com">Xuwznln</maintainer> <maintainer email="18435084+Xuwznln@users.noreply.github.com">Xuwznln</maintainer>