Upgrade to py 3.11.14; ROS2 Humble 0.7; unilabos 0.10.16

Workbench example, adjust log level, and ci check (#220)

* TestLatency Return Value Example & gitignore update

* Adjust log level & Add workbench virtual example & Add not action decorator & Add check_mode &

* Add CI Check

Fix/workstation yb revision (#217)

* Revert log change & update registry

* Revert opcua client & move electrolyte node

Workstation yb merge dev ready 260113 (#216)

* feat(bioyond): 添加计算实验设计功能,支持化合物配比和滴定比例参数

* feat(bioyond): 添加测量小瓶功能,支持基本参数配置

* feat(bioyond): 添加测量小瓶配置,支持新设备参数

* feat(bioyond): 更新仓库布局和尺寸,支持竖向排列的测量小瓶和试剂存放堆栈

* feat(bioyond): 优化任务创建流程,确保无论成功与否都清理任务队列以避免重复累积

* feat(bioyond): 添加设置反应器温度功能,支持温度范围和异常处理

* feat(bioyond): 调整反应器位置配置,统一坐标格式

* feat(bioyond): 添加调度器启动功能,支持任务队列执行并处理异常

* feat(bioyond): 优化调度器启动功能,添加异常处理并更新相关配置

* feat(opcua): 增强节点ID解析兼容性和数据类型处理

改进节点ID解析逻辑以支持多种格式,包括字符串和数字标识符
添加数据类型转换处理,确保写入值时类型匹配
优化错误提示信息,便于调试节点连接问题

* feat(registry): 新增后处理站的设备配置文件

添加后处理站的YAML配置文件,包含动作映射、状态类型和设备描述

* 添加调度器启动功能,合并物料参数配置,优化物料参数处理逻辑

* 添加从 Bioyond 系统自动同步工作流序列的功能,并更新相关配置

* fix:兼容 BioyondReactionStation 中 workflow_sequence 被重写为 property

* fix:同步工作流序列

* feat: remove commented workflow synchronization from `reaction_station.py`.

* 添加时间约束功能及相关配置

* fix:自动更新物料缓存功能,添加物料时更新缓存并在删除时移除缓存项

* fix:在添加物料时处理字符串和字典返回值,确保正确更新缓存

* fix:更新奔曜错误处理报送为物料变更报送,调整日志记录和响应消息

* feat:添加实验报告简化功能,去除冗余信息并保留关键信息

* feat: 添加任务状态事件发布功能,监控并报告任务运行、超时、完成和错误状态

* fix: 修复添加物料时数据格式错误

* Refactor bioyond_dispensing_station and reaction_station_bioyond YAML configurations

- Removed redundant action value mappings from bioyond_dispensing_station.
- Updated goal properties in bioyond_dispensing_station to use enums for target_stack and other parameters.
- Changed data types for end_point and start_point in reaction_station_bioyond to use string enums (Start, End).
- Simplified descriptions and updated measurement units from μL to mL where applicable.
- Removed unused commands from reaction_station_bioyond to streamline the configuration.

* fix:Change the material unit from μL to mL

* fix:refresh_material_cache

* feat: 动态获取工作流步骤ID,优化工作流配置

* feat: 添加清空服务端所有非核心工作流功能

* fix:修复Bottle类的序列化和反序列化方法

* feat:增强材料缓存更新逻辑,支持处理返回数据中的详细信息

* Add debug log

* feat(workstation): update bioyond config migration and coin cell material search logic

- Migrate bioyond_cell config to JSON structure and remove global variable dependencies
- Implement material search confirmation dialog auto-handling
- Add documentation: 20260113_物料搜寻确认弹窗自动处理功能.md and 20260113_配置迁移修改总结.md

* Refactor module paths for Bioyond devices in YAML configuration files

- Updated the module path for BioyondDispensingStation in bioyond_dispensing_station.yaml to reflect the new directory structure.
- Updated the module path for BioyondReactionStation and BioyondReactor in reaction_station_bioyond.yaml to align with the revised organization of the codebase.

* fix: WareHouse 的不可哈希类型错误,优化父节点去重逻辑

* refactor: Move config from module to instance initialization

* fix: 修正 reaction_station 目录名拼写错误

* feat: Integrate material search logic and cleanup deprecated files

- Update coin_cell_assembly.py with material search dialog handling
- Update YB_warehouses.py with latest warehouse configurations
- Remove outdated documentation and test data files

* Refactor: Use instance attributes for action names and workflow step IDs

* refactor: Split tipbox storage into left and right warehouses

* refactor: Merge tipbox storage left and right into single warehouse

---------

Co-authored-by: ZiWei <131428629+ZiWei09@users.noreply.github.com>
Co-authored-by: Andy6M <xieqiming1132@qq.com>

fix: WareHouse 的不可哈希类型错误,优化父节点去重逻辑

fix parent_uuid fetch when bind_parent_id == node_name

物料更新也是用父节点进行报送

Add None conversion for tube rack etc.

Add set_liquid example.

Add create_resource and test_resource example.

Add restart.
Temp allow action message.

Add no_update_feedback option.

Create session_id by edge.

bump version to 0.10.15

temp cancel update req
This commit is contained in:
Xuwznln
2026-01-08 15:26:31 +08:00
parent 8580b84167
commit 2a5ddd611d
106 changed files with 17805 additions and 25458 deletions

View File

@@ -1,589 +0,0 @@
workstation.bioyond_dispensing_station:
category:
- workstation
- bioyond
class:
action_value_mappings:
auto-batch_create_90_10_vial_feeding_tasks:
feedback: {}
goal: {}
goal_default:
delay_time: null
hold_m_name: null
liquid_material_name: NMP
speed: null
temperature: null
titration: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
delay_time:
type: string
hold_m_name:
type: string
liquid_material_name:
default: NMP
type: string
speed:
type: string
temperature:
type: string
titration:
type: string
required:
- titration
type: object
result: {}
required:
- goal
title: batch_create_90_10_vial_feeding_tasks参数
type: object
type: UniLabJsonCommand
auto-batch_create_diamine_solution_tasks:
feedback: {}
goal: {}
goal_default:
delay_time: null
liquid_material_name: NMP
solutions: null
speed: null
temperature: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
delay_time:
type: string
liquid_material_name:
default: NMP
type: string
solutions:
type: string
speed:
type: string
temperature:
type: string
required:
- solutions
type: object
result: {}
required:
- goal
title: batch_create_diamine_solution_tasks参数
type: object
type: UniLabJsonCommand
auto-brief_step_parameters:
feedback: {}
goal: {}
goal_default:
data: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
data:
type: object
required:
- data
type: object
result: {}
required:
- goal
title: brief_step_parameters参数
type: object
type: UniLabJsonCommand
auto-compute_experiment_design:
feedback: {}
goal: {}
goal_default:
m_tot: '70'
ratio: null
titration_percent: '0.03'
wt_percent: '0.25'
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
m_tot:
default: '70'
type: string
ratio:
type: object
titration_percent:
default: '0.03'
type: string
wt_percent:
default: '0.25'
type: string
required:
- ratio
type: object
result:
properties:
feeding_order:
items: {}
title: Feeding Order
type: array
return_info:
title: Return Info
type: string
solutions:
items: {}
title: Solutions
type: array
solvents:
additionalProperties: true
title: Solvents
type: object
titration:
additionalProperties: true
title: Titration
type: object
required:
- solutions
- titration
- solvents
- feeding_order
- return_info
title: ComputeExperimentDesignReturn
type: object
required:
- goal
title: compute_experiment_design参数
type: object
type: UniLabJsonCommand
auto-process_order_finish_report:
feedback: {}
goal: {}
goal_default:
report_request: null
used_materials: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
report_request:
type: string
used_materials:
type: string
required:
- report_request
- used_materials
type: object
result: {}
required:
- goal
title: process_order_finish_report参数
type: object
type: UniLabJsonCommand
auto-project_order_report:
feedback: {}
goal: {}
goal_default:
order_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
order_id:
type: string
required:
- order_id
type: object
result: {}
required:
- goal
title: project_order_report参数
type: object
type: UniLabJsonCommand
auto-query_resource_by_name:
feedback: {}
goal: {}
goal_default:
material_name: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
material_name:
type: string
required:
- material_name
type: object
result: {}
required:
- goal
title: query_resource_by_name参数
type: object
type: UniLabJsonCommand
auto-transfer_materials_to_reaction_station:
feedback: {}
goal: {}
goal_default:
target_device_id: null
transfer_groups: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
target_device_id:
type: string
transfer_groups:
type: array
required:
- target_device_id
- transfer_groups
type: object
result: {}
required:
- goal
title: transfer_materials_to_reaction_station参数
type: object
type: UniLabJsonCommand
auto-wait_for_multiple_orders_and_get_reports:
feedback: {}
goal: {}
goal_default:
batch_create_result: null
check_interval: 10
timeout: 7200
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
batch_create_result:
type: string
check_interval:
default: 10
type: integer
timeout:
default: 7200
type: integer
required: []
type: object
result: {}
required:
- goal
title: wait_for_multiple_orders_and_get_reports参数
type: object
type: UniLabJsonCommand
auto-workflow_sample_locations:
feedback: {}
goal: {}
goal_default:
workflow_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
workflow_id:
type: string
required:
- workflow_id
type: object
result: {}
required:
- goal
title: workflow_sample_locations参数
type: object
type: UniLabJsonCommand
create_90_10_vial_feeding_task:
feedback: {}
goal:
delay_time: delay_time
hold_m_name: hold_m_name
order_name: order_name
percent_10_1_assign_material_name: percent_10_1_assign_material_name
percent_10_1_liquid_material_name: percent_10_1_liquid_material_name
percent_10_1_target_weigh: percent_10_1_target_weigh
percent_10_1_volume: percent_10_1_volume
percent_10_2_assign_material_name: percent_10_2_assign_material_name
percent_10_2_liquid_material_name: percent_10_2_liquid_material_name
percent_10_2_target_weigh: percent_10_2_target_weigh
percent_10_2_volume: percent_10_2_volume
percent_10_3_assign_material_name: percent_10_3_assign_material_name
percent_10_3_liquid_material_name: percent_10_3_liquid_material_name
percent_10_3_target_weigh: percent_10_3_target_weigh
percent_10_3_volume: percent_10_3_volume
percent_90_1_assign_material_name: percent_90_1_assign_material_name
percent_90_1_target_weigh: percent_90_1_target_weigh
percent_90_2_assign_material_name: percent_90_2_assign_material_name
percent_90_2_target_weigh: percent_90_2_target_weigh
percent_90_3_assign_material_name: percent_90_3_assign_material_name
percent_90_3_target_weigh: percent_90_3_target_weigh
speed: speed
temperature: temperature
goal_default:
delay_time: ''
hold_m_name: ''
order_name: ''
percent_10_1_assign_material_name: ''
percent_10_1_liquid_material_name: ''
percent_10_1_target_weigh: ''
percent_10_1_volume: ''
percent_10_2_assign_material_name: ''
percent_10_2_liquid_material_name: ''
percent_10_2_target_weigh: ''
percent_10_2_volume: ''
percent_10_3_assign_material_name: ''
percent_10_3_liquid_material_name: ''
percent_10_3_target_weigh: ''
percent_10_3_volume: ''
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: ''
speed: ''
temperature: ''
handles: {}
result:
return_info: return_info
schema:
description: ''
properties:
feedback:
properties: {}
required: []
title: DispenStationVialFeed_Feedback
type: object
goal:
properties:
delay_time:
type: string
hold_m_name:
type: string
order_name:
type: string
percent_10_1_assign_material_name:
type: string
percent_10_1_liquid_material_name:
type: string
percent_10_1_target_weigh:
type: string
percent_10_1_volume:
type: string
percent_10_2_assign_material_name:
type: string
percent_10_2_liquid_material_name:
type: string
percent_10_2_target_weigh:
type: string
percent_10_2_volume:
type: string
percent_10_3_assign_material_name:
type: string
percent_10_3_liquid_material_name:
type: string
percent_10_3_target_weigh:
type: string
percent_10_3_volume:
type: string
percent_90_1_assign_material_name:
type: string
percent_90_1_target_weigh:
type: string
percent_90_2_assign_material_name:
type: string
percent_90_2_target_weigh:
type: string
percent_90_3_assign_material_name:
type: string
percent_90_3_target_weigh:
type: string
speed:
type: string
temperature:
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
type: object
result:
properties:
return_info:
type: string
required:
- return_info
title: DispenStationVialFeed_Result
type: object
required:
- goal
title: DispenStationVialFeed
type: object
type: DispenStationVialFeed
create_diamine_solution_task:
feedback: {}
goal:
delay_time: delay_time
hold_m_name: hold_m_name
liquid_material_name: liquid_material_name
material_name: material_name
order_name: order_name
speed: speed
target_weigh: target_weigh
temperature: temperature
volume: volume
goal_default:
delay_time: ''
hold_m_name: ''
liquid_material_name: ''
material_name: ''
order_name: ''
speed: ''
target_weigh: ''
temperature: ''
volume: ''
handles: {}
result:
return_info: return_info
schema:
description: ''
properties:
feedback:
properties: {}
required: []
title: DispenStationSolnPrep_Feedback
type: object
goal:
properties:
delay_time:
type: string
hold_m_name:
type: string
liquid_material_name:
type: string
material_name:
type: string
order_name:
type: string
speed:
type: string
target_weigh:
type: string
temperature:
type: string
volume:
type: string
required:
- order_name
- material_name
- target_weigh
- volume
- liquid_material_name
- speed
- temperature
- delay_time
- hold_m_name
title: DispenStationSolnPrep_Goal
type: object
result:
properties:
return_info:
type: string
required:
- return_info
title: DispenStationSolnPrep_Result
type: object
required:
- goal
title: DispenStationSolnPrep
type: object
type: DispenStationSolnPrep
module: unilabos.devices.workstation.bioyond_studio.dispensing_station:BioyondDispensingStation
status_types: {}
type: python
config_info: []
description: ''
handles: []
icon: ''
init_param_schema:
config:
properties:
config:
type: string
deck:
type: string
required:
- config
- deck
type: object
data:
properties: {}
required: []
type: object
version: 1.0.0

File diff suppressed because it is too large Load Diff

View File

@@ -30,71 +30,6 @@ bioyond_dispensing_station:
title: brief_step_parameters参数
type: object
type: UniLabJsonCommand
auto-compute_experiment_design:
feedback: {}
goal: {}
goal_default:
m_tot: '70'
ratio: null
titration_percent: '0.03'
wt_percent: '0.25'
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
m_tot:
default: '70'
type: string
ratio:
type: object
titration_percent:
default: '0.03'
type: string
wt_percent:
default: '0.25'
type: string
required:
- ratio
type: object
result:
properties:
feeding_order:
items: {}
title: Feeding Order
type: array
return_info:
title: Return Info
type: string
solutions:
items: {}
title: Solutions
type: array
solvents:
additionalProperties: true
title: Solvents
type: object
titration:
additionalProperties: true
title: Titration
type: object
required:
- solutions
- titration
- solvents
- feeding_order
- return_info
title: ComputeExperimentDesignReturn
type: object
required:
- goal
title: compute_experiment_design参数
type: object
type: UniLabJsonCommand
auto-process_order_finish_report:
feedback: {}
goal: {}
@@ -174,35 +109,6 @@ bioyond_dispensing_station:
title: query_resource_by_name参数
type: object
type: UniLabJsonCommand
auto-transfer_materials_to_reaction_station:
feedback: {}
goal: {}
goal_default:
target_device_id: null
transfer_groups: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
target_device_id:
type: string
transfer_groups:
type: array
required:
- target_device_id
- transfer_groups
type: object
result: {}
required:
- goal
title: transfer_materials_to_reaction_station参数
type: object
type: UniLabJsonCommand
auto-workflow_sample_locations:
feedback: {}
goal: {}
@@ -394,6 +300,99 @@ bioyond_dispensing_station:
title: BatchCreateDiamineSolutionTasks
type: object
type: UniLabJsonCommand
compute_experiment_design:
feedback: {}
goal:
m_tot: m_tot
ratio: ratio
titration_percent: titration_percent
wt_percent: wt_percent
goal_default:
m_tot: '70'
ratio: ''
titration_percent: '0.03'
wt_percent: '0.25'
handles:
output:
- data_key: solutions
data_source: executor
data_type: array
handler_key: solutions
io_type: sink
label: Solution Data From Python
- data_key: titration
data_source: executor
data_type: object
handler_key: titration
io_type: sink
label: Titration Data From Calculation Node
- data_key: solvents
data_source: executor
data_type: object
handler_key: solvents
io_type: sink
label: Solvents Data From Calculation Node
- data_key: feeding_order
data_source: executor
data_type: array
handler_key: feeding_order
io_type: sink
label: Feeding Order Data From Calculation Node
result:
feeding_order: feeding_order
return_info: return_info
solutions: solutions
solvents: solvents
titration: titration
schema:
description: 计算实验设计输出solutions/titration/solvents/feeding_order用于后续节点。
properties:
feedback: {}
goal:
properties:
m_tot:
default: '70'
description: 总质量(g)
type: string
ratio:
description: 组分摩尔比的对象,保持输入顺序,如{"MDA":1,"BTDA":1}
type: string
titration_percent:
default: '0.03'
description: 滴定比例(10%部分)
type: string
wt_percent:
default: '0.25'
description: 目标固含质量分数
type: string
required:
- ratio
type: object
result:
properties:
feeding_order:
type: array
return_info:
type: string
solutions:
type: array
solvents:
type: object
titration:
type: object
required:
- solutions
- titration
- solvents
- feeding_order
- return_info
title: ComputeExperimentDesign_Result
type: object
required:
- goal
title: ComputeExperimentDesign
type: object
type: UniLabJsonCommand
create_90_10_vial_feeding_task:
feedback: {}
goal:
@@ -620,6 +619,89 @@ bioyond_dispensing_station:
title: DispenStationSolnPrep
type: object
type: DispenStationSolnPrep
scheduler_start:
feedback: {}
goal: {}
goal_default: {}
handles: {}
result:
return_info: return_info
schema:
description: 启动调度器 - 启动Bioyond配液站的任务调度器开始执行队列中的任务
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result:
properties:
return_info:
description: 调度器启动结果成功返回1失败返回0
type: integer
required:
- return_info
title: scheduler_start结果
type: object
required:
- goal
title: scheduler_start参数
type: object
type: UniLabJsonCommand
transfer_materials_to_reaction_station:
feedback: {}
goal:
target_device_id: target_device_id
transfer_groups: transfer_groups
goal_default:
target_device_id: ''
transfer_groups: ''
handles: {}
placeholder_keys:
target_device_id: unilabos_devices
result: {}
schema:
description: 将配液站完成的物料(溶液、样品等)转移到指定反应站的堆栈库位。支持配置多组转移任务,每组包含物料名称、目标堆栈和目标库位。
properties:
feedback: {}
goal:
properties:
target_device_id:
description: 目标反应站设备ID从设备列表中选择所有转移组都使用同一个目标设备
type: string
transfer_groups:
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
required:
- target_device_id
- transfer_groups
type: object
result: {}
required:
- goal
title: transfer_materials_to_reaction_station参数
type: object
type: UniLabJsonCommand
wait_for_multiple_orders_and_get_reports:
feedback: {}
goal:
@@ -688,7 +770,7 @@ bioyond_dispensing_station:
title: WaitForMultipleOrdersAndGetReports
type: object
type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.dispensing_station:BioyondDispensingStation
module: unilabos.devices.workstation.bioyond_studio.dispensing_station.dispensing_station:BioyondDispensingStation
status_types: {}
type: python
config_info: []
@@ -699,15 +781,16 @@ bioyond_dispensing_station:
config:
properties:
config:
type: string
type: object
deck:
type: string
required:
- config
- deck
protocol_type:
type: string
required: []
type: object
data:
properties: {}
required: []
type: object
model: {}
version: 1.0.0

View File

@@ -0,0 +1,850 @@
coincellassemblyworkstation_device:
category:
- coin_cell_workstation
class:
action_value_mappings:
auto-change_hole_sheet_to_2:
feedback: {}
goal: {}
goal_default:
hole: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
hole:
type: object
required:
- hole
type: object
result: {}
required:
- goal
title: change_hole_sheet_to_2参数
type: object
type: UniLabJsonCommandAsync
auto-fill_plate:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: fill_plate参数
type: object
type: UniLabJsonCommandAsync
auto-fun_wuliao_test:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: fun_wuliao_test参数
type: object
type: UniLabJsonCommand
auto-func_allpack_cmd:
feedback: {}
goal: {}
goal_default:
assembly_pressure: 4200
assembly_type: 7
elec_num: null
elec_use_num: null
elec_vol: 50
file_path: /Users/sml/work
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
assembly_pressure:
default: 4200
type: integer
assembly_type:
default: 7
type: integer
elec_num:
type: string
elec_use_num:
type: string
elec_vol:
default: 50
type: integer
file_path:
default: /Users/sml/work
type: string
required:
- elec_num
- elec_use_num
type: object
result: {}
required:
- goal
title: func_allpack_cmd参数
type: object
type: UniLabJsonCommand
auto-func_allpack_cmd_simp:
feedback: {}
goal: {}
goal_default:
assembly_pressure: 4200
assembly_type: 7
battery_clean_ignore: false
battery_pressure_mode: true
dual_drop_first_volume: 25
dual_drop_mode: false
dual_drop_start_timing: false
dual_drop_suction_timing: false
elec_num: null
elec_use_num: null
elec_vol: 50
file_path: /Users/sml/work
fujipian_juzhendianwei: 0
fujipian_panshu: 0
gemo_juzhendianwei: 0
gemopanshu: 0
lvbodian: true
qiangtou_juzhendianwei: 0
handles: {}
placeholder_keys: {}
result: {}
schema:
description: 简化版电池组装函数,整合了参数设置和双滴模式
properties:
feedback: {}
goal:
properties:
assembly_pressure:
default: 4200
description: 电池压制力(N)
type: integer
assembly_type:
default: 7
description: 组装类型(7=不用铝箔垫, 8=使用铝箔垫)
type: integer
battery_clean_ignore:
default: false
description: 是否忽略电池清洁步骤
type: boolean
battery_pressure_mode:
default: true
description: 是否启用压力模式
type: boolean
dual_drop_first_volume:
default: 25
description: 二次滴液第一次排液体积(μL)
type: integer
dual_drop_mode:
default: false
description: 电解液添加模式(false=单次滴液, true=二次滴液)
type: boolean
dual_drop_start_timing:
default: false
description: 二次滴液开始滴液时机(false=正极片前, true=正极片后)
type: boolean
dual_drop_suction_timing:
default: false
description: 二次滴液吸液时机(false=正常吸液, true=先吸液)
type: boolean
elec_num:
description: 电解液瓶数
type: string
elec_use_num:
description: 每瓶电解液组装电池数
type: string
elec_vol:
default: 50
description: 电解液吸液量(μL)
type: integer
file_path:
default: /Users/sml/work
description: 实验记录保存路径
type: string
fujipian_juzhendianwei:
default: 0
description: 负极片矩阵点位。盘位置从1开始计数有效范围1-8, 13-20 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
fujipian_panshu:
default: 0
description: 负极片盘数
type: integer
gemo_juzhendianwei:
default: 0
description: 隔膜矩阵点位。盘位置从1开始计数有效范围1-8, 13-20 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
gemopanshu:
default: 0
description: 隔膜盘数
type: integer
lvbodian:
default: true
description: 是否使用铝箔垫片
type: boolean
qiangtou_juzhendianwei:
default: 0
description: 枪头盒矩阵点位。盘位置从1开始计数有效范围1-32, 64-96 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
required:
- elec_num
- elec_use_num
type: object
result: {}
required:
- goal
title: func_allpack_cmd_simp参数
type: object
type: UniLabJsonCommand
auto-func_get_csv_export_status:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_get_csv_export_status参数
type: object
type: UniLabJsonCommand
auto-func_pack_device_auto:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_pack_device_auto参数
type: object
type: UniLabJsonCommand
auto-func_pack_device_init:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_pack_device_init参数
type: object
type: UniLabJsonCommand
auto-func_pack_device_init_auto_start_combined:
feedback: {}
goal: {}
goal_default:
material_search_enable: false
handles: {}
placeholder_keys: {}
result: {}
schema:
description: 组合函数:设备初始化 + 物料搜寻确认 + 切换自动模式 + 启动。初始化过程中会自动检测物料搜寻确认弹窗,并根据参数自动点击"是"或"否"按钮
properties:
feedback: {}
goal:
properties:
material_search_enable:
default: false
description: 是否启用物料搜寻功能。设备初始化后会弹出物料搜寻确认弹窗,此参数控制自动点击"是"(启用)或"否"(不启用)。默认为false(不启用物料搜寻)
type: boolean
required: []
type: object
result: {}
required:
- goal
title: func_pack_device_init_auto_start_combined参数
type: object
type: UniLabJsonCommand
auto-func_pack_device_start:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_pack_device_start参数
type: object
type: UniLabJsonCommand
auto-func_pack_device_stop:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_pack_device_stop参数
type: object
type: UniLabJsonCommand
auto-func_pack_get_msg_cmd:
feedback: {}
goal: {}
goal_default:
file_path: D:\coin_cell_data
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
file_path:
default: D:\coin_cell_data
type: string
required: []
type: object
result: {}
required:
- goal
title: func_pack_get_msg_cmd参数
type: object
type: UniLabJsonCommand
auto-func_pack_send_bottle_num:
feedback: {}
goal: {}
goal_default:
bottle_num: null
handles:
input:
- data_key: bottle_num
data_source: workflow
data_type: integer
handler_key: bottle_count
io_type: source
label: 配液瓶数
required: true
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
bottle_num:
type: string
required:
- bottle_num
type: object
result: {}
required:
- goal
title: func_pack_send_bottle_num参数
type: object
type: UniLabJsonCommand
auto-func_pack_send_finished_cmd:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_pack_send_finished_cmd参数
type: object
type: UniLabJsonCommand
auto-func_pack_send_msg_cmd:
feedback: {}
goal: {}
goal_default:
assembly_pressure: null
assembly_type: null
elec_use_num: null
elec_vol: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
assembly_pressure:
type: string
assembly_type:
type: string
elec_use_num:
type: string
elec_vol:
type: string
required:
- elec_use_num
- elec_vol
- assembly_type
- assembly_pressure
type: object
result: {}
required:
- goal
title: func_pack_send_msg_cmd参数
type: object
type: UniLabJsonCommand
auto-func_read_data_and_output:
feedback: {}
goal: {}
goal_default:
file_path: /Users/sml/work
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
file_path:
default: /Users/sml/work
type: string
required: []
type: object
result: {}
required:
- goal
title: func_read_data_and_output参数
type: object
type: UniLabJsonCommand
auto-func_sendbottle_allpack_multi:
feedback: {}
goal: {}
goal_default:
assembly_pressure: 4200
assembly_type: 7
battery_clean_ignore: false
battery_pressure_mode: true
dual_drop_first_volume: 25
dual_drop_mode: false
dual_drop_start_timing: false
dual_drop_suction_timing: false
elec_num: null
elec_use_num: null
elec_vol: 50
file_path: /Users/sml/work
fujipian_juzhendianwei: 0
fujipian_panshu: 0
gemo_juzhendianwei: 0
gemopanshu: 0
lvbodian: true
qiangtou_juzhendianwei: 0
handles:
input:
- data_key: elec_num
data_source: workflow
data_type: integer
handler_key: bottle_count
io_type: source
label: 配液瓶数
required: true
placeholder_keys: {}
result: {}
schema:
description: 发送瓶数+简化组装函数(适用于第二批次及后续批次),合并了发送瓶数和简化组装流程
properties:
feedback: {}
goal:
properties:
assembly_pressure:
default: 4200
description: 电池压制力(N)
type: integer
assembly_type:
default: 7
description: 组装类型(7=不用铝箔垫, 8=使用铝箔垫)
type: integer
battery_clean_ignore:
default: false
description: 是否忽略电池清洁步骤
type: boolean
battery_pressure_mode:
default: true
description: 是否启用压力模式
type: boolean
dual_drop_first_volume:
default: 25
description: 二次滴液第一次排液体积(μL)
type: integer
dual_drop_mode:
default: false
description: 电解液添加模式(false=单次滴液, true=二次滴液)
type: boolean
dual_drop_start_timing:
default: false
description: 二次滴液开始滴液时机(false=正极片前, true=正极片后)
type: boolean
dual_drop_suction_timing:
default: false
description: 二次滴液吸液时机(false=正常吸液, true=先吸液)
type: boolean
elec_num:
description: 电解液瓶数如果在workflow中已通过handles连接上游(create_orders的bottle_count输出),则此参数会自动从上游获取,无需手动填写;如果单独使用此函数(没有上游连接),则必须手动填写电解液瓶数
type: string
elec_use_num:
description: 每瓶电解液组装电池数
type: string
elec_vol:
default: 50
description: 电解液吸液量(μL)
type: integer
file_path:
default: /Users/sml/work
description: 实验记录保存路径
type: string
fujipian_juzhendianwei:
default: 0
description: 负极片矩阵点位。盘位置从1开始计数有效范围1-8, 13-20 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
fujipian_panshu:
default: 0
description: 负极片盘数
type: integer
gemo_juzhendianwei:
default: 0
description: 隔膜矩阵点位。盘位置从1开始计数有效范围1-8, 13-20 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
gemopanshu:
default: 0
description: 隔膜盘数
type: integer
lvbodian:
default: true
description: 是否使用铝箔垫片
type: boolean
qiangtou_juzhendianwei:
default: 0
description: 枪头盒矩阵点位。盘位置从1开始计数有效范围1-32, 64-96 (写入值比实际位置少1例如写0取盘位1写1取盘位2)
type: integer
required:
- elec_num
- elec_use_num
type: object
result: {}
required:
- goal
title: func_sendbottle_allpack_multi参数
type: object
type: UniLabJsonCommand
auto-func_stop_read_data:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: func_stop_read_data参数
type: object
type: UniLabJsonCommand
auto-modify_deck_name:
feedback: {}
goal: {}
goal_default:
resource_name: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
resource_name:
type: string
required:
- resource_name
type: object
result: {}
required:
- goal
title: modify_deck_name参数
type: object
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:
feedback: {}
goal: {}
goal_default:
battery_clean_ignore: false
battery_pressure: 4000
battery_pressure_mode: true
fujipian_juzhendianwei: 0
fujipian_panshu: null
gemo_juzhendianwei: 0
gemopanshu: 0
lvbodian: true
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
battery_clean_ignore:
default: false
type: boolean
battery_pressure:
default: 4000
type: integer
battery_pressure_mode:
default: true
type: boolean
fujipian_juzhendianwei:
default: 0
type: integer
fujipian_panshu:
type: integer
gemo_juzhendianwei:
default: 0
type: integer
gemopanshu:
default: 0
type: integer
lvbodian:
default: true
type: boolean
required:
- fujipian_panshu
type: object
result: {}
required:
- goal
title: qiming_coin_cell_code参数
type: object
type: UniLabJsonCommand
module: unilabos.devices.workstation.coin_cell_assembly.coin_cell_assembly:CoinCellAssemblyWorkstation
status_types:
data_assembly_coin_cell_num: int
data_assembly_pressure: int
data_assembly_time: float
data_axis_x_pos: float
data_axis_y_pos: float
data_axis_z_pos: float
data_coin_cell_code: str
data_coin_num: int
data_electrolyte_code: str
data_electrolyte_volume: int
data_glove_box_o2_content: float
data_glove_box_pressure: float
data_glove_box_water_content: float
data_open_circuit_voltage: float
data_pole_weight: float
request_rec_msg_status: bool
request_send_msg_status: bool
sys_mode: str
sys_status: str
type: python
config_info: []
description: ''
handles: []
icon: koudian.webp
init_param_schema:
config:
properties:
address:
default: 172.16.28.102
type: string
config:
type: object
debug_mode:
default: false
type: boolean
deck:
type: string
port:
default: '502'
type: string
required: []
type: object
data:
properties:
data_assembly_coin_cell_num:
type: integer
data_assembly_pressure:
type: integer
data_assembly_time:
type: number
data_axis_x_pos:
type: number
data_axis_y_pos:
type: number
data_axis_z_pos:
type: number
data_coin_cell_code:
type: string
data_coin_num:
type: integer
data_electrolyte_code:
type: string
data_electrolyte_volume:
type: integer
data_glove_box_o2_content:
type: number
data_glove_box_pressure:
type: number
data_glove_box_water_content:
type: number
data_open_circuit_voltage:
type: number
data_pole_weight:
type: number
request_rec_msg_status:
type: boolean
request_send_msg_status:
type: boolean
sys_mode:
type: string
sys_status:
type: string
required:
- sys_status
- sys_mode
- request_rec_msg_status
- request_send_msg_status
- data_assembly_coin_cell_num
- data_assembly_time
- data_open_circuit_voltage
- data_axis_x_pos
- data_axis_y_pos
- data_axis_z_pos
- data_pole_weight
- data_assembly_pressure
- data_electrolyte_volume
- data_coin_num
- data_coin_cell_code
- data_electrolyte_code
- data_glove_box_pressure
- data_glove_box_o2_content
- data_glove_box_water_content
type: object
registry_type: device
version: 1.0.0

View File

@@ -9278,7 +9278,13 @@ liquid_handler.prcxi:
z: 0.0
sample_id: ''
type: ''
handles: {}
handles:
input:
- data_key: wells
data_source: handle
data_type: resource
handler_key: input_wells
label: InputWells
placeholder_keys:
wells: unilabos_resources
result: {}

View File

@@ -49,32 +49,7 @@ opcua_example:
title: load_config参数
type: object
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-refresh_node_values:
feedback: {}
goal: {}
goal_default: {}
@@ -92,32 +67,7 @@ opcua_example:
result: {}
required:
- goal
title: print_cache_stats参数
type: object
type: UniLabJsonCommand
auto-read_node:
feedback: {}
goal: {}
goal_default:
node_name: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
node_name:
type: string
required:
- node_name
type: object
result: {}
required:
- goal
title: read_node参数
title: refresh_node_values参数
type: object
type: UniLabJsonCommand
auto-set_node_value:
@@ -149,9 +99,50 @@ opcua_example:
title: set_node_value参数
type: object
type: UniLabJsonCommand
auto-start_node_refresh:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: start_node_refresh参数
type: object
type: UniLabJsonCommand
auto-stop_node_refresh:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: stop_node_refresh参数
type: object
type: UniLabJsonCommand
module: unilabos.device_comms.opcua_client.client:OpcUaClient
status_types:
cache_stats: dict
node_value: String
type: python
config_info: []
@@ -161,23 +152,15 @@ opcua_example:
init_param_schema:
config:
properties:
cache_timeout:
default: 5.0
type: number
config_path:
type: string
deck:
type: string
password:
type: string
subscription_interval:
default: 500
type: integer
refresh_interval:
default: 1.0
type: number
url:
type: string
use_subscription:
default: true
type: boolean
username:
type: string
required:
@@ -185,12 +168,9 @@ opcua_example:
type: object
data:
properties:
cache_stats:
type: object
node_value:
type: string
required:
- node_value
- cache_stats
type: object
version: 1.0.0

View File

@@ -4,6 +4,81 @@ reaction_station.bioyond:
- reaction_station_bioyond
class:
action_value_mappings:
add_time_constraint:
feedback: {}
goal:
duration: duration
end_point: end_point
end_step_key: end_step_key
start_point: start_point
start_step_key: start_step_key
goal_default:
duration: 0
end_point: 0
end_step_key: ''
start_point: 0
start_step_key: ''
handles: {}
result: {}
schema:
description: 添加时间约束 - 在两个工作流之间添加时间约束
properties:
feedback: {}
goal:
properties:
duration:
description: 时间(秒)
type: integer
end_point:
default: Start
description: 终点计时点 (Start=开始前, End=结束后)
enum:
- Start
- End
type: string
end_step_key:
description: 终点步骤Key (可选, 默认为空则自动选择)
type: string
start_point:
default: Start
description: 起点计时点 (Start=开始前, End=结束后)
enum:
- Start
- End
type: string
start_step_key:
description: 起点步骤Key (例如 "feeding", "liquid", 可选, 默认为空则自动选择)
type: string
required:
- duration
type: object
result: {}
required:
- goal
title: add_time_constraint参数
type: object
type: UniLabJsonCommand
auto-clear_workflows:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: clear_workflows参数
type: object
type: UniLabJsonCommand
auto-create_order:
feedback: {}
goal: {}
@@ -131,6 +206,35 @@ reaction_station.bioyond:
title: process_web_workflows参数
type: object
type: UniLabJsonCommand
auto-set_reactor_temperature:
feedback: {}
goal: {}
goal_default:
reactor_id: null
temperature: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
reactor_id:
type: integer
temperature:
type: number
required:
- reactor_id
- temperature
type: object
result: {}
required:
- goal
title: set_reactor_temperature参数
type: object
type: UniLabJsonCommand
auto-skip_titration_steps:
feedback: {}
goal: {}
@@ -156,6 +260,27 @@ reaction_station.bioyond:
title: skip_titration_steps参数
type: object
type: UniLabJsonCommand
auto-sync_workflow_sequence_from_bioyond:
feedback: {}
goal: {}
goal_default: {}
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result: {}
required:
- goal
title: sync_workflow_sequence_from_bioyond参数
type: object
type: UniLabJsonCommand
auto-wait_for_multiple_orders_and_get_reports:
feedback: {}
goal: {}
@@ -188,6 +313,33 @@ reaction_station.bioyond:
title: wait_for_multiple_orders_and_get_reports参数
type: object
type: UniLabJsonCommand
auto-workflow_sequence:
feedback: {}
goal: {}
goal_default:
value: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
value:
items:
type: string
type: array
required:
- value
type: object
result: {}
required:
- goal
title: workflow_sequence参数
type: object
type: UniLabJsonCommand
auto-workflow_step_query:
feedback: {}
goal: {}
@@ -213,6 +365,36 @@ reaction_station.bioyond:
title: workflow_step_query参数
type: object
type: UniLabJsonCommand
clean_all_server_workflows:
feedback: {}
goal: {}
goal_default: {}
handles: {}
result:
code: code
message: message
schema:
description: 清空服务端所有非核心工作流 (保留核心流程)
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result:
properties:
code:
description: 操作结果代码(1表示成功)
type: integer
message:
description: 结果描述
type: string
type: object
required:
- goal
title: clean_all_server_workflows参数
type: object
type: UniLabJsonCommand
drip_back:
feedback: {}
goal:
@@ -247,13 +429,19 @@ reaction_station.bioyond:
description: 观察时间(分钟)
type: string
titration_type:
description: 是否滴定(1=否, 2=是)
description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
torque_variation:
description: 是否观察 (1=否, 2=是)
description: 是否观察 (NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
volume:
description: 分液公式(μL)
description: 分液公式(mL)
type: string
required:
- volume
@@ -353,13 +541,19 @@ reaction_station.bioyond:
description: 观察时间(分钟)
type: string
titration_type:
description: 是否滴定(1=否, 2=是)
description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
torque_variation:
description: 是否观察 (1=否, 2=是)
description: 是否观察 (NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
volume:
description: 分液公式(μL)
description: 分液公式(mL)
type: string
required:
- volume
@@ -403,7 +597,7 @@ reaction_station.bioyond:
label: Solvents Data From Calculation Node
result: {}
schema:
description: 液体投料-溶剂。可以直接提供volume(μL),或通过solvents对象自动从additional_solvent(mL)计算volume。
description: 液体投料-溶剂。可以直接提供volume(mL),或通过solvents对象自动从additional_solvent(mL)计算volume。
properties:
feedback: {}
goal:
@@ -423,15 +617,21 @@ reaction_station.bioyond:
description: 观察时间(分钟),默认360
type: string
titration_type:
default: '1'
description: 是否滴定(1=否, 2=是),默认1
default: 'NO'
description: 是否滴定(NO=否, YES=是),默认NO
enum:
- 'NO'
- 'YES'
type: string
torque_variation:
default: '2'
description: 是否观察 (1=否, 2=是),默认2
default: 'YES'
description: 是否观察 (NO=否, YES=是),默认YES
enum:
- 'NO'
- 'YES'
type: string
volume:
description: 分液量(μL)。可直接提供,或通过solvents参数自动计算
description: 分液量(mL)。可直接提供,或通过solvents参数自动计算
type: string
required:
- assign_material_name
@@ -504,15 +704,21 @@ reaction_station.bioyond:
description: 观察时间(分钟),默认90
type: string
titration_type:
default: '2'
description: 是否滴定(1=否, 2=是),默认2
default: 'YES'
description: 是否滴定(NO=否, YES=是),默认YES
enum:
- 'NO'
- 'YES'
type: string
torque_variation:
default: '2'
description: 是否观察 (1=否, 2=是),默认2
default: 'YES'
description: 是否观察 (NO=否, YES=是),默认YES
enum:
- 'NO'
- 'YES'
type: string
volume_formula:
description: 分液公式(μL)。可直接提供固定公式,或留空由系统根据x_value、feeding_order_data、extracted_actuals自动生成
description: 分液公式(mL)。可直接提供固定公式,或留空由系统根据x_value、feeding_order_data、extracted_actuals自动生成
type: string
x_value:
description: 公式中的x值,手工输入,格式为"{{1-2-3}}"(包含双花括号)。用于自动公式计算
@@ -560,13 +766,19 @@ reaction_station.bioyond:
description: 观察时间(分钟)
type: string
titration_type:
description: 是否滴定(1=否, 2=是)
description: 是否滴定(NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
torque_variation:
description: 是否观察 (1=否, 2=是)
description: 是否观察 (NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
volume_formula:
description: 分液公式(μL)
description: 分液公式(mL)
type: string
required:
- volume_formula
@@ -680,6 +892,35 @@ reaction_station.bioyond:
title: reactor_taken_out参数
type: object
type: UniLabJsonCommand
scheduler_start:
feedback: {}
goal: {}
goal_default: {}
handles: {}
result:
return_info: return_info
schema:
description: 启动调度器 - 启动Bioyond工作站的任务调度器开始执行队列中的任务
properties:
feedback: {}
goal:
properties: {}
required: []
type: object
result:
properties:
return_info:
description: 调度器启动结果成功返回1失败返回0
type: integer
required:
- return_info
title: scheduler_start结果
type: object
required:
- goal
title: scheduler_start参数
type: object
type: UniLabJsonCommand
solid_feeding_vials:
feedback: {}
goal:
@@ -706,7 +947,11 @@ reaction_station.bioyond:
description: 物料名称(用于获取试剂瓶位ID)
type: string
material_id:
description: 粉末类型ID1=盐21分钟2=面粉27分钟3=BTDA38分钟
description: 粉末类型IDSalt=盐21分钟Flour=面粉27分钟BTDA=BTDA38分钟
enum:
- Salt
- Flour
- BTDA
type: string
temperature:
description: 温度设定(°C)
@@ -715,7 +960,10 @@ reaction_station.bioyond:
description: 观察时间(分钟)
type: string
torque_variation:
description: 是否观察 (1=否, 2=是)
description: 是否观察 (NO=否, YES=是)
enum:
- 'NO'
- 'YES'
type: string
required:
- assign_material_name
@@ -730,10 +978,10 @@ reaction_station.bioyond:
title: solid_feeding_vials参数
type: object
type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.reaction_station:BioyondReactionStation
module: unilabos.devices.workstation.bioyond_studio.reaction_station.reaction_station:BioyondReactionStation
protocol_type: []
status_types:
workflow_sequence: String
workflow_sequence: str
type: python
config_info: []
description: Bioyond反应站
@@ -753,9 +1001,7 @@ reaction_station.bioyond:
data:
properties:
workflow_sequence:
items:
type: string
type: array
type: string
required:
- workflow_sequence
type: object
@@ -791,7 +1037,7 @@ reaction_station.reactor:
title: update_metrics参数
type: object
type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.reaction_station:BioyondReactor
module: unilabos.devices.workstation.bioyond_studio.reaction_station.reaction_station:BioyondReactor
status_types: {}
type: python
config_info: []

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,20 @@ class Registry:
from unilabos.app.web.utils.action_utils import get_yaml_from_goal_type
# 获取 HostNode 类的增强信息,用于自动生成 action schema
host_node_enhanced_info = get_enhanced_class_info(
"unilabos.ros.nodes.presets.host_node:HostNode", use_dynamic=True
)
# 为 test_latency 生成 schema保留原有 description
test_latency_method_info = host_node_enhanced_info.get("action_methods", {}).get("test_latency", {})
test_latency_schema = self._generate_unilab_json_command_schema(
test_latency_method_info.get("args", []),
"test_latency",
test_latency_method_info.get("return_annotation"),
)
test_latency_schema["description"] = "用于测试延迟的动作,返回延迟时间和时间差。"
self.device_type_registry.update(
{
"host_node": {
@@ -124,11 +138,25 @@ class Registry:
"output": [
{
"handler_key": "labware",
"label": "Labware",
"data_type": "resource",
"data_source": "handle",
"data_key": "liquid",
}
"label": "Labware",
"data_source": "executor",
"data_key": "created_resource_tree.@flatten",
},
{
"handler_key": "liquid_slots",
"data_type": "resource",
"label": "LiquidSlots",
"data_source": "executor",
"data_key": "liquid_input_resource_tree.@flatten",
},
{
"handler_key": "materials",
"data_type": "resource",
"label": "AllMaterials",
"data_source": "executor",
"data_key": "[created_resource_tree,liquid_input_resource_tree].@flatten.@flatten",
},
]
},
"placeholder_keys": {
@@ -138,14 +166,19 @@ class Registry:
},
},
"test_latency": {
"type": self.EmptyIn,
"type": (
"UniLabJsonCommandAsync"
if test_latency_method_info.get("is_async", False)
else "UniLabJsonCommand"
),
"goal": {},
"feedback": {},
"result": {},
"schema": ros_action_to_json_schema(
self.EmptyIn, "用于测试延迟的动作,返回延迟时间和时间差。"
),
"goal_default": {},
"schema": test_latency_schema,
"goal_default": {
arg["name"]: arg["default"]
for arg in test_latency_method_info.get("args", [])
},
"handles": {},
},
"auto-test_resource": {
@@ -186,7 +219,17 @@ class Registry:
"resources": "unilabos_resources",
},
"goal_default": {},
"handles": {},
"handles": {
"input": [
{
"handler_key": "input_resources",
"data_type": "resource",
"label": "InputResources",
"data_source": "handle",
"data_key": "resources", # 不为空
},
]
},
},
},
},
@@ -455,7 +498,11 @@ class Registry:
return status_schema
def _generate_unilab_json_command_schema(
self, method_args: List[Dict[str, Any]], method_name: str, return_annotation: Any = None
self,
method_args: List[Dict[str, Any]],
method_name: str,
return_annotation: Any = None,
previous_schema: Dict[str, Any] | None = None,
) -> Dict[str, Any]:
"""
根据UniLabJsonCommand方法信息生成JSON Schema暂不支持嵌套类型
@@ -464,6 +511,7 @@ class Registry:
method_args: 方法信息字典包含args等
method_name: 方法名称
return_annotation: 返回类型注解用于生成result schema仅支持TypedDict
previous_schema: 之前的 schema用于保留 goal/feedback/result 下一级字段的 description
Returns:
JSON Schema格式的参数schema
@@ -497,7 +545,7 @@ class Registry:
if return_annotation is not None and self._is_typed_dict(return_annotation):
result_schema = self._generate_typed_dict_result_schema(return_annotation)
return {
final_schema = {
"title": f"{method_name}参数",
"description": f"",
"type": "object",
@@ -505,6 +553,40 @@ class Registry:
"required": ["goal"],
}
# 保留之前 schema 中 goal/feedback/result 下一级字段的 description
if previous_schema:
self._preserve_field_descriptions(final_schema, previous_schema)
return final_schema
def _preserve_field_descriptions(self, new_schema: Dict[str, Any], previous_schema: Dict[str, Any]) -> None:
"""
保留之前 schema 中 goal/feedback/result 下一级字段的 description 和 title
Args:
new_schema: 新生成的 schema会被修改
previous_schema: 之前的 schema
"""
for section in ["goal", "feedback", "result"]:
new_section = new_schema.get("properties", {}).get(section, {})
prev_section = previous_schema.get("properties", {}).get(section, {})
if not new_section or not prev_section:
continue
new_props = new_section.get("properties", {})
prev_props = prev_section.get("properties", {})
for field_name, field_schema in new_props.items():
if field_name in prev_props:
prev_field = prev_props[field_name]
# 保留字段的 description
if "description" in prev_field and prev_field["description"]:
field_schema["description"] = prev_field["description"]
# 保留字段的 title用户自定义的中文名
if "title" in prev_field and prev_field["title"]:
field_schema["title"] = prev_field["title"]
def _is_typed_dict(self, annotation: Any) -> bool:
"""
检查类型注解是否是TypedDict
@@ -673,13 +755,10 @@ class Registry:
sorted(device_config["class"]["status_types"].items())
)
if complete_registry:
# 保存原有的description信息
old_descriptions = {}
# 保存原有的 action 配置(用于保留 schema 的 description 和 handles 等)
old_action_configs = {}
for action_name, action_config in device_config["class"]["action_value_mappings"].items():
if "description" in action_config.get("schema", {}):
description = action_config["schema"]["description"]
if len(description):
old_descriptions[action_name] = action_config["schema"]["description"]
old_action_configs[action_name] = action_config
device_config["class"]["action_value_mappings"] = {
k: v
@@ -695,10 +774,15 @@ class Registry:
"feedback": {},
"result": {},
"schema": self._generate_unilab_json_command_schema(
v["args"], k, v.get("return_annotation")
v["args"],
k,
v.get("return_annotation"),
# 传入旧的 schema 以保留字段 description
old_action_configs.get(f"auto-{k}", {}).get("schema"),
),
"goal_default": {i["name"]: i["default"] for i in v["args"]},
"handles": [],
# 保留原有的 handles 配置
"handles": old_action_configs.get(f"auto-{k}", {}).get("handles", []),
"placeholder_keys": {
i["name"]: (
"unilabos_resources"
@@ -722,12 +806,14 @@ class Registry:
if k not in device_config["class"]["action_value_mappings"]
}
)
# 恢复原有的description信息auto开头的不修改
for action_name, description in old_descriptions.items():
# 恢复原有的 description 信息(auto- 开头的动作
for action_name, old_config in old_action_configs.items():
if action_name in device_config["class"]["action_value_mappings"]: # 有一些会被删除
device_config["class"]["action_value_mappings"][action_name]["schema"][
"description"
] = description
old_schema = old_config.get("schema", {})
if "description" in old_schema and old_schema["description"]:
device_config["class"]["action_value_mappings"][action_name]["schema"][
"description"
] = old_schema["description"]
device_config["init_param_schema"] = {}
device_config["init_param_schema"]["config"] = self._generate_unilab_json_command_schema(
enhanced_info["init_params"], "__init__"

View File

@@ -0,0 +1,170 @@
# UniLabOS 资源注册架构详解
> **目标受众**: 主要开发 `unilabos/registry/devices` 抽象层的开发者
> **最后更新**: 2026-01-11
> **维护者**: Uni-Lab-OS 开发团队
本文档详细说明 UniLabOS 资源注册系统的架构、资源的完整生命周期,以及如何实现动态物料位置追踪。
---
## 📚 目录
- [核心概念](#核心概念)
- [三层架构详解](#三层架构详解)
- [资源注册机制](#资源注册机制)
- [物料生命周期管理](#物料生命周期管理)
- [动态物料位置追踪](#动态物料位置追踪)
- [实战案例](#实战案例)
- [常见问题排查](#常见问题排查)
---
## 核心概念
### 1. Resources vs Registry
UniLabOS 采用**声明式注册**模式,将资源的**定义**Python与**注册信息**YAML分离
```
┌──────────────────────────────────────────────────────────┐
│ unilabos/resources (Python 实现) │
│ - 定义资源的物理属性、行为和创建逻辑 │
│ - 例如: 瓶子的尺寸、容量、材质 │
├──────────────────────────────────────────────────────────┤
│ unilabos/registry/resources (YAML 注册表) │
│ - 声明哪些资源可以被前端使用 │
│ - 定义资源的分类、图标、初始化参数 │
└──────────────────────────────────────────────────────────┘
```
**为什么要分离?**
1. **解耦**: Python 代码可以定义无限多的资源类,但只有在 YAML 中注册的才能被前端识别
2. **灵活性**: 无需修改 Python 代码,只需修改 YAML 就能添加/移除可用资源
3. **可扩展性**: 第三方开发者可以通过 YAML 注册自己的资源,无需修改核心代码
---
## 三层架构详解
UniLabOS 资源系统采用**三层架构**实现从前端UI到底层硬件的完整映射
### 架构图
```
┌─────────────────────────────────────────────────────┐
│ 第1层: YAML 注册表 (registry/resources) │
│ - 告诉系统"哪些资源可用" │
│ - 前端通过此层获取可用资源列表 │
│ - 文件: YB_bottle.yaml, YB_bottle_carriers.yaml │
├─────────────────────────────────────────────────────┤
│ 第2层: Python 实现 (resources/bioyond) │
│ - 定义资源的具体属性和行为 │
│ - 创建资源实例的工厂函数 │
│ - 文件: YB_bottles.py, YB_bottle_carriers.py │
├─────────────────────────────────────────────────────┤
│ 第3层: Hardware/API 集成 (devices/workstation) │
│ - 连接 Bioyond 系统 API │
│ - 同步物料位置和状态 │
│ - 文件: station.py, bioyond_rpc.py, config.py │
└─────────────────────────────────────────────────────┘
```
### 第1层: YAML 注册表
#### YB_bottle.yaml - 单个瓶子注册
```yaml
YB_5ml_fenyeping:
category:
- yb3 # 系统分类
- YB_bottle # 资源类型
class:
module: unilabos.resources.bioyond.YB_bottles:YB_5ml_fenyeping # Python 函数路径
type: pylabrobot # 框架类型
description: YB_5ml_fenyeping # 前端显示名称
handles: []
icon: '' # 图标路径
init_param_schema: {} # 初始化参数 schema
registry_type: resource
version: 1.0.0
```
**作用:**
- 前端通过读取此文件知道有一个叫 "YB_5ml_fenyeping" 的资源
- 用户拖拽时,系统会调用 `YB_bottles:YB_5ml_fenyeping()` 创建实例
#### YB_bottle_carriers.yaml - 载架(容器)注册
```yaml
YB_5ml_fenyepingban:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_5ml_fenyepingban
type: pylabrobot
description: YB_5ml_fenyepingban # 5ml分液瓶板
```
**作用:**
- 载架是容器,里面可以放多个瓶子
- 例如: `YB_5ml_fenyepingban` 是一个 4x2 布局的板,可以放 8 个 5ml 瓶子
### 第2层: Python 实现
#### YB_bottles.py - 瓶子工厂函数
```python
def YB_5ml_fenyeping(
name: str,
diameter: float = 20.0, # 直径 (mm)
height: float = 50.0, # 高度 (mm)
max_volume: float = 5000.0, # 最大容量 (μL)
barcode: str = None,
) -> Bottle:
\"\"\"创建5ml分液瓶\"\"\"
return Bottle(
name=name,
diameter=diameter,
height=height,
max_volume=max_volume,
barcode=barcode,
model="YB_5ml_fenyeping", # ⭐ 与 YAML 中的名称对应
)
```
**关键点:**
- 函数名 `YB_5ml_fenyeping` 必须与 YAML 中的 `module` 路径末尾一致
- 返回一个 `Bottle` 对象PyLabRobot 资源类型)
- `model` 字段用于在 Bioyond 系统中识别资源类型
**详细文档请参考完整版 README**
---
## 相关文件索引
### 核心文件
| 文件 | 功能 | 路径 |
|------|------|------|
| `YB_bottle.yaml` | 瓶子注册表 | `unilabos/registry/resources/bioyond/` |
| `YB_bottle_carriers.yaml` | 载架注册表 | `unilabos/registry/resources/bioyond/` |
| `deck.yaml` | Deck注册表 | `unilabos/registry/resources/bioyond/` |
| `YB_bottles.py` | 瓶子实现 | `unilabos/resources/bioyond/` |
| `YB_bottle_carriers.py` | 载架实现 | `unilabos/resources/bioyond/` |
| `YB_warehouses.py` | 仓库实现 | `unilabos/resources/bioyond/` |
| `decks.py` | Deck布局 | `unilabos/resources/bioyond/` |
| `station.py` | 物料同步 | `unilabos/devices/workstation/bioyond_studio/` |
| `config.py` | UUID映射 | `unilabos/devices/workstation/bioyond_studio/` |
### 仓库相关文档
- [README_WAREHOUSE.md](../../resources/bioyond/README_WAREHOUSE.md) - 仓库系统开发指南
---
**维护者:** Uni-Lab-OS 开发团队
**最后更新:** 2026-01-11

View File

@@ -0,0 +1,92 @@
YB_20ml_fenyeping:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_20ml_fenyeping
type: pylabrobot
description: YB_20ml_fenyeping
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_5ml_fenyeping:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_5ml_fenyeping
type: pylabrobot
description: YB_5ml_fenyeping
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_jia_yang_tou_da:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_jia_yang_tou_da
type: pylabrobot
description: YB_jia_yang_tou_da
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_pei_ye_da_Bottle:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_pei_ye_da_Bottle
type: pylabrobot
description: YB_pei_ye_da_Bottle
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_pei_ye_xiao_Bottle:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_pei_ye_xiao_Bottle
type: pylabrobot
description: YB_pei_ye_xiao_Bottle
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_qiang_tou:
category:
- yb3
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_qiang_tou
type: pylabrobot
description: YB_qiang_tou
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_ye_Bottle:
category:
- yb3
- YB_bottle_carriers
- YB_bottle
class:
module: unilabos.resources.bioyond.YB_bottles:YB_ye_Bottle
type: pylabrobot
description: YB_ye_Bottle
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0

View File

@@ -0,0 +1,182 @@
YB_100ml_yeti:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_100ml_yeti
type: pylabrobot
description: YB_100ml_yeti
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_20ml_fenyepingban:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_20ml_fenyepingban
type: pylabrobot
description: YB_20ml_fenyepingban
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_5ml_fenyepingban:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_5ml_fenyepingban
type: pylabrobot
description: YB_5ml_fenyepingban
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_6StockCarrier:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6StockCarrier
type: pylabrobot
description: YB_6StockCarrier
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_6VialCarrier:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6VialCarrier
type: pylabrobot
description: YB_6VialCarrier
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_gao_nian_ye_Bottle:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottles:YB_gao_nian_ye_Bottle
type: pylabrobot
description: YB_gao_nian_ye_Bottle
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_gaonianye:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_gaonianye
type: pylabrobot
description: YB_gaonianye
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_jia_yang_tou_da_Carrier:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_jia_yang_tou_da_Carrier
type: pylabrobot
description: YB_jia_yang_tou_da_Carrier
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_peiyepingdaban:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingdaban
type: pylabrobot
description: YB_peiyepingdaban
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_peiyepingxiaoban:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingxiaoban
type: pylabrobot
description: YB_peiyepingxiaoban
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_qiang_tou_he:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_qiang_tou_he
type: pylabrobot
description: YB_qiang_tou_he
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_shi_pei_qi_kuai:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_shi_pei_qi_kuai
type: pylabrobot
description: YB_shi_pei_qi_kuai
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_ye:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_ye
type: pylabrobot
description: YB_ye_Bottle_Carrier
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_ye_100ml_Bottle:
category:
- yb3
- YB_bottle_carriers
class:
module: unilabos.resources.bioyond.YB_bottles:YB_ye_100ml_Bottle
type: pylabrobot
description: YB_ye_100ml_Bottle
handles: []
icon: ''
init_param_schema: {}
registry_type: resource
version: 1.0.0

View File

@@ -20,6 +20,17 @@ BIOYOND_PolymerStation_Liquid_Vial:
icon: ''
init_param_schema: {}
version: 1.0.0
BIOYOND_PolymerStation_Measurement_Vial:
category:
- bottles
class:
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Measurement_Vial
type: pylabrobot
description: 聚合站-测量小瓶(测密度)
handles: []
icon: ''
init_param_schema: {}
version: 1.0.0
BIOYOND_PolymerStation_Reactor:
category:
- bottles

View File

@@ -22,15 +22,27 @@ BIOYOND_PolymerReactionStation_Deck:
init_param_schema: {}
registry_type: resource
version: 1.0.0
YB_Deck11:
BIOYOND_YB_Deck:
category:
- deck
class:
module: unilabos.resources.bioyond.decks:YB_Deck
type: pylabrobot
description: BIOYOND PolymerReactionStation Deck
description: BIOYOND ElectrolyteFormulationStation Deck
handles: []
icon: 配液站.webp
init_param_schema: {}
registry_type: resource
version: 1.0.0
CoincellDeck:
category:
- deck
class:
module: unilabos.devices.workstation.coin_cell_assembly.YB_YH_materials:YH_Deck
type: pylabrobot
description: YIHUA CoinCellAssembly Deck
handles: []
icon: koudian.webp
init_param_schema: {}
registry_type: resource
version: 1.0.0