mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-08 07:55:12 +00:00
Compare commits
5 Commits
e0da1c7217
...
c85c49817d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c85c49817d | ||
|
|
c70eafa5f0 | ||
|
|
b64466d443 | ||
|
|
ef3f24ed48 | ||
|
|
2a8e8d014b |
3
.github/workflows/conda-pack-build.yml
vendored
3
.github/workflows/conda-pack-build.yml
vendored
@@ -207,8 +207,7 @@ jobs:
|
||||
if: steps.should_build.outputs.should_build == 'true' && matrix.platform == 'win-64'
|
||||
run: |
|
||||
echo Packing unilab environment with conda-pack...
|
||||
mamba install conda-pack -c conda-forge -y
|
||||
conda pack -n unilab -o unilab-env-${{ matrix.platform }}.tar.gz --ignore-missing-files
|
||||
mamba activate unilab && conda pack -n unilab -o unilab-env-${{ matrix.platform }}.tar.gz --ignore-missing-files
|
||||
echo Pack file created:
|
||||
dir unilab-env-${{ matrix.platform }}.tar.gz
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ Examples:
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
f.write(readme_content)
|
||||
|
||||
print(f"✓ README.txt created: {output_path}")
|
||||
print(f" README.txt created: {output_path}")
|
||||
print(f" Platform: {args.platform}")
|
||||
print(f" Branch: {args.branch}")
|
||||
|
||||
|
||||
@@ -12,23 +12,13 @@ lab_registry.setup()
|
||||
|
||||
|
||||
type_mapping = {
|
||||
"烧杯": "BIOYOND_PolymerStation_1FlaskCarrier",
|
||||
"试剂瓶": "BIOYOND_PolymerStation_1BottleCarrier",
|
||||
"样品板": "BIOYOND_PolymerStation_6StockCarrier",
|
||||
"分装板": "BIOYOND_PolymerStation_6VialCarrier",
|
||||
"样品瓶": "BIOYOND_PolymerStation_Solid_Stock",
|
||||
"90%分装小瓶": "BIOYOND_PolymerStation_Solid_Vial",
|
||||
"10%分装小瓶": "BIOYOND_PolymerStation_Liquid_Vial",
|
||||
}
|
||||
|
||||
type_uuid_mapping = {
|
||||
"烧杯": "",
|
||||
"试剂瓶": "",
|
||||
"样品板": "",
|
||||
"分装板": "3a14196e-5dfe-6e21-0c79-fe2036d052c4",
|
||||
"样品瓶": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
"90%分装小瓶": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
"10%分装小瓶": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
"烧杯": ("BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||
"试剂瓶": ("BIOYOND_PolymerStation_1BottleCarrier", ""),
|
||||
"样品板": ("BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||
"分装板": ("BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"样品瓶": ("BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||
"90%分装小瓶": ("BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||
"10%分装小瓶": ("BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||
}
|
||||
|
||||
|
||||
|
||||
115
test/resources/test_itemized_carrier.py
Normal file
115
test/resources/test_itemized_carrier.py
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
测试修改后的 get_child_identifier 函数
|
||||
"""
|
||||
|
||||
from unilabos.resources.itemized_carrier import ItemizedCarrier, Bottle
|
||||
from pylabrobot.resources.coordinate import Coordinate
|
||||
|
||||
def test_get_child_identifier_with_indices():
|
||||
"""测试返回x,y,z索引的 get_child_identifier 函数"""
|
||||
|
||||
# 创建一些测试瓶子
|
||||
bottle1 = Bottle("bottle1", diameter=25.0, height=50.0, max_volume=15.0)
|
||||
bottle1.location = Coordinate(10, 20, 5)
|
||||
|
||||
bottle2 = Bottle("bottle2", diameter=25.0, height=50.0, max_volume=15.0)
|
||||
bottle2.location = Coordinate(50, 20, 5)
|
||||
|
||||
bottle3 = Bottle("bottle3", diameter=25.0, height=50.0, max_volume=15.0)
|
||||
bottle3.location = Coordinate(90, 20, 5)
|
||||
|
||||
# 创建载架,指定维度
|
||||
sites = {
|
||||
"A1": bottle1,
|
||||
"A2": bottle2,
|
||||
"A3": bottle3,
|
||||
"B1": None, # 空位
|
||||
"B2": None,
|
||||
"B3": None
|
||||
}
|
||||
|
||||
carrier = ItemizedCarrier(
|
||||
name="test_carrier",
|
||||
size_x=150,
|
||||
size_y=100,
|
||||
size_z=30,
|
||||
num_items_x=3, # 3列
|
||||
num_items_y=2, # 2行
|
||||
num_items_z=1, # 1层
|
||||
sites=sites
|
||||
)
|
||||
|
||||
print("测试载架维度:")
|
||||
print(f"num_items_x: {carrier.num_items_x}")
|
||||
print(f"num_items_y: {carrier.num_items_y}")
|
||||
print(f"num_items_z: {carrier.num_items_z}")
|
||||
print()
|
||||
|
||||
# 测试获取bottle1的标识符信息 (A1 = idx:0, x:0, y:0, z:0)
|
||||
result1 = carrier.get_child_identifier(bottle1)
|
||||
print("测试bottle1 (A1):")
|
||||
print(f" identifier: {result1['identifier']}")
|
||||
print(f" idx: {result1['idx']}")
|
||||
print(f" x index: {result1['x']}")
|
||||
print(f" y index: {result1['y']}")
|
||||
print(f" z index: {result1['z']}")
|
||||
|
||||
# Assert 验证 bottle1 (A1) 的结果
|
||||
assert result1['identifier'] == 'A1', f"Expected identifier 'A1', got '{result1['identifier']}'"
|
||||
assert result1['idx'] == 0, f"Expected idx 0, got {result1['idx']}"
|
||||
assert result1['x'] == 0, f"Expected x index 0, got {result1['x']}"
|
||||
assert result1['y'] == 0, f"Expected y index 0, got {result1['y']}"
|
||||
assert result1['z'] == 0, f"Expected z index 0, got {result1['z']}"
|
||||
print(" ✓ bottle1 (A1) 测试通过")
|
||||
print()
|
||||
|
||||
# 测试获取bottle2的标识符信息 (A2 = idx:1, x:1, y:0, z:0)
|
||||
result2 = carrier.get_child_identifier(bottle2)
|
||||
print("测试bottle2 (A2):")
|
||||
print(f" identifier: {result2['identifier']}")
|
||||
print(f" idx: {result2['idx']}")
|
||||
print(f" x index: {result2['x']}")
|
||||
print(f" y index: {result2['y']}")
|
||||
print(f" z index: {result2['z']}")
|
||||
|
||||
# Assert 验证 bottle2 (A2) 的结果
|
||||
assert result2['identifier'] == 'A2', f"Expected identifier 'A2', got '{result2['identifier']}'"
|
||||
assert result2['idx'] == 1, f"Expected idx 1, got {result2['idx']}"
|
||||
assert result2['x'] == 1, f"Expected x index 1, got {result2['x']}"
|
||||
assert result2['y'] == 0, f"Expected y index 0, got {result2['y']}"
|
||||
assert result2['z'] == 0, f"Expected z index 0, got {result2['z']}"
|
||||
print(" ✓ bottle2 (A2) 测试通过")
|
||||
print()
|
||||
|
||||
# 测试获取bottle3的标识符信息 (A3 = idx:2, x:2, y:0, z:0)
|
||||
result3 = carrier.get_child_identifier(bottle3)
|
||||
print("测试bottle3 (A3):")
|
||||
print(f" identifier: {result3['identifier']}")
|
||||
print(f" idx: {result3['idx']}")
|
||||
print(f" x index: {result3['x']}")
|
||||
print(f" y index: {result3['y']}")
|
||||
print(f" z index: {result3['z']}")
|
||||
|
||||
# Assert 验证 bottle3 (A3) 的结果
|
||||
assert result3['identifier'] == 'A3', f"Expected identifier 'A3', got '{result3['identifier']}'"
|
||||
assert result3['idx'] == 2, f"Expected idx 2, got {result3['idx']}"
|
||||
assert result3['x'] == 2, f"Expected x index 2, got {result3['x']}"
|
||||
assert result3['y'] == 0, f"Expected y index 0, got {result3['y']}"
|
||||
assert result3['z'] == 0, f"Expected z index 0, got {result3['z']}"
|
||||
print(" ✓ bottle3 (A3) 测试通过")
|
||||
print()
|
||||
|
||||
# 测试错误情况:查找不存在的资源
|
||||
bottle_not_exists = Bottle("bottle_not_exists", diameter=25.0, height=50.0, max_volume=15.0)
|
||||
try:
|
||||
carrier.get_child_identifier(bottle_not_exists)
|
||||
assert False, "应该抛出 ValueError 异常"
|
||||
except ValueError as e:
|
||||
print("✓ 正确抛出了 ValueError 异常:", str(e))
|
||||
assert "is not assigned to this carrier" in str(e), "异常消息应该包含预期的文本"
|
||||
|
||||
print("\n🎉 所有测试都通过了!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_get_child_identifier_with_indices()
|
||||
@@ -37,7 +37,7 @@ def _initialize_material_system(self, deck_config: Dict[str, Any], children_conf
|
||||
**定义在**: `workstation_base.py`
|
||||
|
||||
**设计目的**:
|
||||
- 提供外部物料系统(如Bioyong、LIMS等)集成的标准接口
|
||||
- 提供外部物料系统(如Bioyond、LIMS等)集成的标准接口
|
||||
- 双向同步:从外部系统同步到本地deck,以及将本地变更同步到外部系统
|
||||
- 处理外部系统的变更通知
|
||||
|
||||
@@ -59,7 +59,7 @@ async def handle_external_change(self, change_info: Dict[str, Any]) -> bool:
|
||||
**扩展功能**:
|
||||
- HTTP报送接收服务集成
|
||||
- 具体工作流实现(液体转移、板洗等)
|
||||
- Bioyong物料系统同步器示例
|
||||
- Bioyond物料系统同步器示例
|
||||
- 外部报送处理方法
|
||||
|
||||
## 技术栈
|
||||
@@ -142,11 +142,11 @@ success = workstation.execute_workflow("liquid_transfer", {
|
||||
### 3. 外部系统集成
|
||||
|
||||
```python
|
||||
class BioyongResourceSynchronizer(ResourceSynchronizer):
|
||||
"""Bioyong系统同步器"""
|
||||
class BioyondResourceSynchronizer(ResourceSynchronizer):
|
||||
"""Bioyond系统同步器"""
|
||||
|
||||
async def sync_from_external(self) -> bool:
|
||||
# 从Bioyong API获取物料
|
||||
# 从Bioyond API获取物料
|
||||
external_materials = await self._fetch_bioyong_materials()
|
||||
|
||||
# 转换并添加到本地deck
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,22 +9,6 @@ API_CONFIG = {
|
||||
"api_host": ""
|
||||
}
|
||||
|
||||
# 站点类型配置
|
||||
STATION_TYPES = {
|
||||
"REACTION": "reaction_station", # 仅反应站
|
||||
"DISPENSING": "dispensing_station", # 仅配液站
|
||||
"HYBRID": "hybrid_station" # 混合模式
|
||||
}
|
||||
|
||||
# 默认站点配置
|
||||
DEFAULT_STATION_CONFIG = {
|
||||
"station_type": STATION_TYPES["REACTION"], # 默认反应站模式
|
||||
"enable_reaction_station": True, # 是否启用反应站功能
|
||||
"enable_dispensing_station": False, # 是否启用配液站功能
|
||||
"station_name": "BioyondReactionStation", # 站点名称
|
||||
"description": "Bioyond反应工作站" # 站点描述
|
||||
}
|
||||
|
||||
# 工作流映射配置
|
||||
WORKFLOW_MAPPINGS = {
|
||||
"reactor_taken_out": "",
|
||||
@@ -49,52 +33,75 @@ WORKFLOW_TO_SECTION_MAP = {
|
||||
}
|
||||
|
||||
# 库位映射配置
|
||||
LOCATION_MAPPING = {
|
||||
'A01': '',
|
||||
'A02': '',
|
||||
'A03': '',
|
||||
'A04': '',
|
||||
'A05': '',
|
||||
'A06': '',
|
||||
'A07': '',
|
||||
'A08': '',
|
||||
'B01': '',
|
||||
'B02': '',
|
||||
'B03': '',
|
||||
'B04': '',
|
||||
'B05': '',
|
||||
'B06': '',
|
||||
'B07': '',
|
||||
'B08': '',
|
||||
'C01': '',
|
||||
'C02': '',
|
||||
'C03': '',
|
||||
'C04': '',
|
||||
'C05': '',
|
||||
'C06': '',
|
||||
'C07': '',
|
||||
'C08': '',
|
||||
'D01': '',
|
||||
'D02': '',
|
||||
'D03': '',
|
||||
'D04': '',
|
||||
'D05': '',
|
||||
'D06': '',
|
||||
'D07': '',
|
||||
'D08': '',
|
||||
WAREHOUSE_MAPPING = {
|
||||
"粉末堆栈": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
# 样品板
|
||||
"A1": "3a14198e-6929-31f0-8a22-0f98f72260df",
|
||||
"A2": "3a14198e-6929-4379-affa-9a2935c17f99",
|
||||
"A3": "3a14198e-6929-56da-9a1c-7f5fbd4ae8af",
|
||||
"A4": "3a14198e-6929-5e99-2b79-80720f7cfb54",
|
||||
"B1": "3a14198e-6929-f525-9a1b-1857552b28ee",
|
||||
"B2": "3a14198e-6929-bf98-0fd5-26e1d68bf62d",
|
||||
"B3": "3a14198e-6929-2d86-a468-602175a2b5aa",
|
||||
"B4": "3a14198e-6929-1a98-ae57-e97660c489ad",
|
||||
# 分装板
|
||||
"C1": "3a14198e-6929-46fe-841e-03dd753f1e4a",
|
||||
"C2": "3a14198e-6929-1bc9-a9bd-3b7ca66e7f95",
|
||||
"C3": "3a14198e-6929-72ac-32ce-9b50245682b8",
|
||||
"C4": "3a14198e-6929-3bd8-e6c7-4a9fd93be118",
|
||||
"D1": "3a14198e-6929-8a0b-b686-6f4a2955c4e2",
|
||||
"D2": "3a14198e-6929-dde1-fc78-34a84b71afdf",
|
||||
"D3": "3a14198e-6929-a0ec-5f15-c0f9f339f963",
|
||||
"D4": "3a14198e-6929-7ac8-915a-fea51cb2e884"
|
||||
}
|
||||
},
|
||||
"溶液堆栈": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A1": "3a14198e-d724-e036-afdc-2ae39a7f3383",
|
||||
"A2": "3a14198e-d724-afa4-fc82-0ac8a9016791",
|
||||
"A3": "3a14198e-d724-ca48-bb9e-7e85751e55b6",
|
||||
"A4": "3a14198e-d724-df6d-5e32-5483b3cab583",
|
||||
"B1": "3a14198e-d724-d818-6d4f-5725191a24b5",
|
||||
"B2": "3a14198e-d724-be8a-5e0b-012675e195c6",
|
||||
"B3": "3a14198e-d724-cc1e-5c2c-228a130f40a8",
|
||||
"B4": "3a14198e-d724-1e28-c885-574c3df468d0",
|
||||
"C1": "3a14198e-d724-b5bb-adf3-4c5a0da6fb31",
|
||||
"C2": "3a14198e-d724-ab4e-48cb-817c3c146707",
|
||||
"C3": "3a14198e-d724-7f18-1853-39d0c62e1d33",
|
||||
"C4": "3a14198e-d724-28a2-a760-baa896f46b66",
|
||||
"D1": "3a14198e-d724-d378-d266-2508a224a19f",
|
||||
"D2": "3a14198e-d724-f56e-468b-0110a8feb36a",
|
||||
"D3": "3a14198e-d724-0cf1-dea9-a1f40fe7e13c",
|
||||
"D4": "3a14198e-d724-0ddd-9654-f9352a421de9"
|
||||
}
|
||||
},
|
||||
"试剂堆栈": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A1": "3a14198c-c2cf-8b40-af28-b467808f1c36",
|
||||
"A2": "3a14198c-c2d0-f3e7-871a-e470d144296f",
|
||||
"A3": "3a14198c-c2d0-dc7d-b8d0-e1d88cee3094",
|
||||
"A4": "3a14198c-c2d0-2070-efc8-44e245f10c6f",
|
||||
"B1": "3a14198c-c2d0-354f-39ad-642e1a72fcb8",
|
||||
"B2": "3a14198c-c2d0-1559-105d-0ea30682cab4",
|
||||
"B3": "3a14198c-c2d0-725e-523d-34c037ac2440",
|
||||
"B4": "3a14198c-c2d0-efce-0939-69ca5a7dfd39"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 物料类型配置
|
||||
MATERIAL_TYPE_IDS = {
|
||||
"样品板": "",
|
||||
"样品": "",
|
||||
"烧杯": ""
|
||||
}
|
||||
|
||||
MATERIAL_TYPE_MAPPINGS = {
|
||||
"烧杯": "BIOYOND_PolymerStation_1FlaskCarrier",
|
||||
"试剂瓶": "BIOYOND_PolymerStation_1BottleCarrier",
|
||||
"样品板": "BIOYOND_PolymerStation_6VialCarrier",
|
||||
"烧杯": ("BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||
"试剂瓶": ("BIOYOND_PolymerStation_1BottleCarrier", ""),
|
||||
"样品板": ("BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||
"分装板": ("BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"样品瓶": ("BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||
"90%分装小瓶": ("BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||
"10%分装小瓶": ("BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||
}
|
||||
|
||||
# 步骤参数配置(各工作流的步骤UUID)
|
||||
@@ -127,3 +134,5 @@ WORKFLOW_STEP_IDS = {
|
||||
"observe": ""
|
||||
}
|
||||
}
|
||||
|
||||
LOCATION_MAPPING = {}
|
||||
@@ -0,0 +1,824 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from unilabos.devices.workstation.bioyond_studio.bioyond_rpc import BioyondException
|
||||
from unilabos.devices.workstation.bioyond_studio.station import BioyondWorkstation
|
||||
|
||||
|
||||
class BioyondDispensingStation(BioyondWorkstation):
|
||||
def __init__(self, config):
|
||||
super().__init__(config)
|
||||
# self.config = config
|
||||
# self.api_key = config["api_key"]
|
||||
# self.host = config["api_host"]
|
||||
#
|
||||
# # 使用简单的Logger替代原来的logger
|
||||
# self._logger = SimpleLogger()
|
||||
# self.is_running = False
|
||||
|
||||
# 90%10%小瓶投料任务创建方法
|
||||
def create_90_10_vial_feeding_task(self,
|
||||
order_name: str = None,
|
||||
speed: str = None,
|
||||
temperature: str = None,
|
||||
delay_time: str = None,
|
||||
percent_90_1_assign_material_name: str = None,
|
||||
percent_90_1_target_weigh: str = None,
|
||||
percent_90_2_assign_material_name: str = None,
|
||||
percent_90_2_target_weigh: str = None,
|
||||
percent_90_3_assign_material_name: str = None,
|
||||
percent_90_3_target_weigh: str = None,
|
||||
percent_10_1_assign_material_name: str = None,
|
||||
percent_10_1_target_weigh: str = None,
|
||||
percent_10_1_volume: str = None,
|
||||
percent_10_1_liquid_material_name: str = None,
|
||||
percent_10_2_assign_material_name: str = None,
|
||||
percent_10_2_target_weigh: str = None,
|
||||
percent_10_2_volume: str = None,
|
||||
percent_10_2_liquid_material_name: str = None,
|
||||
percent_10_3_assign_material_name: str = None,
|
||||
percent_10_3_target_weigh: str = None,
|
||||
percent_10_3_volume: str = None,
|
||||
percent_10_3_liquid_material_name: str = None,
|
||||
hold_m_name: str = None) -> dict:
|
||||
"""
|
||||
创建90%10%小瓶投料任务
|
||||
|
||||
参数说明:
|
||||
- order_name: 任务名称,如果为None则使用默认名称
|
||||
- speed: 搅拌速度,如果为None则使用默认值400
|
||||
- temperature: 温度,如果为None则使用默认值40
|
||||
- delay_time: 延迟时间,如果为None则使用默认值600
|
||||
- percent_90_1_assign_material_name: 90%_1物料名称
|
||||
- percent_90_1_target_weigh: 90%_1目标重量
|
||||
- percent_90_2_assign_material_name: 90%_2物料名称
|
||||
- percent_90_2_target_weigh: 90%_2目标重量
|
||||
- percent_90_3_assign_material_name: 90%_3物料名称
|
||||
- percent_90_3_target_weigh: 90%_3目标重量
|
||||
- percent_10_1_assign_material_name: 10%_1固体物料名称
|
||||
- percent_10_1_target_weigh: 10%_1固体目标重量
|
||||
- percent_10_1_volume: 10%_1液体体积
|
||||
- percent_10_1_liquid_material_name: 10%_1液体物料名称
|
||||
- percent_10_2_assign_material_name: 10%_2固体物料名称
|
||||
- percent_10_2_target_weigh: 10%_2固体目标重量
|
||||
- percent_10_2_volume: 10%_2液体体积
|
||||
- percent_10_2_liquid_material_name: 10%_2液体物料名称
|
||||
- percent_10_3_assign_material_name: 10%_3固体物料名称
|
||||
- percent_10_3_target_weigh: 10%_3固体目标重量
|
||||
- percent_10_3_volume: 10%_3液体体积
|
||||
- percent_10_3_liquid_material_name: 10%_3液体物料名称
|
||||
- hold_m_name: 库位名称,如"C01",用于查找对应的holdMId
|
||||
|
||||
返回: 任务创建结果
|
||||
|
||||
异常:
|
||||
- BioyondException: 各种错误情况下的统一异常
|
||||
"""
|
||||
try:
|
||||
# 1. 参数验证
|
||||
if not hold_m_name:
|
||||
raise BioyondException("hold_m_name 是必填参数")
|
||||
|
||||
# 检查90%物料参数的完整性
|
||||
# 90%_1物料:如果有物料名称或目标重量,就必须有全部参数
|
||||
if percent_90_1_assign_material_name or percent_90_1_target_weigh:
|
||||
if not percent_90_1_assign_material_name:
|
||||
raise BioyondException("90%_1物料:如果提供了目标重量,必须同时提供物料名称")
|
||||
if not percent_90_1_target_weigh:
|
||||
raise BioyondException("90%_1物料:如果提供了物料名称,必须同时提供目标重量")
|
||||
|
||||
# 90%_2物料:如果有物料名称或目标重量,就必须有全部参数
|
||||
if percent_90_2_assign_material_name or percent_90_2_target_weigh:
|
||||
if not percent_90_2_assign_material_name:
|
||||
raise BioyondException("90%_2物料:如果提供了目标重量,必须同时提供物料名称")
|
||||
if not percent_90_2_target_weigh:
|
||||
raise BioyondException("90%_2物料:如果提供了物料名称,必须同时提供目标重量")
|
||||
|
||||
# 90%_3物料:如果有物料名称或目标重量,就必须有全部参数
|
||||
if percent_90_3_assign_material_name or percent_90_3_target_weigh:
|
||||
if not percent_90_3_assign_material_name:
|
||||
raise BioyondException("90%_3物料:如果提供了目标重量,必须同时提供物料名称")
|
||||
if not percent_90_3_target_weigh:
|
||||
raise BioyondException("90%_3物料:如果提供了物料名称,必须同时提供目标重量")
|
||||
|
||||
# 检查10%物料参数的完整性
|
||||
# 10%_1物料:如果有物料名称、目标重量、体积或液体物料名称中的任何一个,就必须有全部参数
|
||||
if any([percent_10_1_assign_material_name, percent_10_1_target_weigh, percent_10_1_volume, percent_10_1_liquid_material_name]):
|
||||
if not percent_10_1_assign_material_name:
|
||||
raise BioyondException("10%_1物料:如果提供了其他参数,必须同时提供固体物料名称")
|
||||
if not percent_10_1_target_weigh:
|
||||
raise BioyondException("10%_1物料:如果提供了其他参数,必须同时提供固体目标重量")
|
||||
if not percent_10_1_volume:
|
||||
raise BioyondException("10%_1物料:如果提供了其他参数,必须同时提供液体体积")
|
||||
if not percent_10_1_liquid_material_name:
|
||||
raise BioyondException("10%_1物料:如果提供了其他参数,必须同时提供液体物料名称")
|
||||
|
||||
# 10%_2物料:如果有物料名称、目标重量、体积或液体物料名称中的任何一个,就必须有全部参数
|
||||
if any([percent_10_2_assign_material_name, percent_10_2_target_weigh, percent_10_2_volume, percent_10_2_liquid_material_name]):
|
||||
if not percent_10_2_assign_material_name:
|
||||
raise BioyondException("10%_2物料:如果提供了其他参数,必须同时提供固体物料名称")
|
||||
if not percent_10_2_target_weigh:
|
||||
raise BioyondException("10%_2物料:如果提供了其他参数,必须同时提供固体目标重量")
|
||||
if not percent_10_2_volume:
|
||||
raise BioyondException("10%_2物料:如果提供了其他参数,必须同时提供液体体积")
|
||||
if not percent_10_2_liquid_material_name:
|
||||
raise BioyondException("10%_2物料:如果提供了其他参数,必须同时提供液体物料名称")
|
||||
|
||||
# 10%_3物料:如果有物料名称、目标重量、体积或液体物料名称中的任何一个,就必须有全部参数
|
||||
if any([percent_10_3_assign_material_name, percent_10_3_target_weigh, percent_10_3_volume, percent_10_3_liquid_material_name]):
|
||||
if not percent_10_3_assign_material_name:
|
||||
raise BioyondException("10%_3物料:如果提供了其他参数,必须同时提供固体物料名称")
|
||||
if not percent_10_3_target_weigh:
|
||||
raise BioyondException("10%_3物料:如果提供了其他参数,必须同时提供固体目标重量")
|
||||
if not percent_10_3_volume:
|
||||
raise BioyondException("10%_3物料:如果提供了其他参数,必须同时提供液体体积")
|
||||
if not percent_10_3_liquid_material_name:
|
||||
raise BioyondException("10%_3物料:如果提供了其他参数,必须同时提供液体物料名称")
|
||||
|
||||
# 2. 生成任务编码和设置默认值
|
||||
order_code = "task_vial_" + str(int(datetime.now().timestamp()))
|
||||
if order_name is None:
|
||||
order_name = "90%10%小瓶投料任务"
|
||||
if speed is None:
|
||||
speed = "400"
|
||||
if temperature is None:
|
||||
temperature = "40"
|
||||
if delay_time is None:
|
||||
delay_time = "600"
|
||||
|
||||
# 3. 工作流ID
|
||||
workflow_id = "3a19310d-16b9-9d81-b109-0748e953694b"
|
||||
|
||||
# 4. 查询工作流对应的holdMID
|
||||
material_info = self.hardware_interface.material_id_query(workflow_id)
|
||||
if not material_info:
|
||||
raise BioyondException(f"无法查询工作流 {workflow_id} 的物料信息")
|
||||
|
||||
# 获取locations列表
|
||||
locations = material_info.get("locations", []) if isinstance(material_info, dict) else []
|
||||
if not locations:
|
||||
raise BioyondException(f"工作流 {workflow_id} 没有找到库位信息")
|
||||
|
||||
# 查找指定名称的库位
|
||||
hold_mid = None
|
||||
for location in locations:
|
||||
if location.get("holdMName") == hold_m_name:
|
||||
hold_mid = location.get("holdMId")
|
||||
break
|
||||
|
||||
if not hold_mid:
|
||||
raise BioyondException(f"未找到库位名称为 {hold_m_name} 的库位,请检查名称是否正确")
|
||||
|
||||
extend_properties = f"{{\"{ hold_mid }\": {{}}}}"
|
||||
self.hardware_interface._logger.info(f"找到库位 {hold_m_name} 对应的holdMId: {hold_mid}")
|
||||
|
||||
# 5. 构建任务参数
|
||||
order_data = {
|
||||
"orderCode": order_code,
|
||||
"orderName": order_name,
|
||||
"workflowId": workflow_id,
|
||||
"borderNumber": 1,
|
||||
"paramValues": {},
|
||||
"ExtendProperties": extend_properties
|
||||
}
|
||||
|
||||
# 添加搅拌参数
|
||||
order_data["paramValues"]["e8264e47-c319-d9d9-8676-4dd5cb382b11"] = [
|
||||
{"m": 0, "n": 3, "Key": "speed", "Value": speed},
|
||||
{"m": 0, "n": 3, "Key": "temperature", "Value": temperature}
|
||||
]
|
||||
|
||||
# 添加延迟时间参数
|
||||
order_data["paramValues"]["dc5dba79-5e4b-8eae-cbc5-e93482e43b1f"] = [
|
||||
{"m": 0, "n": 4, "Key": "DelayTime", "Value": delay_time}
|
||||
]
|
||||
|
||||
# 添加90%_1参数
|
||||
if percent_90_1_assign_material_name is not None and percent_90_1_target_weigh is not None:
|
||||
order_data["paramValues"]["e7d3c0a3-25c2-c42d-c84b-860c4a5ef844"] = [
|
||||
{"m": 15, "n": 1, "Key": "targetWeigh", "Value": percent_90_1_target_weigh},
|
||||
{"m": 15, "n": 1, "Key": "assignMaterialName", "Value": percent_90_1_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加90%_2参数
|
||||
if percent_90_2_assign_material_name is not None and percent_90_2_target_weigh is not None:
|
||||
order_data["paramValues"]["50b912c4-6c81-0734-1c8b-532428b2a4a5"] = [
|
||||
{"m": 18, "n": 1, "Key": "targetWeigh", "Value": percent_90_2_target_weigh},
|
||||
{"m": 18, "n": 1, "Key": "assignMaterialName", "Value": percent_90_2_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加90%_3参数
|
||||
if percent_90_3_assign_material_name is not None and percent_90_3_target_weigh is not None:
|
||||
order_data["paramValues"]["9c3674b3-c7cb-946e-fa03-fa2861d8aec4"] = [
|
||||
{"m": 21, "n": 1, "Key": "targetWeigh", "Value": percent_90_3_target_weigh},
|
||||
{"m": 21, "n": 1, "Key": "assignMaterialName", "Value": percent_90_3_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_1固体参数
|
||||
if percent_10_1_assign_material_name is not None and percent_10_1_target_weigh is not None:
|
||||
order_data["paramValues"]["73a0bfd8-1967-45e9-4bab-c07ccd1a2727"] = [
|
||||
{"m": 3, "n": 1, "Key": "targetWeigh", "Value": percent_10_1_target_weigh},
|
||||
{"m": 3, "n": 1, "Key": "assignMaterialName", "Value": percent_10_1_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_1液体参数
|
||||
if percent_10_1_liquid_material_name is not None and percent_10_1_volume is not None:
|
||||
order_data["paramValues"]["39634d40-c623-473a-8e5f-bc301aca2522"] = [
|
||||
{"m": 3, "n": 3, "Key": "volume", "Value": percent_10_1_volume},
|
||||
{"m": 3, "n": 3, "Key": "assignMaterialName", "Value": percent_10_1_liquid_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_2固体参数
|
||||
if percent_10_2_assign_material_name is not None and percent_10_2_target_weigh is not None:
|
||||
order_data["paramValues"]["2d9c16fa-2a19-cd47-a67b-3cadff9e3e3d"] = [
|
||||
{"m": 7, "n": 1, "Key": "targetWeigh", "Value": percent_10_2_target_weigh},
|
||||
{"m": 7, "n": 1, "Key": "assignMaterialName", "Value": percent_10_2_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_2液体参数
|
||||
if percent_10_2_liquid_material_name is not None and percent_10_2_volume is not None:
|
||||
order_data["paramValues"]["e60541bb-ed68-e839-7305-2b4abe38a13d"] = [
|
||||
{"m": 7, "n": 3, "Key": "volume", "Value": percent_10_2_volume},
|
||||
{"m": 7, "n": 3, "Key": "assignMaterialName", "Value": percent_10_2_liquid_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_3固体参数
|
||||
if percent_10_3_assign_material_name is not None and percent_10_3_target_weigh is not None:
|
||||
order_data["paramValues"]["27494733-0f71-a916-7cd2-1929a0125f17"] = [
|
||||
{"m": 11, "n": 1, "Key": "targetWeigh", "Value": percent_10_3_target_weigh},
|
||||
{"m": 11, "n": 1, "Key": "assignMaterialName", "Value": percent_10_3_assign_material_name}
|
||||
]
|
||||
|
||||
# 添加10%_3液体参数
|
||||
if percent_10_3_liquid_material_name is not None and percent_10_3_volume is not None:
|
||||
order_data["paramValues"]["c8798c29-786f-6858-7d7f-5330b890f2a6"] = [
|
||||
{"m": 11, "n": 3, "Key": "volume", "Value": percent_10_3_volume},
|
||||
{"m": 11, "n": 3, "Key": "assignMaterialName", "Value": percent_10_3_liquid_material_name}
|
||||
]
|
||||
|
||||
# 6. 转换为JSON字符串并创建任务
|
||||
json_str = json.dumps([order_data], ensure_ascii=False)
|
||||
self.hardware_interface._logger.info(f"创建90%10%小瓶投料任务参数: {json_str}")
|
||||
|
||||
# 7. 调用create_order方法创建任务
|
||||
result = self.hardware_interface.create_order(json_str)
|
||||
self.hardware_interface._logger.info(f"创建90%10%小瓶投料任务结果: {result}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
except BioyondException:
|
||||
# 重新抛出BioyondException
|
||||
raise
|
||||
except Exception as e:
|
||||
# 捕获其他未预期的异常,转换为BioyondException
|
||||
error_msg = f"创建90%10%小瓶投料任务时发生未预期的错误: {str(e)}"
|
||||
self.hardware_interface._logger.error(error_msg)
|
||||
raise BioyondException(error_msg)
|
||||
|
||||
# 二胺溶液配置任务创建方法
|
||||
def create_diamine_solution_task(self,
|
||||
order_name: str = None,
|
||||
material_name: str = None,
|
||||
target_weigh: str = None,
|
||||
volume: str = None,
|
||||
liquid_material_name: str = "NMP",
|
||||
speed: str = None,
|
||||
temperature: str = None,
|
||||
delay_time: str = None,
|
||||
hold_m_name: str = None) -> dict:
|
||||
"""
|
||||
创建二胺溶液配置任务
|
||||
|
||||
参数说明:
|
||||
- order_name: 任务名称,如果为None则使用默认名称
|
||||
- material_name: 固体物料名称,必填
|
||||
- target_weigh: 固体目标重量,必填
|
||||
- volume: 液体体积,必填
|
||||
- liquid_material_name: 液体物料名称,默认为NMP
|
||||
- speed: 搅拌速度,如果为None则使用默认值400
|
||||
- temperature: 温度,如果为None则使用默认值20
|
||||
- delay_time: 延迟时间,如果为None则使用默认值600
|
||||
- hold_m_name: 库位名称,如"ODA-1",用于查找对应的holdMId
|
||||
|
||||
返回: 任务创建结果
|
||||
|
||||
异常:
|
||||
- BioyondException: 各种错误情况下的统一异常
|
||||
"""
|
||||
try:
|
||||
# 1. 参数验证
|
||||
if not material_name:
|
||||
raise BioyondException("material_name 是必填参数")
|
||||
if not target_weigh:
|
||||
raise BioyondException("target_weigh 是必填参数")
|
||||
if not volume:
|
||||
raise BioyondException("volume 是必填参数")
|
||||
if not hold_m_name:
|
||||
raise BioyondException("hold_m_name 是必填参数")
|
||||
|
||||
|
||||
# 2. 生成任务编码和设置默认值
|
||||
order_code = "task_oda_" + str(int(datetime.now().timestamp()))
|
||||
if order_name is None:
|
||||
order_name = f"二胺溶液配置-{material_name}"
|
||||
if speed is None:
|
||||
speed = "400"
|
||||
if temperature is None:
|
||||
temperature = "20"
|
||||
if delay_time is None:
|
||||
delay_time = "600"
|
||||
|
||||
# 3. 工作流ID - 二胺溶液配置工作流
|
||||
workflow_id = "3a15d4a1-3bbe-76f9-a458-292896a338f5"
|
||||
|
||||
# 4. 查询工作流对应的holdMID
|
||||
material_info = self.material_id_query(workflow_id)
|
||||
if not material_info:
|
||||
raise BioyondException(f"无法查询工作流 {workflow_id} 的物料信息")
|
||||
|
||||
# 获取locations列表
|
||||
locations = material_info.get("locations", []) if isinstance(material_info, dict) else []
|
||||
if not locations:
|
||||
raise BioyondException(f"工作流 {workflow_id} 没有找到库位信息")
|
||||
|
||||
# 查找指定名称的库位
|
||||
hold_mid = None
|
||||
for location in locations:
|
||||
if location.get("holdMName") == hold_m_name:
|
||||
hold_mid = location.get("holdMId")
|
||||
break
|
||||
|
||||
if not hold_mid:
|
||||
raise BioyondException(f"未找到库位名称为 {hold_m_name} 的库位,请检查名称是否正确")
|
||||
|
||||
extend_properties = f"{{\"{ hold_mid }\": {{}}}}"
|
||||
self.hardware_interface._logger.info(f"找到库位 {hold_m_name} 对应的holdMId: {hold_mid}")
|
||||
|
||||
# 5. 构建任务参数
|
||||
order_data = {
|
||||
"orderCode": order_code,
|
||||
"orderName": order_name,
|
||||
"workflowId": workflow_id,
|
||||
"borderNumber": 1,
|
||||
"paramValues": {
|
||||
# 固体物料参数
|
||||
"3a15d4a1-3bde-f5bc-053f-1ae0bf1f357e": [
|
||||
{"m": 3, "n": 2, "Key": "targetWeigh", "Value": target_weigh},
|
||||
{"m": 3, "n": 2, "Key": "assignMaterialName", "Value": material_name}
|
||||
],
|
||||
# 液体物料参数
|
||||
"3a15d4a1-3bde-d584-b309-e661ae8f1c01": [
|
||||
{"m": 3, "n": 3, "Key": "volume", "Value": volume},
|
||||
{"m": 3, "n": 3, "Key": "assignMaterialName", "Value": liquid_material_name}
|
||||
],
|
||||
# 搅拌参数
|
||||
"3a15d4a1-3bde-8ec4-1ced-92efc97ed73d": [
|
||||
{"m": 3, "n": 6, "Key": "speed", "Value": speed},
|
||||
{"m": 3, "n": 6, "Key": "temperature", "Value": temperature}
|
||||
],
|
||||
# 延迟时间参数
|
||||
"3a15d4a1-3bde-3b92-83ff-8923a0addbbc": [
|
||||
{"m": 3, "n": 7, "Key": "DelayTime", "Value": delay_time}
|
||||
]
|
||||
},
|
||||
"ExtendProperties": extend_properties
|
||||
}
|
||||
|
||||
# 6. 转换为JSON字符串并创建任务
|
||||
json_str = json.dumps([order_data], ensure_ascii=False)
|
||||
self.hardware_interface._logger.info(f"创建二胺溶液配置任务参数: {json_str}")
|
||||
|
||||
# 7. 调用create_order方法创建任务
|
||||
result = self.hardware_interface.create_order(json_str)
|
||||
self.hardware_interface._logger.info(f"创建二胺溶液配置任务结果: {result}")
|
||||
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
except BioyondException:
|
||||
# 重新抛出BioyondException
|
||||
raise
|
||||
except Exception as e:
|
||||
# 捕获其他未预期的异常,转换为BioyondException
|
||||
error_msg = f"创建二胺溶液配置任务时发生未预期的错误: {str(e)}"
|
||||
self.hardware_interface._logger.error(error_msg)
|
||||
raise BioyondException(error_msg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
bioyond = BioyondDispensingStation(config={
|
||||
"api_key": "DE9BDDA0",
|
||||
"api_host": "http://192.168.1.200:44388"
|
||||
})
|
||||
|
||||
# 示例1:使用material_id_query查询工作流对应的holdMID
|
||||
workflow_id_1 = "3a15d4a1-3bbe-76f9-a458-292896a338f5" # 二胺溶液配置工作流ID
|
||||
workflow_id_2 = "3a19310d-16b9-9d81-b109-0748e953694b" # 90%10%小瓶投料工作流ID
|
||||
|
||||
#示例2:创建二胺溶液配置任务 - ODA,指定库位名称
|
||||
# bioyond.create_diamine_solution_task(
|
||||
# order_code="task_oda_" + str(int(datetime.now().timestamp())),
|
||||
# order_name="二胺溶液配置-ODA",
|
||||
# material_name="ODA-1",
|
||||
# target_weigh="12.000",
|
||||
# volume="60",
|
||||
# liquid_material_name= "NMP",
|
||||
# speed="400",
|
||||
# temperature="20",
|
||||
# delay_time="600",
|
||||
# hold_m_name="烧杯ODA"
|
||||
# )
|
||||
|
||||
# bioyond.create_diamine_solution_task(
|
||||
# order_code="task_pda_" + str(int(datetime.now().timestamp())),
|
||||
# order_name="二胺溶液配置-PDA",
|
||||
# material_name="PDA-1",
|
||||
# target_weigh="4.178",
|
||||
# volume="60",
|
||||
# liquid_material_name= "NMP",
|
||||
# speed="400",
|
||||
# temperature="20",
|
||||
# delay_time="600",
|
||||
# hold_m_name="烧杯PDA-2"
|
||||
# )
|
||||
|
||||
# bioyond.create_diamine_solution_task(
|
||||
# order_code="task_mpda_" + str(int(datetime.now().timestamp())),
|
||||
# order_name="二胺溶液配置-MPDA",
|
||||
# material_name="MPDA-1",
|
||||
# target_weigh="3.298",
|
||||
# volume="50",
|
||||
# liquid_material_name= "NMP",
|
||||
# speed="400",
|
||||
# temperature="20",
|
||||
# delay_time="600",
|
||||
# hold_m_name="烧杯MPDA"
|
||||
# )
|
||||
|
||||
bioyond.material_id_query("3a19310d-16b9-9d81-b109-0748e953694b")
|
||||
bioyond.material_id_query("3a15d4a1-3bbe-76f9-a458-292896a338f5")
|
||||
|
||||
|
||||
#示例4:创建90%10%小瓶投料任务
|
||||
# vial_result = bioyond.create_90_10_vial_feeding_task(
|
||||
# order_code="task_vial_" + str(int(datetime.now().timestamp())),
|
||||
# order_name="90%10%小瓶投料-1",
|
||||
# percent_90_1_assign_material_name="BTDA-1",
|
||||
# percent_90_1_target_weigh="7.392",
|
||||
# percent_90_2_assign_material_name="BTDA-1",
|
||||
# percent_90_2_target_weigh="7.392",
|
||||
# percent_90_3_assign_material_name="BTDA-2",
|
||||
# percent_90_3_target_weigh="7.392",
|
||||
# percent_10_1_assign_material_name="BTDA-2",
|
||||
# percent_10_1_target_weigh="1.500",
|
||||
# percent_10_1_volume="20",
|
||||
# percent_10_1_liquid_material_name="NMP",
|
||||
# # percent_10_2_assign_material_name="BTDA-c",
|
||||
# # percent_10_2_target_weigh="1.2",
|
||||
# # percent_10_2_volume="20",
|
||||
# # percent_10_2_liquid_material_name="NMP",
|
||||
# speed="400",
|
||||
# temperature="60",
|
||||
# delay_time="1200",
|
||||
# hold_m_name="8.4分装板-1"
|
||||
# )
|
||||
|
||||
# vial_result = bioyond.create_90_10_vial_feeding_task(
|
||||
# order_code="task_vial_" + str(int(datetime.now().timestamp())),
|
||||
# order_name="90%10%小瓶投料-2",
|
||||
# percent_90_1_assign_material_name="BPDA-1",
|
||||
# percent_90_1_target_weigh="5.006",
|
||||
# percent_90_2_assign_material_name="PMDA-1",
|
||||
# percent_90_2_target_weigh="3.810",
|
||||
# percent_90_3_assign_material_name="BPDA-1",
|
||||
# percent_90_3_target_weigh="8.399",
|
||||
# percent_10_1_assign_material_name="BPDA-1",
|
||||
# percent_10_1_target_weigh="1.200",
|
||||
# percent_10_1_volume="20",
|
||||
# percent_10_1_liquid_material_name="NMP",
|
||||
# percent_10_2_assign_material_name="BPDA-1",
|
||||
# percent_10_2_target_weigh="1.200",
|
||||
# percent_10_2_volume="20",
|
||||
# percent_10_2_liquid_material_name="NMP",
|
||||
# speed="400",
|
||||
# temperature="60",
|
||||
# delay_time="1200",
|
||||
# hold_m_name="8.4分装板-2"
|
||||
# )
|
||||
|
||||
#启动调度器
|
||||
#bioyond.scheduler_start()
|
||||
|
||||
#继续调度器
|
||||
#bioyond.scheduler_continue()
|
||||
|
||||
result0 = bioyond.stock_material('{"typeMode": 0, "includeDetail": true}')
|
||||
result1 = bioyond.stock_material('{"typeMode": 1, "includeDetail": true}')
|
||||
result2 = bioyond.stock_material('{"typeMode": 2, "includeDetail": true}')
|
||||
|
||||
matpos1 = bioyond.query_warehouse_by_material_type("3a14196e-b7a0-a5da-1931-35f3000281e9")
|
||||
matpos2 = bioyond.query_warehouse_by_material_type("3a14196e-5dfe-6e21-0c79-fe2036d052c4")
|
||||
matpos3 = bioyond.query_warehouse_by_material_type("3a14196b-24f2-ca49-9081-0cab8021bf1a")
|
||||
|
||||
#样品板(里面有样品瓶)
|
||||
material_data_yp = {
|
||||
"typeId": "3a14196e-b7a0-a5da-1931-35f3000281e9",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "8.4样品板",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"details": [
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "BTDA-1",
|
||||
"quantity": 20,
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "BPDA-1",
|
||||
"quantity": 20,
|
||||
"x": 2,
|
||||
"y": 1, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "BTDA-2",
|
||||
"quantity": 20,
|
||||
"x": 1,
|
||||
"y": 2, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "PMDA-1",
|
||||
"quantity": 20,
|
||||
"x": 2,
|
||||
"y": 2, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
}
|
||||
],
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
material_data_yp = {
|
||||
"typeId": "3a14196e-b7a0-a5da-1931-35f3000281e9",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "8.7样品板",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"details": [
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "mianfen",
|
||||
"quantity": 13,
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196a-cf7d-8aea-48d8-b9662c7dba94",
|
||||
#"code": "物料编码001",
|
||||
"name": "mianfen2",
|
||||
"quantity": 13,
|
||||
"x": 1,
|
||||
"y": 2, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
}
|
||||
],
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
#分装板
|
||||
material_data_fzb_1 = {
|
||||
"typeId": "3a14196e-5dfe-6e21-0c79-fe2036d052c4",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "8.7分装板",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"details": [
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶1",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶2",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶3",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶1",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 1, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶2",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶3",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
}
|
||||
],
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
material_data_fzb_2 = {
|
||||
"typeId": "3a14196e-5dfe-6e21-0c79-fe2036d052c4",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "8.4分装板-2",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"details": [
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶1",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶2",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-76be-2279-4e22-7310d69aed68",
|
||||
#"code": "物料编码001",
|
||||
"name": "10%小瓶3",
|
||||
"quantity": 1,
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶1",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 1, #x1y2是A02
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶2",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
#"unit": "单位"
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
},
|
||||
{
|
||||
"typeId": "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea",
|
||||
#"code": "物料编码001",
|
||||
"name": "90%小瓶3",
|
||||
"quantity": 1,
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"molecular": 1,
|
||||
"Parameters":"{\"molecular\": 1}"
|
||||
}
|
||||
],
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
#烧杯
|
||||
material_data_sb_oda = {
|
||||
"typeId": "3a14196b-24f2-ca49-9081-0cab8021bf1a",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "mianfen1",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
material_data_sb_pda_2 = {
|
||||
"typeId": "3a14196b-24f2-ca49-9081-0cab8021bf1a",
|
||||
#"code": "物料编码001",
|
||||
#"barCode": "物料条码001",
|
||||
"name": "mianfen2",
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"Parameters":"{}"
|
||||
}
|
||||
|
||||
# material_data_sb_mpda = {
|
||||
# "typeId": "3a14196b-24f2-ca49-9081-0cab8021bf1a",
|
||||
# #"code": "物料编码001",
|
||||
# #"barCode": "物料条码001",
|
||||
# "name": "烧杯MPDA",
|
||||
# "unit": "个",
|
||||
# "quantity": 1,
|
||||
# "Parameters":"{}"
|
||||
# }
|
||||
|
||||
|
||||
#result_1 = bioyond.add_material(json.dumps(material_data_yp, ensure_ascii=False))
|
||||
#result_2 = bioyond.add_material(json.dumps(material_data_fzb_1, ensure_ascii=False))
|
||||
# result_3 = bioyond.add_material(json.dumps(material_data_fzb_2, ensure_ascii=False))
|
||||
# result_4 = bioyond.add_material(json.dumps(material_data_sb_oda, ensure_ascii=False))
|
||||
# result_5 = bioyond.add_material(json.dumps(material_data_sb_pda_2, ensure_ascii=False))
|
||||
# #result会返回id
|
||||
# #样品板1id:3a1b3e7d-339d-0291-dfd3-13e2a78fe521
|
||||
|
||||
|
||||
# #将指定物料入库到指定库位
|
||||
#bioyond.material_inbound(result_1, "3a14198e-6929-31f0-8a22-0f98f72260df")
|
||||
#bioyond.material_inbound(result_2, "3a14198e-6929-46fe-841e-03dd753f1e4a")
|
||||
# bioyond.material_inbound(result_3, "3a14198e-6929-72ac-32ce-9b50245682b8")
|
||||
# bioyond.material_inbound(result_4, "3a14198e-d724-e036-afdc-2ae39a7f3383")
|
||||
# bioyond.material_inbound(result_5, "3a14198e-d724-d818-6d4f-5725191a24b5")
|
||||
|
||||
#bioyond.material_outbound(result_1, "3a14198e-6929-31f0-8a22-0f98f72260df")
|
||||
|
||||
# bioyond.stock_material('{"typeMode": 2, "includeDetail": true}')
|
||||
|
||||
query_order = {"status":"100", "pageCount": "10"}
|
||||
bioyond.order_query(json.dumps(query_order, ensure_ascii=False))
|
||||
|
||||
# id = "3a1bce3c-4f31-c8f3-5525-f3b273bc34dc"
|
||||
# bioyond.sample_waste_removal(id)
|
||||
|
||||
207
unilabos/devices/workstation/bioyond_studio/reaction_station.py
Normal file
207
unilabos/devices/workstation/bioyond_studio/reaction_station.py
Normal file
@@ -0,0 +1,207 @@
|
||||
import json
|
||||
|
||||
from unilabos.devices.workstation.bioyond_studio.station import BioyondWorkstation
|
||||
from unilabos.devices.workstation.bioyond_studio.config import (
|
||||
API_CONFIG, WORKFLOW_MAPPINGS, WORKFLOW_STEP_IDS, MATERIAL_TYPE_MAPPINGS,
|
||||
STATION_TYPES, DEFAULT_STATION_CONFIG
|
||||
)
|
||||
|
||||
|
||||
class BioyondReactionStation(BioyondWorkstation):
|
||||
def __init__(self, config: dict = None):
|
||||
super().__init__(config)
|
||||
|
||||
# 工作流方法
|
||||
def reactor_taken_out(self):
|
||||
"""反应器取出"""
|
||||
self.hardware_interface.append_to_workflow_sequence('{"web_workflow_name": "reactor_taken_out"}')
|
||||
reactor_taken_out_params = {"param_values": {}}
|
||||
self.hardware_interface.pending_task_params.append(reactor_taken_out_params)
|
||||
print(f"成功添加反应器取出工作流")
|
||||
print(f"当前队列长度: {len(self.hardware_interface.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def reactor_taken_in(self, assign_material_name: str, cutoff: str = "900000", temperature: float = -10.00):
|
||||
"""反应器放入"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "reactor_taken_in"}')
|
||||
material_id = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
step_id = WORKFLOW_STEP_IDS["reactor_taken_in"]["config"]
|
||||
reactor_taken_in_params = {
|
||||
"param_values": {
|
||||
step_id: [
|
||||
{"m": 0, "n": 3, "Key": "cutoff", "Value": cutoff},
|
||||
{"m": 0, "n": 3, "Key": "temperature", "Value": f"{temperature:.2f}"},
|
||||
{"m": 0, "n": 3, "Key": "assignMaterialName", "Value": material_id}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(reactor_taken_in_params)
|
||||
print(f"成功添加反应器放入参数: material={assign_material_name}->ID:{material_id}, cutoff={cutoff}, temp={temperature:.2f}")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def solid_feeding_vials(self, material_id: str, time: str = "0", torque_variation: str = "1",
|
||||
assign_material_name: str = None, temperature: float = 25.00):
|
||||
"""固体进料小瓶"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "Solid_feeding_vials"}')
|
||||
material_id_m = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
feeding_id = WORKFLOW_STEP_IDS["solid_feeding_vials"]["feeding"]
|
||||
observe_id = WORKFLOW_STEP_IDS["solid_feeding_vials"]["observe"]
|
||||
|
||||
solid_feeding_vials_params = {
|
||||
"param_values": {
|
||||
feeding_id: [
|
||||
{"m": 0, "n": 3, "Key": "materialId", "Value": material_id},
|
||||
{"m": 0, "n": 3, "Key": "assignMaterialName", "Value": material_id_m}
|
||||
],
|
||||
observe_id: [
|
||||
{"m": 1, "n": 0, "Key": "time", "Value": time},
|
||||
{"m": 1, "n": 0, "Key": "torqueVariation", "Value": torque_variation},
|
||||
{"m": 1, "n": 0, "Key": "temperature", "Value": f"{temperature:.2f}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(solid_feeding_vials_params)
|
||||
print(f"成功添加固体进料小瓶参数: material_id={material_id}, time={time}min, temp={temperature:.2f}°C")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def liquid_feeding_vials_non_titration(self, volumeFormula: str, assign_material_name: str,
|
||||
titration_type: str = "1", time: str = "0",
|
||||
torque_variation: str = "1", temperature: float = 25.00):
|
||||
"""液体进料小瓶(非滴定)"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "Liquid_feeding_vials(non-titration)"}')
|
||||
material_id = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
liquid_id = WORKFLOW_STEP_IDS["liquid_feeding_vials_non_titration"]["liquid"]
|
||||
observe_id = WORKFLOW_STEP_IDS["liquid_feeding_vials_non_titration"]["observe"]
|
||||
|
||||
params = {
|
||||
"param_values": {
|
||||
liquid_id: [
|
||||
{"m": 0, "n": 3, "Key": "volumeFormula", "Value": volumeFormula},
|
||||
{"m": 0, "n": 3, "Key": "assignMaterialName", "Value": material_id},
|
||||
{"m": 0, "n": 3, "Key": "titrationType", "Value": titration_type}
|
||||
],
|
||||
observe_id: [
|
||||
{"m": 1, "n": 0, "Key": "time", "Value": time},
|
||||
{"m": 1, "n": 0, "Key": "torqueVariation", "Value": torque_variation},
|
||||
{"m": 1, "n": 0, "Key": "temperature", "Value": f"{temperature:.2f}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(params)
|
||||
print(f"成功添加液体进料小瓶(非滴定)参数: volume={volumeFormula}μL, material={assign_material_name}->ID:{material_id}")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def liquid_feeding_solvents(self, assign_material_name: str, volume: str, titration_type: str = "1",
|
||||
time: str = "360", torque_variation: str = "2", temperature: float = 25.00):
|
||||
"""液体进料溶剂"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "Liquid_feeding_solvents"}')
|
||||
material_id = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
liquid_id = WORKFLOW_STEP_IDS["liquid_feeding_solvents"]["liquid"]
|
||||
observe_id = WORKFLOW_STEP_IDS["liquid_feeding_solvents"]["observe"]
|
||||
|
||||
params = {
|
||||
"param_values": {
|
||||
liquid_id: [
|
||||
{"m": 0, "n": 1, "Key": "titrationType", "Value": titration_type},
|
||||
{"m": 0, "n": 1, "Key": "volume", "Value": volume},
|
||||
{"m": 0, "n": 1, "Key": "assignMaterialName", "Value": material_id}
|
||||
],
|
||||
observe_id: [
|
||||
{"m": 1, "n": 0, "Key": "time", "Value": time},
|
||||
{"m": 1, "n": 0, "Key": "torqueVariation", "Value": torque_variation},
|
||||
{"m": 1, "n": 0, "Key": "temperature", "Value": f"{temperature:.2f}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(params)
|
||||
print(f"成功添加液体进料溶剂参数: material={assign_material_name}->ID:{material_id}, volume={volume}μL")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def liquid_feeding_titration(self, volume_formula: str, assign_material_name: str, titration_type: str = "1",
|
||||
time: str = "90", torque_variation: int = 2, temperature: float = 25.00):
|
||||
"""液体进料(滴定)"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "Liquid_feeding(titration)"}')
|
||||
material_id = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
liquid_id = WORKFLOW_STEP_IDS["liquid_feeding_titration"]["liquid"]
|
||||
observe_id = WORKFLOW_STEP_IDS["liquid_feeding_titration"]["observe"]
|
||||
|
||||
params = {
|
||||
"param_values": {
|
||||
liquid_id: [
|
||||
{"m": 0, "n": 3, "Key": "volumeFormula", "Value": volume_formula},
|
||||
{"m": 0, "n": 3, "Key": "titrationType", "Value": titration_type},
|
||||
{"m": 0, "n": 3, "Key": "assignMaterialName", "Value": material_id}
|
||||
],
|
||||
observe_id: [
|
||||
{"m": 1, "n": 0, "Key": "time", "Value": time},
|
||||
{"m": 1, "n": 0, "Key": "torqueVariation", "Value": str(torque_variation)},
|
||||
{"m": 1, "n": 0, "Key": "temperature", "Value": f"{temperature:.2f}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(params)
|
||||
print(f"成功添加液体进料滴定参数: volume={volume_formula}μL, material={assign_material_name}->ID:{material_id}")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
|
||||
def liquid_feeding_beaker(self, volume: str = "35000", assign_material_name: str = "BAPP",
|
||||
time: str = "0", torque_variation: str = "1", titrationType: str = "1",
|
||||
temperature: float = 25.00):
|
||||
"""液体进料烧杯"""
|
||||
self.append_to_workflow_sequence('{"web_workflow_name": "liquid_feeding_beaker"}')
|
||||
material_id = self._get_material_id_by_name(assign_material_name)
|
||||
|
||||
if isinstance(temperature, str):
|
||||
temperature = float(temperature)
|
||||
|
||||
liquid_id = WORKFLOW_STEP_IDS["liquid_feeding_beaker"]["liquid"]
|
||||
observe_id = WORKFLOW_STEP_IDS["liquid_feeding_beaker"]["observe"]
|
||||
|
||||
params = {
|
||||
"param_values": {
|
||||
liquid_id: [
|
||||
{"m": 0, "n": 2, "Key": "volume", "Value": volume},
|
||||
{"m": 0, "n": 2, "Key": "assignMaterialName", "Value": material_id},
|
||||
{"m": 0, "n": 2, "Key": "titrationType", "Value": titrationType}
|
||||
],
|
||||
observe_id: [
|
||||
{"m": 1, "n": 0, "Key": "time", "Value": time},
|
||||
{"m": 1, "n": 0, "Key": "torqueVariation", "Value": torque_variation},
|
||||
{"m": 1, "n": 0, "Key": "temperature", "Value": f"{temperature:.2f}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.pending_task_params.append(params)
|
||||
print(f"成功添加液体进料烧杯参数: volume={volume}μL, material={assign_material_name}->ID:{material_id}")
|
||||
print(f"当前队列长度: {len(self.pending_task_params)}")
|
||||
return json.dumps({"suc": True})
|
||||
File diff suppressed because it is too large
Load Diff
252
unilabos/registry/devices/bioyond.yaml
Normal file
252
unilabos/registry/devices/bioyond.yaml
Normal file
@@ -0,0 +1,252 @@
|
||||
workstation.bioyond_dispensing_station:
|
||||
category:
|
||||
- workstation
|
||||
- bioyond
|
||||
class:
|
||||
action_value_mappings:
|
||||
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
|
||||
required:
|
||||
- config
|
||||
type: object
|
||||
data:
|
||||
properties: {}
|
||||
required: []
|
||||
type: object
|
||||
version: 1.0.0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1361,8 +1361,7 @@ laiyu_liquid:
|
||||
mix_liquid_height: 0.0
|
||||
mix_rate: 0
|
||||
mix_stage: ''
|
||||
mix_times:
|
||||
- 0
|
||||
mix_times: 0
|
||||
mix_vol: 0
|
||||
none_keys:
|
||||
- ''
|
||||
@@ -1492,11 +1491,9 @@ laiyu_liquid:
|
||||
mix_stage:
|
||||
type: string
|
||||
mix_times:
|
||||
items:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
type: array
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
mix_vol:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
|
||||
@@ -3994,8 +3994,7 @@ liquid_handler:
|
||||
mix_liquid_height: 0.0
|
||||
mix_rate: 0
|
||||
mix_stage: ''
|
||||
mix_times:
|
||||
- 0
|
||||
mix_times: 0
|
||||
mix_vol: 0
|
||||
none_keys:
|
||||
- ''
|
||||
@@ -4151,11 +4150,9 @@ liquid_handler:
|
||||
mix_stage:
|
||||
type: string
|
||||
mix_times:
|
||||
items:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
type: array
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
mix_vol:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
@@ -5015,8 +5012,7 @@ liquid_handler.biomek:
|
||||
mix_liquid_height: 0.0
|
||||
mix_rate: 0
|
||||
mix_stage: ''
|
||||
mix_times:
|
||||
- 0
|
||||
mix_times: 0
|
||||
mix_vol: 0
|
||||
none_keys:
|
||||
- ''
|
||||
@@ -5159,11 +5155,9 @@ liquid_handler.biomek:
|
||||
mix_stage:
|
||||
type: string
|
||||
mix_times:
|
||||
items:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
type: array
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
mix_vol:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
@@ -7807,8 +7801,7 @@ liquid_handler.prcxi:
|
||||
mix_liquid_height: 0.0
|
||||
mix_rate: 0
|
||||
mix_stage: ''
|
||||
mix_times:
|
||||
- 0
|
||||
mix_times: 0
|
||||
mix_vol: 0
|
||||
none_keys:
|
||||
- ''
|
||||
@@ -7937,11 +7930,9 @@ liquid_handler.prcxi:
|
||||
mix_stage:
|
||||
type: string
|
||||
mix_times:
|
||||
items:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
type: array
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
type: integer
|
||||
mix_vol:
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
|
||||
@@ -4,11 +4,11 @@ reaction_station.bioyond:
|
||||
- reaction_station_bioyond
|
||||
class:
|
||||
action_value_mappings:
|
||||
auto-add_material:
|
||||
auto-append_to_workflow_sequence:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_data: null
|
||||
web_workflow_name: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
@@ -18,22 +18,21 @@ reaction_station.bioyond:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_data:
|
||||
type: object
|
||||
web_workflow_name:
|
||||
type: string
|
||||
required:
|
||||
- material_data
|
||||
- web_workflow_name
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: add_material参数
|
||||
title: append_to_workflow_sequence参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_90_10_vial_feeding_task:
|
||||
auto-clear_workflows:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
task_data: null
|
||||
goal_default: {}
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
@@ -42,470 +41,13 @@ reaction_station.bioyond:
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
task_data:
|
||||
type: string
|
||||
required:
|
||||
- task_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_90_10_vial_feeding_task参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_batch_90_10_vial_feeding_task:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
batch_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
batch_data:
|
||||
type: string
|
||||
required:
|
||||
- batch_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_batch_90_10_vial_feeding_task参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_batch_diamine_solution_task:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
batch_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
batch_data:
|
||||
type: string
|
||||
required:
|
||||
- batch_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_batch_diamine_solution_task参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_diamine_solution_task:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
solution_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
solution_data:
|
||||
type: string
|
||||
required:
|
||||
- solution_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_diamine_solution_task参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_order:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
parameters: null
|
||||
task_name: null
|
||||
workflow_name: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
parameters:
|
||||
type: object
|
||||
task_name:
|
||||
type: string
|
||||
workflow_name:
|
||||
type: string
|
||||
required:
|
||||
- workflow_name
|
||||
- task_name
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_order参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-create_resource:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
resource_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
resource_data:
|
||||
type: string
|
||||
required:
|
||||
- resource_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: create_resource参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-delete_material:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_data:
|
||||
type: string
|
||||
required:
|
||||
- material_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: delete_material参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-device_operation:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
device_id: null
|
||||
operation: null
|
||||
parameters: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
device_id:
|
||||
type: string
|
||||
operation:
|
||||
type: string
|
||||
parameters:
|
||||
type: object
|
||||
required:
|
||||
- device_id
|
||||
- operation
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: device_operation参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-dispensing_material_inbound:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_data:
|
||||
type: string
|
||||
required:
|
||||
- material_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: dispensing_material_inbound参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-dispensing_material_outbound:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_data:
|
||||
type: string
|
||||
required:
|
||||
- material_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: dispensing_material_outbound参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-drip_back:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
assign_material_name: Reactor
|
||||
temperature: 25.0
|
||||
time: '0'
|
||||
torque_variation: '1'
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
assign_material_name:
|
||||
default: Reactor
|
||||
type: string
|
||||
temperature:
|
||||
default: 25.0
|
||||
type: number
|
||||
time:
|
||||
default: '0'
|
||||
type: string
|
||||
torque_variation:
|
||||
default: '1'
|
||||
type: string
|
||||
properties: {}
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: drip_back参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-execute_bioyond_sync_workflow:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
parameters: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
parameters:
|
||||
type: object
|
||||
required:
|
||||
- parameters
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: execute_bioyond_sync_workflow参数
|
||||
type: object
|
||||
type: UniLabJsonCommandAsync
|
||||
auto-execute_bioyond_update_workflow:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
parameters: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
parameters:
|
||||
type: object
|
||||
required:
|
||||
- parameters
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: execute_bioyond_update_workflow参数
|
||||
type: object
|
||||
type: UniLabJsonCommandAsync
|
||||
auto-liquid_feeding_beaker:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_name: ''
|
||||
volume: ''
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_name:
|
||||
default: ''
|
||||
type: string
|
||||
volume:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: liquid_feeding_beaker参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-liquid_feeding_solvents:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_name: ''
|
||||
volume: ''
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_name:
|
||||
default: ''
|
||||
type: string
|
||||
volume:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: liquid_feeding_solvents参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-liquid_feeding_titration:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_name: ''
|
||||
time: '120'
|
||||
titration_type: '1'
|
||||
torque_variation: '2'
|
||||
volume: ''
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_name:
|
||||
default: ''
|
||||
type: string
|
||||
time:
|
||||
default: '120'
|
||||
type: string
|
||||
titration_type:
|
||||
default: '1'
|
||||
type: string
|
||||
torque_variation:
|
||||
default: '2'
|
||||
type: string
|
||||
volume:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: liquid_feeding_titration参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-liquid_feeding_vials_non_titration:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_name: ''
|
||||
volume: ''
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_name:
|
||||
default: ''
|
||||
type: string
|
||||
volume:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: liquid_feeding_vials_non_titration参数
|
||||
title: clear_workflows参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-load_bioyond_data_from_file:
|
||||
@@ -533,74 +75,11 @@ reaction_station.bioyond:
|
||||
title: load_bioyond_data_from_file参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-material_inbound:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
location_name: null
|
||||
material_id: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
location_name:
|
||||
type: string
|
||||
material_id:
|
||||
type: string
|
||||
required:
|
||||
- material_id
|
||||
- location_name
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: material_inbound参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-material_outbound:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
location_name: null
|
||||
material_id: null
|
||||
quantity: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
location_name:
|
||||
type: string
|
||||
material_id:
|
||||
type: string
|
||||
quantity:
|
||||
type: integer
|
||||
required:
|
||||
- material_id
|
||||
- location_name
|
||||
- quantity
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: material_outbound参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-merge_workflow_with_parameters:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
name: null
|
||||
workflows: null
|
||||
json_str: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
@@ -610,15 +89,10 @@ reaction_station.bioyond:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
name:
|
||||
json_str:
|
||||
type: string
|
||||
workflows:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
- workflows
|
||||
- json_str
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
@@ -626,31 +100,6 @@ reaction_station.bioyond:
|
||||
title: merge_workflow_with_parameters参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-order_query:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
query_data: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
query_data:
|
||||
type: string
|
||||
required:
|
||||
- query_data
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: order_query参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-post_init:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
@@ -676,33 +125,11 @@ reaction_station.bioyond:
|
||||
title: post_init参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-reactor_taken_in:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default: {}
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties: {}
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: reactor_taken_in参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-reactor_taken_out:
|
||||
auto-process_web_workflows:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
order_id: ''
|
||||
preintake_id: ''
|
||||
json_str: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
@@ -712,18 +139,15 @@ reaction_station.bioyond:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
order_id:
|
||||
default: ''
|
||||
json_str:
|
||||
type: string
|
||||
preintake_id:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
required:
|
||||
- json_str
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: reactor_taken_out参数
|
||||
title: process_web_workflows参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-reset_workstation:
|
||||
@@ -747,11 +171,11 @@ reaction_station.bioyond:
|
||||
title: reset_workstation参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-sample_waste_removal:
|
||||
auto-resource_tree_add:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
waste_data: null
|
||||
resources: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
@@ -761,119 +185,42 @@ reaction_station.bioyond:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
waste_data:
|
||||
resources:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- resources
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: resource_tree_add参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-set_workflow_sequence:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
json_str: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
json_str:
|
||||
type: string
|
||||
required:
|
||||
- waste_data
|
||||
- json_str
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: sample_waste_removal参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-solid_feeding_vials:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
material_name: ''
|
||||
volume: ''
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
material_name:
|
||||
default: ''
|
||||
type: string
|
||||
volume:
|
||||
default: ''
|
||||
type: string
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: solid_feeding_vials参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-start_scheduler:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default: {}
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties: {}
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: start_scheduler参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-stock_material:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
location: null
|
||||
material_id: null
|
||||
quantity: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
location:
|
||||
type: string
|
||||
material_id:
|
||||
type: string
|
||||
quantity:
|
||||
type: integer
|
||||
required:
|
||||
- material_id
|
||||
- location
|
||||
- quantity
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: stock_material参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-stop_scheduler:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default: {}
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties: {}
|
||||
required: []
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: stop_scheduler参数
|
||||
title: set_workflow_sequence参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-transfer_resource_to_another:
|
||||
@@ -1064,33 +411,6 @@ reaction_station.bioyond:
|
||||
title: transfer_resource_to_another参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
auto-validate_workflow_parameters:
|
||||
feedback: {}
|
||||
goal: {}
|
||||
goal_default:
|
||||
workflows: null
|
||||
handles: {}
|
||||
placeholder_keys: {}
|
||||
result: {}
|
||||
schema:
|
||||
description: ''
|
||||
properties:
|
||||
feedback: {}
|
||||
goal:
|
||||
properties:
|
||||
workflows:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- workflows
|
||||
type: object
|
||||
result: {}
|
||||
required:
|
||||
- goal
|
||||
title: validate_workflow_parameters参数
|
||||
type: object
|
||||
type: UniLabJsonCommand
|
||||
bioyond_sync:
|
||||
feedback: {}
|
||||
goal:
|
||||
@@ -1407,11 +727,8 @@ reaction_station.bioyond:
|
||||
module: unilabos.devices.workstation.bioyond_studio.station:BioyondWorkstation
|
||||
protocol_type: []
|
||||
status_types:
|
||||
all_workflows: dict
|
||||
bioyond_status: dict
|
||||
device_list: dict
|
||||
scheduler_status: dict
|
||||
station_info: dict
|
||||
workflow_parameter_template: dict
|
||||
workstation_status: dict
|
||||
type: python
|
||||
config_info: []
|
||||
@@ -1431,24 +748,15 @@ reaction_station.bioyond:
|
||||
type: object
|
||||
data:
|
||||
properties:
|
||||
all_workflows:
|
||||
type: object
|
||||
bioyond_status:
|
||||
type: object
|
||||
device_list:
|
||||
type: object
|
||||
scheduler_status:
|
||||
type: object
|
||||
station_info:
|
||||
type: object
|
||||
workflow_parameter_template:
|
||||
type: object
|
||||
workstation_status:
|
||||
type: object
|
||||
required:
|
||||
- station_info
|
||||
- bioyond_status
|
||||
- workflow_parameter_template
|
||||
- scheduler_status
|
||||
- device_list
|
||||
- all_workflows
|
||||
- workstation_status
|
||||
type: object
|
||||
version: 1.0.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,16 @@
|
||||
import importlib
|
||||
import inspect
|
||||
import json
|
||||
import os.path
|
||||
import traceback
|
||||
from typing import Union, Any, Dict, List
|
||||
from typing import Union, Any, Dict, List, Tuple
|
||||
import networkx as nx
|
||||
from pylabrobot.resources import ResourceHolder
|
||||
from unilabos_msgs.msg import Resource
|
||||
|
||||
from unilabos.config.config import BasicConfig
|
||||
from unilabos.resources.container import RegularContainer
|
||||
from unilabos.resources.itemized_carrier import ItemizedCarrier
|
||||
from unilabos.ros.msgs.message_converter import convert_to_ros_msg
|
||||
from unilabos.ros.nodes.resource_tracker import (
|
||||
ResourceDictInstance,
|
||||
@@ -44,6 +47,29 @@ def canonicalize_nodes_data(
|
||||
if node.get("label") is not None:
|
||||
node_id = node.pop("label")
|
||||
node["id"] = node["name"] = node_id
|
||||
if not isinstance(node.get("config"), dict):
|
||||
node["config"] = {}
|
||||
if not node.get("type"):
|
||||
node["type"] = "device"
|
||||
print_status(f"Warning: Node {node.get('id', 'unknown')} missing 'type', defaulting to 'device'", "warning")
|
||||
if not node.get("name"):
|
||||
node["name"] = node.get("id")
|
||||
print_status(f"Warning: Node {node.get('id', 'unknown')} missing 'name', defaulting to {node['name']}", "warning")
|
||||
if not isinstance(node.get("position"), dict):
|
||||
node["position"] = {"position": {}}
|
||||
x = node.pop("x", None)
|
||||
if x is not None:
|
||||
node["position"]["position"]["x"] = x
|
||||
y = node.pop("y", None)
|
||||
if y is not None:
|
||||
node["position"]["position"]["y"] = y
|
||||
z = node.pop("z", None)
|
||||
if z is not None:
|
||||
node["position"]["position"]["z"] = z
|
||||
for k in list(node.keys()):
|
||||
if k not in ["id", "uuid", "name", "description", "schema", "model", "icon", "parent_uuid", "parent", "type", "class", "position", "config", "data"]:
|
||||
v = node.pop(k)
|
||||
node["config"][k] = v
|
||||
|
||||
# 第二步:处理parent_relation
|
||||
id2idx = {node["id"]: idx for idx, node in enumerate(nodes)}
|
||||
@@ -301,6 +327,10 @@ def read_graphml(graphml_file: str) -> tuple[nx.Graph, ResourceTreeSet, List[Dic
|
||||
"nodes": [node.res_content.model_dump(by_alias=True) for node in resource_tree_set.all_nodes],
|
||||
"links": standardized_links,
|
||||
}
|
||||
dump_json_path = os.path.join(BasicConfig.working_dir, os.path.basename(graphml_file).rsplit(".")[0] + ".json")
|
||||
with open(dump_json_path, "w", encoding="utf-8") as f:
|
||||
f.write(json.dumps(graph_data, indent=4, ensure_ascii=False))
|
||||
print_status(f"GraphML converted to JSON and saved to {dump_json_path}", "info")
|
||||
physical_setup_graph = nx.node_link_graph(graph_data, link="links", multigraph=False)
|
||||
handle_communications(physical_setup_graph)
|
||||
|
||||
@@ -576,13 +606,13 @@ def resource_plr_to_ulab(resource_plr: "ResourcePLR", parent_name: str = None, w
|
||||
return r
|
||||
|
||||
|
||||
def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: dict = {}, deck: Any = None) -> list[dict]:
|
||||
def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[str, Tuple[str, str]] = {}, deck: Any = None) -> list[dict]:
|
||||
"""
|
||||
将 bioyond 物料格式转换为 ulab 物料格式
|
||||
|
||||
Args:
|
||||
bioyond_materials: bioyond 系统的物料查询结果列表
|
||||
type_mapping: 物料类型映射字典,格式 {bioyond_type: plr_class_name}
|
||||
type_mapping: 物料类型映射字典,格式 {bioyond_type: [plr_class_name, class_uuid]}
|
||||
location_id_mapping: 库位 ID 到名称的映射字典,格式 {location_id: location_name}
|
||||
|
||||
Returns:
|
||||
@@ -592,7 +622,7 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: dict =
|
||||
|
||||
for material in bioyond_materials:
|
||||
className = (
|
||||
type_mapping.get(material.get("typeName"), "RegularContainer") if type_mapping else "RegularContainer"
|
||||
type_mapping.get(material.get("typeName"), ("RegularContainer", ""))[0] if type_mapping else "RegularContainer"
|
||||
)
|
||||
|
||||
plr_material: ResourcePLR = initialize_resource(
|
||||
@@ -614,7 +644,7 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: dict =
|
||||
# plr_material.unassign_child_resource(bottle)
|
||||
plr_material.sites[number] = None
|
||||
plr_material[number] = initialize_resource(
|
||||
{"name": f'{detail["name"]}_{number}', "class": type_mapping[detail["name"]]}, resource_type=ResourcePLR
|
||||
{"name": f'{detail["name"]}_{number}', "class": type_mapping[detail["name"]][0]}, resource_type=ResourcePLR
|
||||
)
|
||||
else:
|
||||
bottle.tracker.liquids = [
|
||||
@@ -645,32 +675,59 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: dict =
|
||||
return plr_materials
|
||||
|
||||
|
||||
def resource_plr_to_bioyond(plr_materials: list[ResourcePLR], type_mapping: dict = {}, warehouse_mapping: dict = {}) -> list[dict]:
|
||||
def resource_plr_to_bioyond(plr_resources: list[ResourcePLR], type_mapping: dict = {}, warehouse_mapping: dict = {}) -> list[dict]:
|
||||
bioyond_materials = []
|
||||
for plr_material in plr_materials:
|
||||
material = {
|
||||
"name": plr_material.name,
|
||||
"typeName": plr_material.__class__.__name__,
|
||||
"code": plr_material.code,
|
||||
"quantity": 0,
|
||||
"detail": [],
|
||||
"locations": [],
|
||||
}
|
||||
if hasattr(plr_material, "capacity") and plr_material.capacity > 1:
|
||||
for idx in range(plr_material.capacity):
|
||||
bottle = plr_material[idx]
|
||||
detail = {
|
||||
"x": (idx // (plr_material.num_items_x * plr_material.num_items_y)) + 1,
|
||||
"y": ((idx % (plr_material.num_items_x * plr_material.num_items_y)) // plr_material.num_items_x) + 1,
|
||||
"z": (idx % plr_material.num_items_x) + 1,
|
||||
for resource in plr_resources:
|
||||
if hasattr(resource, "capacity") and resource.capacity > 1:
|
||||
material = {
|
||||
"typeId": type_mapping.get(resource.model)[1],
|
||||
"name": resource.name,
|
||||
"unit": "个",
|
||||
"quantity": 1,
|
||||
"details": [],
|
||||
"Parameters": "{}"
|
||||
}
|
||||
for bottle in resource.children:
|
||||
if isinstance(resource, ItemizedCarrier):
|
||||
site = resource.get_child_identifier(bottle)
|
||||
else:
|
||||
site = {"x": bottle.location.x - 1, "y": bottle.location.y - 1}
|
||||
detail_item = {
|
||||
"typeId": type_mapping.get(bottle.model)[1],
|
||||
"name": bottle.name,
|
||||
"code": bottle.code if hasattr(bottle, "code") else "",
|
||||
"quantity": sum(qty for _, qty in bottle.tracker.liquids) if hasattr(bottle, "tracker") else 0,
|
||||
"x": site["x"] + 1,
|
||||
"y": site["y"] + 1,
|
||||
"molecular": 1,
|
||||
"Parameters": json.dumps({"molecular": 1})
|
||||
}
|
||||
material["detail"].append(detail)
|
||||
material["quantity"] = 1.0
|
||||
material["details"].append(detail_item)
|
||||
else:
|
||||
bottle = plr_material[0] if plr_material.capacity > 0 else plr_material
|
||||
material["quantity"] = sum(qty for _, qty in bottle.tracker.liquids) if hasattr(plr_material, "tracker") else 0
|
||||
bottle = resource[0] if resource.capacity > 0 else resource
|
||||
material = {
|
||||
"typeId": "3a14196b-24f2-ca49-9081-0cab8021bf1a",
|
||||
"name": resource.get("name", ""),
|
||||
"unit": "",
|
||||
"quantity": sum(qty for _, qty in bottle.tracker.liquids) if hasattr(bottle, "tracker") else 0,
|
||||
"Parameters": "{}"
|
||||
}
|
||||
|
||||
if resource.parent is not None and isinstance(resource.parent, ItemizedCarrier):
|
||||
site_in_parent = resource.parent.get_child_identifier(resource)
|
||||
material["locations"] = [
|
||||
{
|
||||
"id": warehouse_mapping[resource.parent.name]["site_uuids"][site_in_parent["identifier"]],
|
||||
"whid": warehouse_mapping[resource.parent.name]["uuid"],
|
||||
"whName": resource.parent.name,
|
||||
"x": site_in_parent["z"] + 1,
|
||||
"y": site_in_parent["y"] + 1,
|
||||
"z": 1,
|
||||
"quantity": 0
|
||||
}
|
||||
],
|
||||
|
||||
print(f"material_data: {material}")
|
||||
bioyond_materials.append(material)
|
||||
return bioyond_materials
|
||||
|
||||
|
||||
@@ -163,6 +163,89 @@ class ItemizedCarrier(ResourcePLR):
|
||||
if hasattr(resource, "unassign"):
|
||||
resource.unassign()
|
||||
|
||||
def get_child_identifier(self, child: ResourcePLR):
|
||||
"""Get the identifier information for a given child resource.
|
||||
|
||||
Args:
|
||||
child: The Resource object to find the identifier for
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing:
|
||||
- identifier: The string identifier (e.g. "A1", "B2")
|
||||
- idx: The integer index in the sites list
|
||||
- x: The x index (column index, 0-based)
|
||||
- y: The y index (row index, 0-based)
|
||||
- z: The z index (layer index, 0-based)
|
||||
|
||||
Raises:
|
||||
ValueError: If the child resource is not found in this carrier
|
||||
"""
|
||||
# Find the child resource in sites
|
||||
for idx, resource in enumerate(self.sites):
|
||||
if resource is child:
|
||||
# Get the identifier from ordering keys
|
||||
identifier = list(self._ordering.keys())[idx]
|
||||
|
||||
# Parse identifier to get x, y, z indices
|
||||
x_idx, y_idx, z_idx = self._parse_identifier_to_indices(identifier, idx)
|
||||
|
||||
return {
|
||||
"identifier": identifier,
|
||||
"idx": idx,
|
||||
"x": x_idx,
|
||||
"y": y_idx,
|
||||
"z": z_idx
|
||||
}
|
||||
|
||||
# If not found, raise an error
|
||||
raise ValueError(f"Resource {child} is not assigned to this carrier")
|
||||
|
||||
def _parse_identifier_to_indices(self, identifier: str, idx: int) -> Tuple[int, int, int]:
|
||||
"""Parse identifier string to get x, y, z indices.
|
||||
|
||||
Args:
|
||||
identifier: String identifier like "A1", "B2", etc.
|
||||
idx: Linear index as fallback for calculation
|
||||
|
||||
Returns:
|
||||
Tuple of (x_idx, y_idx, z_idx)
|
||||
"""
|
||||
# If we have explicit dimensions, calculate from idx
|
||||
if self.num_items_x > 0 and self.num_items_y > 0:
|
||||
# Calculate 3D indices from linear index
|
||||
z_idx = idx // (self.num_items_x * self.num_items_y) if self.num_items_z > 0 else 0
|
||||
remaining = idx % (self.num_items_x * self.num_items_y)
|
||||
y_idx = remaining // self.num_items_x
|
||||
x_idx = remaining % self.num_items_x
|
||||
return x_idx, y_idx, z_idx
|
||||
|
||||
# Fallback: parse from Excel-style identifier
|
||||
if isinstance(identifier, str) and len(identifier) >= 2:
|
||||
# Extract row (letter) and column (number)
|
||||
row_letters = ""
|
||||
col_numbers = ""
|
||||
|
||||
for char in identifier:
|
||||
if char.isalpha():
|
||||
row_letters += char
|
||||
elif char.isdigit():
|
||||
col_numbers += char
|
||||
|
||||
if row_letters and col_numbers:
|
||||
# Convert letter(s) to row index (A=0, B=1, etc.)
|
||||
y_idx = 0
|
||||
for char in row_letters:
|
||||
y_idx = y_idx * 26 + (ord(char.upper()) - ord('A'))
|
||||
|
||||
# Convert number to column index (1-based to 0-based)
|
||||
x_idx = int(col_numbers) - 1
|
||||
z_idx = 0 # Default layer
|
||||
|
||||
return x_idx, y_idx, z_idx
|
||||
|
||||
# If all else fails, assume linear arrangement
|
||||
return idx, 0, 0
|
||||
|
||||
def __getitem__(
|
||||
self,
|
||||
identifier: Union[str, int, Sequence[int], Sequence[str], slice, range],
|
||||
|
||||
Reference in New Issue
Block a user