mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 04:51:10 +00:00
Compare commits
12 Commits
fa9b2a08f2
...
workstatio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6413828c59 | ||
|
|
5072f00836 | ||
|
|
9dfbe3246e | ||
|
|
bef69db3b6 | ||
|
|
a061bc2942 | ||
|
|
8c9e11c04f | ||
|
|
e4e3ec805a | ||
|
|
d634316bce | ||
|
|
f5446c6480 | ||
|
|
a98d25c16d | ||
|
|
80b9589973 | ||
|
|
4d4bbcbae8 |
@@ -90,9 +90,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"data": {}
|
"data": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "NewareTester",
|
||||||
|
"name": "新威电池测试系统",
|
||||||
|
"parent": null,
|
||||||
|
"children": [],
|
||||||
|
"type": "device",
|
||||||
|
"class": "neware_battery_test_system",
|
||||||
|
"config": {
|
||||||
|
"ip": "127.0.0.1",
|
||||||
|
"port": 502,
|
||||||
|
"machine_id": 1,
|
||||||
|
"devtype": "27",
|
||||||
|
"timeout": 20,
|
||||||
|
"size_x": 500.0,
|
||||||
|
"size_y": 500.0,
|
||||||
|
"size_z": 2000.0
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"size": {
|
||||||
|
"height": 1600,
|
||||||
|
"width": 1200,
|
||||||
|
"depth": 800
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1500,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"功能说明": "新威电池测试系统,提供720通道监控和CSV批量提交功能",
|
||||||
|
"监控功能": "支持720个通道的实时状态监控、2盘电池物料管理、状态导出等",
|
||||||
|
"提交功能": "通过submit_from_csv action从CSV文件批量提交测试任务"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": []
|
"links": []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from cgi import print_arguments
|
from cgi import print_arguments
|
||||||
from doctest import debug
|
from doctest import debug
|
||||||
from typing import Dict, Any, List, Optional
|
from typing import Dict, Any, List, Optional, Tuple
|
||||||
import requests
|
import requests
|
||||||
from pylabrobot.resources.resource import Resource as ResourcePLR
|
from pylabrobot.resources.resource import Resource as ResourcePLR
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -19,8 +19,22 @@ from unilabos.devices.workstation.bioyond_studio.config import (
|
|||||||
)
|
)
|
||||||
from unilabos.devices.workstation.workstation_http_service import WorkstationHTTPService
|
from unilabos.devices.workstation.workstation_http_service import WorkstationHTTPService
|
||||||
from unilabos.resources.bioyond.decks import BIOYOND_YB_Deck
|
from unilabos.resources.bioyond.decks import BIOYOND_YB_Deck
|
||||||
|
from unilabos.resources.graphio import resource_bioyond_to_plr
|
||||||
from unilabos.utils.log import logger
|
from unilabos.utils.log import logger
|
||||||
from unilabos.registry.registry import lab_registry
|
from unilabos.registry.registry import lab_registry
|
||||||
|
from unilabos.ros.nodes.base_device_node import ROS2DeviceNode
|
||||||
|
|
||||||
|
|
||||||
|
class device(BIOYOND_YB_Deck):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def deserialize(cls, data, allow_marshal=False): # type: ignore[override]
|
||||||
|
patched = dict(data)
|
||||||
|
if patched.get("type") == "device":
|
||||||
|
patched["type"] = "Deck"
|
||||||
|
if patched.get("category") == "device":
|
||||||
|
patched["category"] = "deck"
|
||||||
|
return super().deserialize(patched, allow_marshal=allow_marshal)
|
||||||
|
|
||||||
def _iso_local_now_ms() -> str:
|
def _iso_local_now_ms() -> str:
|
||||||
# 文档要求:到毫秒 + Z,例如 2025-08-15T05:43:22.814Z
|
# 文档要求:到毫秒 + Z,例如 2025-08-15T05:43:22.814Z
|
||||||
@@ -40,12 +54,14 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
def __init__(self, config: dict = None, deck=None, protocol_type=None, **kwargs):
|
def __init__(self, config: dict = None, deck=None, protocol_type=None, **kwargs):
|
||||||
|
|
||||||
# 使用统一配置,支持自定义覆盖, 从 config.py 加载完整配置
|
# 使用统一配置,支持自定义覆盖, 从 config.py 加载完整配置
|
||||||
self.bioyond_config ={
|
self.bioyond_config = {
|
||||||
**API_CONFIG,
|
**API_CONFIG,
|
||||||
"material_type_mappings": MATERIAL_TYPE_MAPPINGS,
|
"material_type_mappings": MATERIAL_TYPE_MAPPINGS,
|
||||||
"warehouse_mapping": WAREHOUSE_MAPPING,
|
"warehouse_mapping": WAREHOUSE_MAPPING,
|
||||||
"debug_mode": False
|
"debug_mode": False,
|
||||||
}
|
}
|
||||||
|
if config:
|
||||||
|
self.bioyond_config.update(config)
|
||||||
|
|
||||||
# "material_type_mappings": MATERIAL_TYPE_MAPPINGS
|
# "material_type_mappings": MATERIAL_TYPE_MAPPINGS
|
||||||
# "warehouse_mapping": WAREHOUSE_MAPPING
|
# "warehouse_mapping": WAREHOUSE_MAPPING
|
||||||
@@ -56,6 +72,12 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
self.http_service_started = self.debug_mode
|
self.http_service_started = self.debug_mode
|
||||||
self._device_id = "bioyond_cell_workstation" # 默认值,后续会从_ros_node获取
|
self._device_id = "bioyond_cell_workstation" # 默认值,后续会从_ros_node获取
|
||||||
super().__init__(bioyond_config=config, deck=deck)
|
super().__init__(bioyond_config=config, deck=deck)
|
||||||
|
self.transfer_target_device_id = self.bioyond_config.get("transfer_target_device_id", "BatteryStation")
|
||||||
|
self.transfer_target_parent = self.bioyond_config.get("transfer_target_parent", "YB_YH_Deck")
|
||||||
|
self.transfer_timeout = float(self.bioyond_config.get("transfer_timeout", 180.0))
|
||||||
|
self.coin_cell_workflow_config = self.bioyond_config.get("coin_cell_workflow_config", {})
|
||||||
|
self.pending_transfer_materials: List[Dict[str, Any]] = []
|
||||||
|
self.pending_transfer_plr: List[ResourcePLR] = []
|
||||||
self.update_push_ip() #直接修改奔耀端的报送ip地址
|
self.update_push_ip() #直接修改奔耀端的报送ip地址
|
||||||
logger.info("已更新奔耀端推送 IP 地址")
|
logger.info("已更新奔耀端推送 IP 地址")
|
||||||
|
|
||||||
@@ -257,7 +279,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
def auto_feeding4to3(
|
def auto_feeding4to3(
|
||||||
self,
|
self,
|
||||||
# ★ 修改点:默认模板路径
|
# ★ 修改点:默认模板路径
|
||||||
xlsx_path: Optional[str] = "/Users/calvincao/Desktop/work/uni-lab-all/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/material_template.xlsx",
|
xlsx_path: Optional[str] = "/Users/sml/work/Unilab/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/material_template.xlsx",
|
||||||
# ---------------- WH4 - 加样头面 (Z=1, 12个点位) ----------------
|
# ---------------- WH4 - 加样头面 (Z=1, 12个点位) ----------------
|
||||||
WH4_x1_y1_z1_1_materialName: str = "", WH4_x1_y1_z1_1_quantity: float = 0.0,
|
WH4_x1_y1_z1_1_materialName: str = "", WH4_x1_y1_z1_1_quantity: float = 0.0,
|
||||||
WH4_x2_y1_z1_2_materialName: str = "", WH4_x2_y1_z1_2_quantity: float = 0.0,
|
WH4_x2_y1_z1_2_materialName: str = "", WH4_x2_y1_z1_2_quantity: float = 0.0,
|
||||||
@@ -394,10 +416,14 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
order_code = response.get("data", {}).get("orderCode")
|
order_code = response.get("data", {}).get("orderCode")
|
||||||
if not order_code:
|
if not order_code:
|
||||||
logger.error("上料任务未返回有效 orderCode!")
|
logger.error("上料任务未返回有效 orderCode!")
|
||||||
return response
|
return {"api_response": response, "order_finish": None}
|
||||||
# 等待完成报送
|
# 等待完成报送
|
||||||
result = self.wait_for_order_finish(order_code)
|
result = self.wait_for_order_finish(order_code)
|
||||||
return result
|
return {
|
||||||
|
"api_response": response,
|
||||||
|
"order_finish": result,
|
||||||
|
"items": items,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def auto_batch_outbound_from_xlsx(self, xlsx_path: str) -> Dict[str, Any]:
|
def auto_batch_outbound_from_xlsx(self, xlsx_path: str) -> Dict[str, Any]:
|
||||||
@@ -468,7 +494,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
# 2.14 新建实验
|
# 2.14 新建实验
|
||||||
def create_orders(self, xlsx_path: str) -> Dict[str, Any]:
|
def create_orders(self, xlsx_path: str, *, material_filter: Optional[str] = None) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
从 Excel 解析并创建实验(2.14)
|
从 Excel 解析并创建实验(2.14)
|
||||||
约定:
|
约定:
|
||||||
@@ -477,7 +503,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
- totalMass 自动计算为所有物料质量之和
|
- totalMass 自动计算为所有物料质量之和
|
||||||
- createTime 缺失或为空时自动填充为当前日期(YYYY/M/D)
|
- createTime 缺失或为空时自动填充为当前日期(YYYY/M/D)
|
||||||
"""
|
"""
|
||||||
default_path = Path("/Users/calvincao/Desktop/work/uni-lab-all/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx")
|
default_path = Path("/Users/sml/work/Unilab/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx")
|
||||||
path = Path(xlsx_path) if xlsx_path else default_path
|
path = Path(xlsx_path) if xlsx_path else default_path
|
||||||
print(f"[create_orders] 使用 Excel 路径: {path}")
|
print(f"[create_orders] 使用 Excel 路径: {path}")
|
||||||
if path != default_path:
|
if path != default_path:
|
||||||
@@ -623,9 +649,36 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
if not order_code:
|
if not order_code:
|
||||||
logger.error("上料任务未返回有效 orderCode!")
|
logger.error("上料任务未返回有效 orderCode!")
|
||||||
return response
|
return response
|
||||||
# 等待完成报送
|
# 等待完成报送
|
||||||
result = self.wait_for_order_finish(order_code)
|
result = self.wait_for_order_finish(order_code)
|
||||||
return result
|
report_data = result.get("report") if isinstance(result, dict) else None
|
||||||
|
materials_from_report = (
|
||||||
|
report_data.get("usedMaterials") if isinstance(report_data, dict) else None
|
||||||
|
)
|
||||||
|
if materials_from_report:
|
||||||
|
materials = materials_from_report
|
||||||
|
logger.info(
|
||||||
|
"[create_orders] 使用订单完成报送中的物料信息: "
|
||||||
|
f"{len(materials)} 条"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
materials = self._fetch_bioyond_materials(filter_keyword=material_filter)
|
||||||
|
logger.info(
|
||||||
|
"[create_orders] 未收到订单报送物料信息,回退到实时查询"
|
||||||
|
)
|
||||||
|
print("materials_from_report:", materials_from_report)
|
||||||
|
# TODO: 需要将 materials 字典转换为 ResourceSlot 对象后才能转运
|
||||||
|
# self.transfer_resource_to_another(
|
||||||
|
# resource=[materials],
|
||||||
|
# mount_resource=["YB_YH_Deck"],
|
||||||
|
# sites=[None],
|
||||||
|
# mount_device_id="BatteryStation"
|
||||||
|
# )
|
||||||
|
return {
|
||||||
|
"api_response": response,
|
||||||
|
"order_finish": result,
|
||||||
|
"materials": materials,
|
||||||
|
}
|
||||||
|
|
||||||
# 2.7 启动调度
|
# 2.7 启动调度
|
||||||
def scheduler_start(self) -> Dict[str, Any]:
|
def scheduler_start(self) -> Dict[str, Any]:
|
||||||
@@ -697,6 +750,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
return response
|
return response
|
||||||
# 等待完成报送
|
# 等待完成报送
|
||||||
result = self.wait_for_order_finish(order_code)
|
result = self.wait_for_order_finish(order_code)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# 2.5 批量查询实验报告(post过滤关键字查询)
|
# 2.5 批量查询实验报告(post过滤关键字查询)
|
||||||
@@ -1165,137 +1219,221 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
})
|
})
|
||||||
return final_result
|
return final_result
|
||||||
|
|
||||||
|
def _fetch_bioyond_materials(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
filter_keyword: Optional[str] = None,
|
||||||
|
type_mode: int = 2,
|
||||||
|
) -> List[Dict[str, Any]]:
|
||||||
|
query: Dict[str, Any] = {
|
||||||
|
"typeMode": type_mode,
|
||||||
|
"includeDetail": True,
|
||||||
|
}
|
||||||
|
if filter_keyword:
|
||||||
|
query["filter"] = filter_keyword
|
||||||
|
|
||||||
|
response = self._post_lims("/api/lims/storage/stock-material", query)
|
||||||
|
raw_materials = response.get("data")
|
||||||
|
if not isinstance(raw_materials, list):
|
||||||
|
raw_materials = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
resource_bioyond_to_plr(
|
||||||
|
raw_materials,
|
||||||
|
type_mapping=self.bioyond_config.get("material_type_mappings", MATERIAL_TYPE_MAPPINGS),
|
||||||
|
deck=self.deck,
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning(f"转换奔曜物料到 PLR 失败: {exc}", exc_info=True)
|
||||||
|
|
||||||
def run_bioyond_cell_workflow(config: Dict[str, Any]) -> BioyondCellWorkstation:
|
return raw_materials
|
||||||
"""按照统一配置执行奔曜配液与转运工作流。
|
|
||||||
|
|
||||||
Args:
|
def _convert_materials_to_plr(self, materials: List[Dict[str, Any]]) -> List[ResourcePLR]:
|
||||||
config: 统一的工作流配置。字段示例:
|
try:
|
||||||
|
return resource_bioyond_to_plr(
|
||||||
|
deepcopy(materials),
|
||||||
|
type_mapping=self.bioyond_config.get("material_type_mappings", MATERIAL_TYPE_MAPPINGS),
|
||||||
|
deck=self.deck,
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.error(f"物料转换为 PLR 失败: {exc}", exc_info=True)
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _wait_for_future(self, future, stage: str, timeout: Optional[float] = None):
|
||||||
|
if future is None:
|
||||||
|
return None
|
||||||
|
timeout = timeout or self.transfer_timeout
|
||||||
|
start = time.time()
|
||||||
|
while not future.done():
|
||||||
|
if (time.time() - start) > timeout:
|
||||||
|
raise TimeoutError(f"{stage} 超时 {timeout}s")
|
||||||
|
time.sleep(0.05)
|
||||||
|
return future.result()
|
||||||
|
|
||||||
|
def _register_plr_resources(self, resources: List[ResourcePLR]) -> None:
|
||||||
|
if not resources or not hasattr(self, "_ros_node") or self._ros_node is None:
|
||||||
|
return
|
||||||
|
future = ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, resources=resources)
|
||||||
|
self._wait_for_future(future, "update_resource")
|
||||||
|
|
||||||
|
def _get_target_resource(self, name: str) -> ResourcePLR:
|
||||||
|
if not hasattr(self, "_ros_node") or self._ros_node is None:
|
||||||
|
raise RuntimeError("ROS 节点未初始化,无法获取资源")
|
||||||
|
resource = self._ros_node.resource_tracker.figure_resource({"name": name}, try_mode=False) # type: ignore
|
||||||
|
if resource is None:
|
||||||
|
raise ValueError(f"未找到目标资源: {name}")
|
||||||
|
return resource
|
||||||
|
|
||||||
|
def _allocate_sites(self, parent_resource: ResourcePLR, count: int) -> List[str]:
|
||||||
|
if not hasattr(parent_resource, "get_free_sites"):
|
||||||
|
raise ValueError(f"资源 {parent_resource} 不支持自动分配站位")
|
||||||
|
free_indices = list(parent_resource.get_free_sites())
|
||||||
|
if len(free_indices) < count:
|
||||||
|
raise ValueError(f"{parent_resource.name} 可用站位不足 (need {count}, have {len(free_indices)})")
|
||||||
|
ordering = list(getattr(parent_resource, "_ordering", {}).keys())
|
||||||
|
sites: List[str] = []
|
||||||
|
for idx in free_indices[:count]:
|
||||||
|
if ordering and idx < len(ordering):
|
||||||
|
sites.append(ordering[idx])
|
||||||
|
else:
|
||||||
|
sites.append(str(idx))
|
||||||
|
return sites
|
||||||
|
|
||||||
|
def _invoke_coin_cell_workflow(self, material_payload: List[Dict[str, Any]]) -> Any:
|
||||||
|
timeout = float(self.bioyond_config.get("coin_cell_workflow_timeout", 300.0))
|
||||||
|
workflow_payload: Dict[str, Any] = {}
|
||||||
|
if isinstance(self.coin_cell_workflow_config, dict):
|
||||||
|
workflow_payload.update(deepcopy(self.coin_cell_workflow_config))
|
||||||
|
workflow_payload["materials"] = deepcopy(material_payload)
|
||||||
|
return self._call_remote_device_method(
|
||||||
|
self.transfer_target_device_id,
|
||||||
|
"run_coin_cell_assembly_workflow",
|
||||||
|
timeout=timeout,
|
||||||
|
workflow_config=workflow_payload,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _call_remote_device_method(
|
||||||
|
self,
|
||||||
|
device_id: str,
|
||||||
|
method: str,
|
||||||
|
*,
|
||||||
|
timeout: Optional[float] = None,
|
||||||
|
**kwargs,
|
||||||
|
) -> Any:
|
||||||
|
if not hasattr(self, "_ros_node") or self._ros_node is None:
|
||||||
|
raise RuntimeError("ROS 节点未初始化,无法调用远程设备")
|
||||||
|
if not device_id:
|
||||||
|
raise ValueError("device_id 不能为空")
|
||||||
|
if not method:
|
||||||
|
raise ValueError("method 不能为空")
|
||||||
|
|
||||||
|
timeout = timeout or self.transfer_timeout
|
||||||
|
payload = json.dumps(
|
||||||
{
|
{
|
||||||
"lab_registry": {"setup": True},
|
"function_name": method,
|
||||||
"deck": {"setup": True},
|
"function_args": kwargs,
|
||||||
"workstation": {"config": {...}},
|
},
|
||||||
"update_push_ip": True,
|
ensure_ascii=False,
|
||||||
"samples": [
|
)
|
||||||
{"name": "...", "board_type": "...", "bottle_type": "...", "location_code": "...", "warehouse_name": "..."}
|
future = ROS2DeviceNode.run_async_func(
|
||||||
],
|
self._ros_node.execute_single_action,
|
||||||
"scheduler": {"start": True, "log": True},
|
True,
|
||||||
"operations": {
|
device_id=device_id,
|
||||||
"auto_feeding4to3": {"enabled": True},
|
action_name="_execute_driver_command_async",
|
||||||
"create_orders": {"excel_path": "...", "log": True},
|
action_kwargs={"string": payload},
|
||||||
"transfer_3_to_2_to_1": {"enabled": True, "log": True},
|
)
|
||||||
"transfer_1_to_2": {"enabled": True, "log": True}
|
result = self._wait_for_future(future, f"{device_id}.{method}", timeout)
|
||||||
},
|
if hasattr(result, "return_info"):
|
||||||
"keep_alive": False,
|
try:
|
||||||
"keep_alive_interval": 1
|
return json.loads(result.return_info)
|
||||||
}
|
except Exception:
|
||||||
|
return result.return_info
|
||||||
|
return result
|
||||||
|
|
||||||
Returns:
|
def run_feeding_stage(self) -> Dict[str, Any]:
|
||||||
执行完毕的 `BioyondCellWorkstation` 实例。
|
self.create_sample(
|
||||||
"""
|
board_type="配液瓶(小)板",
|
||||||
|
bottle_type="配液瓶(小)",
|
||||||
if config.get("lab_registry", {}).get("setup", True):
|
location_code="B01",
|
||||||
lab_registry.setup()
|
name="配液瓶",
|
||||||
|
warehouse_name="手动堆栈"
|
||||||
deck_config = config.get("deck")
|
)
|
||||||
if isinstance(deck_config, dict):
|
self.create_sample(
|
||||||
deck = BIOYOND_YB_Deck(**deck_config)
|
board_type="5ml分液瓶板",
|
||||||
elif deck_config is None:
|
bottle_type="5ml分液瓶",
|
||||||
deck = BIOYOND_YB_Deck(setup=True)
|
location_code="B02",
|
||||||
else:
|
name="分液瓶",
|
||||||
deck = deck_config
|
warehouse_name="手动堆栈"
|
||||||
|
)
|
||||||
workstation_kwargs = dict(config.get("workstation", {}))
|
self.scheduler_start()
|
||||||
if "deck" not in workstation_kwargs:
|
feeding_task = self.auto_feeding4to3(
|
||||||
workstation_kwargs["deck"] = deck
|
xlsx_path="/Users/sml/work/Unilab/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/material_template.xlsx"
|
||||||
ws = BioyondCellWorkstation(**workstation_kwargs)
|
)
|
||||||
|
feeding_materials = self._fetch_bioyond_materials()
|
||||||
if config.get("update_push_ip", True):
|
return {
|
||||||
ws.update_push_ip()
|
"feeding_materials": feeding_materials,
|
||||||
|
"feeding_items": feeding_task.get("items", []),
|
||||||
for sample_cfg in config.get("samples", []):
|
"feeding_task": feeding_task,
|
||||||
ws.create_sample(**sample_cfg)
|
}
|
||||||
|
|
||||||
scheduler_cfg = config.get("scheduler", {})
|
|
||||||
if scheduler_cfg.get("start", True):
|
|
||||||
result = ws.scheduler_start()
|
|
||||||
if scheduler_cfg.get("log", True):
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
operations_cfg = config.get("operations", {})
|
|
||||||
|
|
||||||
auto_feeding_cfg = operations_cfg.get("auto_feeding4to3", {})
|
|
||||||
if auto_feeding_cfg.get("enabled", True):
|
|
||||||
result = ws.auto_feeding4to3()
|
|
||||||
if auto_feeding_cfg.get("log", True):
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
create_orders_cfg = operations_cfg.get("create_orders")
|
|
||||||
if create_orders_cfg:
|
|
||||||
excel_path = create_orders_cfg.get("excel_path")
|
|
||||||
if not excel_path:
|
|
||||||
raise ValueError("create_orders 需要提供 excel_path。")
|
|
||||||
result = ws.create_orders(Path(excel_path))
|
|
||||||
if create_orders_cfg.get("log", True):
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
transfer_321_cfg = operations_cfg.get("transfer_3_to_2_to_1", {})
|
|
||||||
if transfer_321_cfg.get("enabled", True):
|
|
||||||
result = ws.transfer_3_to_2_to_1()
|
|
||||||
if transfer_321_cfg.get("log", True):
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
transfer_12_cfg = operations_cfg.get("transfer_1_to_2", {})
|
|
||||||
if transfer_12_cfg.get("enabled", True):
|
|
||||||
result = ws.transfer_1_to_2()
|
|
||||||
if transfer_12_cfg.get("log", True):
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
if config.get("keep_alive", False):
|
|
||||||
interval = config.get("keep_alive_interval", 1)
|
|
||||||
while True:
|
|
||||||
time.sleep(interval)
|
|
||||||
|
|
||||||
return ws
|
|
||||||
|
|
||||||
|
def run_liquid_preparation_stage(
|
||||||
|
self,
|
||||||
|
feeding_materials: Optional[List[Dict[str, Any]]] = None,
|
||||||
|
) -> Dict[str, List[Dict[str, Any]]]:
|
||||||
|
result = self.create_orders(
|
||||||
|
xlsx_path="/Users/sml/work/Unilab/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx"
|
||||||
|
)
|
||||||
|
filter_keyword = self.bioyond_config.get("mixing_material_filter") or None
|
||||||
|
materials = result.get("materials")
|
||||||
|
if materials is None:
|
||||||
|
materials = self._fetch_bioyond_materials(filter_keyword=filter_keyword)
|
||||||
|
return {
|
||||||
|
"feeding_materials": feeding_materials or [],
|
||||||
|
"liquid_materials": materials,
|
||||||
|
}
|
||||||
|
|
||||||
|
def run_transfer_stage(
|
||||||
|
self,
|
||||||
|
liquid_materials: Optional[List[Dict[str, Any]]] = None,
|
||||||
|
source_wh_id: Optional[str] = '3a19debc-84b4-0359-e2d4-b3beea49348b',
|
||||||
|
source_x: int = 1,
|
||||||
|
source_y: int = 1,
|
||||||
|
source_z: int = 1
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""转运阶段:调用transfer_3_to_2_to_1执行3到2到1转运"""
|
||||||
|
logger.info("开始执行转运阶段 (run_transfer_stage)")
|
||||||
|
|
||||||
|
# 暂时注释掉物料转换和跨工站转运逻辑
|
||||||
|
# transfer_summary: Dict[str, Any] = {}
|
||||||
|
# try:
|
||||||
|
# source_materials = liquid_materials or self._fetch_bioyond_materials()
|
||||||
|
# transfer_plr = self._convert_materials_to_plr(source_materials)
|
||||||
|
# transfer_summary["plr_count"] = len(transfer_plr)
|
||||||
|
# ...
|
||||||
|
# except Exception as exc:
|
||||||
|
# transfer_summary["error"] = str(exc)
|
||||||
|
# logger.error(f"跨工站转运失败: {exc}", exc_info=True)
|
||||||
|
|
||||||
|
# 只执行核心的3到2到1转运
|
||||||
|
transfer_result = self.transfer_3_to_2_to_1(
|
||||||
|
source_wh_id=source_wh_id,
|
||||||
|
source_x=source_x,
|
||||||
|
source_y=source_y,
|
||||||
|
source_z=source_z
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info("转运阶段执行完成")
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"stage": "transfer",
|
||||||
|
"transfer_result": transfer_result
|
||||||
|
}
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
workflow_config = {
|
deck = BIOYOND_YB_Deck(setup=True)
|
||||||
"deck": {"setup": True},
|
w = BioyondCellWorkstation(deck=deck, address="172.16.28.102", port="502", debug_mode=False)
|
||||||
"update_push_ip": True,
|
feeding = w.run_feeding_stage()
|
||||||
"samples": [
|
liquid = w.run_liquid_preparation_stage(feeding.get("feeding_materials"))
|
||||||
{
|
transfer = w.run_transfer_stage(liquid.get("liquid_materials"))
|
||||||
"name": "配液瓶",
|
|
||||||
"board_type": "配液瓶(小)板",
|
|
||||||
"bottle_type": "配液瓶(小)",
|
|
||||||
"location_code": "E01",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "分液瓶",
|
|
||||||
"board_type": "5ml分液瓶板",
|
|
||||||
"bottle_type": "5ml分液瓶",
|
|
||||||
"location_code": "D01",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"operations": {
|
|
||||||
"auto_feeding4to3": {"enabled": True, "log": True},
|
|
||||||
"create_orders": {
|
|
||||||
"excel_path": "/Users/calvincao/Desktop/work/uni-lab-all/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx",
|
|
||||||
"log": True,
|
|
||||||
},
|
|
||||||
"transfer_3_to_2_to_1": {"enabled": True, "log": True},
|
|
||||||
"transfer_1_to_2": {"enabled": True, "log": True},
|
|
||||||
},
|
|
||||||
"keep_alive": True,
|
|
||||||
}
|
|
||||||
run_bioyond_cell_workflow(workflow_config)
|
|
||||||
|
|
||||||
# 1. location code
|
|
||||||
# 2. 实验文件
|
|
||||||
# 3. material template file
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
# re=ws.scheduler_stop()
|
# re=ws.scheduler_stop()
|
||||||
|
|||||||
Binary file not shown.
@@ -8,8 +8,8 @@ import os
|
|||||||
# BioyondCellWorkstation 默认配置(包含所有必需参数)
|
# BioyondCellWorkstation 默认配置(包含所有必需参数)
|
||||||
API_CONFIG = {
|
API_CONFIG = {
|
||||||
# API 连接配置
|
# API 连接配置
|
||||||
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.1.143:44389"),#实机
|
# "api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.1.143:44389"),#实机
|
||||||
# "api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.7.149:44388"),# 仿真机
|
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.11.219:44388"),# 仿真机
|
||||||
"api_key": os.getenv("BIOYOND_API_KEY", "8A819E5C"),
|
"api_key": os.getenv("BIOYOND_API_KEY", "8A819E5C"),
|
||||||
"timeout": int(os.getenv("BIOYOND_TIMEOUT", "30")),
|
"timeout": int(os.getenv("BIOYOND_TIMEOUT", "30")),
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ API_CONFIG = {
|
|||||||
"report_token": os.getenv("BIOYOND_REPORT_TOKEN", "CHANGE_ME_TOKEN"),
|
"report_token": os.getenv("BIOYOND_REPORT_TOKEN", "CHANGE_ME_TOKEN"),
|
||||||
|
|
||||||
# HTTP 服务配置
|
# HTTP 服务配置
|
||||||
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "172.16.2.140"), # HTTP服务监听地址,监听计算机飞连ip地址
|
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "172.16.11.2"), # HTTP服务监听地址,监听计算机飞连ip地址
|
||||||
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
|
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
|
||||||
"debug_mode": False,# 调试模式
|
"debug_mode": False,# 调试模式
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import csv
|
import csv
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
@@ -139,12 +138,11 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
if not modbus_client.client.is_socket_open():
|
if not modbus_client.client.is_socket_open():
|
||||||
raise ValueError('modbus tcp connection failed')
|
raise ValueError('modbus tcp connection failed')
|
||||||
self.nodes = BaseClient.load_csv(os.path.join(os.path.dirname(__file__), 'coin_cell_assembly_a.csv'))
|
self.nodes = BaseClient.load_csv(os.path.join(os.path.dirname(__file__), 'coin_cell_assembly_1105.csv'))
|
||||||
self.client = modbus_client.register_node_list(self.nodes)
|
self.client = modbus_client.register_node_list(self.nodes)
|
||||||
else:
|
else:
|
||||||
print("测试模式,跳过连接")
|
print("测试模式,跳过连接")
|
||||||
self.nodes, self.client = None, None
|
self.nodes, self.client = None, None
|
||||||
|
|
||||||
""" 工站的配置 """
|
""" 工站的配置 """
|
||||||
|
|
||||||
self.success = False
|
self.success = False
|
||||||
@@ -161,6 +159,27 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
"resources": [self.deck]
|
"resources": [self.deck]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def sync_transfer_resources(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
供跨工站转运完成后调用,强制将当前台面资源同步到云端/前端。
|
||||||
|
"""
|
||||||
|
if not hasattr(self, "_ros_node") or self._ros_node is None:
|
||||||
|
return {"status": "failed", "error": "ros_node_not_ready"}
|
||||||
|
if self.deck is None:
|
||||||
|
return {"status": "failed", "error": "deck_not_initialized"}
|
||||||
|
try:
|
||||||
|
future = ROS2DeviceNode.run_async_func(
|
||||||
|
self._ros_node.update_resource,
|
||||||
|
True,
|
||||||
|
resources=[self.deck],
|
||||||
|
)
|
||||||
|
if future:
|
||||||
|
future.result()
|
||||||
|
return {"status": "success"}
|
||||||
|
except Exception as exc:
|
||||||
|
logger.error(f"同步转运资源失败: {exc}", exc_info=True)
|
||||||
|
return {"status": "failed", "error": str(exc)}
|
||||||
|
|
||||||
# 批量操作在这里写
|
# 批量操作在这里写
|
||||||
async def change_hole_sheet_to_2(self, hole: MaterialHole):
|
async def change_hole_sheet_to_2(self, hole: MaterialHole):
|
||||||
hole._unilabos_state["max_sheets"] = 2
|
hole._unilabos_state["max_sheets"] = 2
|
||||||
@@ -986,6 +1005,31 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
#self.success = True
|
#self.success = True
|
||||||
#return self.success
|
#return self.success
|
||||||
|
|
||||||
|
def run_packaging_workflow(self, workflow_config: Dict[str, Any]) -> "CoinCellAssemblyWorkstation":
|
||||||
|
config = workflow_config or {}
|
||||||
|
|
||||||
|
qiming_params = config.get("qiming") or {}
|
||||||
|
if qiming_params:
|
||||||
|
self.qiming_coin_cell_code(**qiming_params)
|
||||||
|
|
||||||
|
if config.get("init", True):
|
||||||
|
self.func_pack_device_init()
|
||||||
|
if config.get("auto", True):
|
||||||
|
self.func_pack_device_auto()
|
||||||
|
if config.get("start", True):
|
||||||
|
self.func_pack_device_start()
|
||||||
|
|
||||||
|
packaging_config = config.get("packaging") or {}
|
||||||
|
bottle_num = packaging_config.get("bottle_num")
|
||||||
|
if bottle_num is not None:
|
||||||
|
self.func_pack_send_bottle_num(bottle_num)
|
||||||
|
|
||||||
|
allpack_params = packaging_config.get("command") or {}
|
||||||
|
if allpack_params:
|
||||||
|
self.func_allpack_cmd(**allpack_params)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
def fun_wuliao_test(self) -> bool:
|
def fun_wuliao_test(self) -> bool:
|
||||||
#找到data_init中构建的2个物料盘
|
#找到data_init中构建的2个物料盘
|
||||||
liaopan3 = self.deck.get_resource("\u7535\u6c60\u6599\u76d8")
|
liaopan3 = self.deck.get_resource("\u7535\u6c60\u6599\u76d8")
|
||||||
@@ -1199,96 +1243,95 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
"""移液枪头库存 (数量, INT16)"""
|
"""移液枪头库存 (数量, INT16)"""
|
||||||
inventory, read_err = self.client.register_node_list(self.nodes).use_node('REG_DATA_TIPS_INVENTORY').read(1)
|
inventory, read_err = self.client.register_node_list(self.nodes).use_node('REG_DATA_TIPS_INVENTORY').read(1)
|
||||||
return inventory
|
return inventory
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def run_coin_cell_packaging_workflow(config: Dict[str, Any]) -> CoinCellAssemblyWorkstation:
|
def run_coin_cell_assembly_workflow(
|
||||||
"""根据统一配置顺序执行扣电池装配工作流。
|
self,
|
||||||
|
workflow_config: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
config: Dict[str, Any]
|
||||||
|
if workflow_config is None:
|
||||||
|
config = {}
|
||||||
|
elif isinstance(workflow_config, list):
|
||||||
|
config = {"materials": workflow_config}
|
||||||
|
else:
|
||||||
|
config = workflow_config
|
||||||
|
qiming_defaults = {
|
||||||
|
"fujipian_panshu": 1,
|
||||||
|
"fujipian_juzhendianwei": 0,
|
||||||
|
"gemopanshu": 1,
|
||||||
|
"gemo_juzhendianwei": 0,
|
||||||
|
"lvbodian": True,
|
||||||
|
"battery_pressure_mode": True,
|
||||||
|
"battery_pressure": 4200,
|
||||||
|
"battery_clean_ignore": False,
|
||||||
|
}
|
||||||
|
qiming_params = {**qiming_defaults, **(config.get("qiming") or {})}
|
||||||
|
qiming_success = self.qiming_coin_cell_code(**qiming_params)
|
||||||
|
|
||||||
Args:
|
step_results: Dict[str, Any] = {}
|
||||||
config: 统一的工作流配置。字段示例:
|
try:
|
||||||
{
|
self.func_pack_device_init()
|
||||||
"deck": {"setup": True, "name": "coin_cell_deck"},
|
step_results["init"] = True
|
||||||
"workstation": {"address": "...", "port": "...", "debug_mode": False},
|
except Exception as exc:
|
||||||
"qiming": {...},
|
step_results["init"] = f"error: {exc}"
|
||||||
"init": True,
|
|
||||||
"auto": True,
|
|
||||||
"start": True,
|
|
||||||
"packaging": {
|
|
||||||
"bottle_num": 16,
|
|
||||||
"command": {...}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Returns:
|
try:
|
||||||
执行完毕的 `CoinCellAssemblyWorkstation` 实例。
|
self.func_pack_device_auto()
|
||||||
"""
|
step_results["auto"] = True
|
||||||
|
except Exception as exc:
|
||||||
|
step_results["auto"] = f"error: {exc}"
|
||||||
|
|
||||||
deck_config = config.get("deck")
|
try:
|
||||||
if isinstance(deck_config, Deck):
|
self.func_pack_device_start()
|
||||||
deck = deck_config
|
step_results["start"] = True
|
||||||
elif isinstance(deck_config, dict):
|
except Exception as exc:
|
||||||
deck = CoincellDeck(**deck_config)
|
step_results["start"] = f"error: {exc}"
|
||||||
elif deck_config is None:
|
|
||||||
deck = CoincellDeck(setup=True, name="coin_cell_deck")
|
|
||||||
else:
|
|
||||||
raise ValueError("deck 配置需为 Deck 实例或 dict。")
|
|
||||||
|
|
||||||
workstation_config = dict(config.get("workstation", {}))
|
packaging_cfg = config.get("packaging") or {}
|
||||||
workstation_config.setdefault("deck", deck)
|
bottle_num = packaging_cfg.get("bottle_num", 1)
|
||||||
workstation = CoinCellAssemblyWorkstation(**workstation_config)
|
try:
|
||||||
|
self.func_pack_send_bottle_num(bottle_num)
|
||||||
|
step_results["send_bottle_num"] = True
|
||||||
|
except Exception as exc:
|
||||||
|
step_results["send_bottle_num"] = f"error: {exc}"
|
||||||
|
|
||||||
qiming_params = config.get("qiming", {})
|
command_defaults = {
|
||||||
if qiming_params:
|
"elec_num": 1,
|
||||||
workstation.qiming_coin_cell_code(**qiming_params)
|
"elec_use_num": 1,
|
||||||
|
"elec_vol": 50,
|
||||||
|
"assembly_type": 7,
|
||||||
|
"assembly_pressure": 4200,
|
||||||
|
"file_path": "/Users/sml/work",
|
||||||
|
}
|
||||||
|
command_params = {**command_defaults, **(packaging_cfg.get("command") or {})}
|
||||||
|
packaging_result = self.func_allpack_cmd(**command_params)
|
||||||
|
|
||||||
if config.get("init", True):
|
finished_result = self.func_pack_send_finished_cmd()
|
||||||
workstation.func_pack_device_init()
|
stop_result = self.func_pack_device_stop()
|
||||||
if config.get("auto", True):
|
|
||||||
workstation.func_pack_device_auto()
|
|
||||||
if config.get("start", True):
|
|
||||||
workstation.func_pack_device_start()
|
|
||||||
|
|
||||||
packaging_config = config.get("packaging", {})
|
return {
|
||||||
bottle_num = packaging_config.get("bottle_num")
|
"qiming": {
|
||||||
if bottle_num is not None:
|
"params": qiming_params,
|
||||||
workstation.func_pack_send_bottle_num(bottle_num)
|
"success": qiming_success,
|
||||||
|
},
|
||||||
allpack_params = packaging_config.get("command", {})
|
"workflow_steps": step_results,
|
||||||
if allpack_params:
|
"packaging": {
|
||||||
workstation.func_allpack_cmd(**allpack_params)
|
"bottle_num": bottle_num,
|
||||||
|
"command": command_params,
|
||||||
return workstation
|
"result": packaging_result,
|
||||||
|
},
|
||||||
|
"finish": {
|
||||||
|
"send_finished": finished_result,
|
||||||
|
"stop": stop_result,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
workflow_config = {
|
deck = CoincellDeck(setup=True, name="coin_cell_deck")
|
||||||
"deck": {"setup": True, "name": "coin_cell_deck"},
|
w = CoinCellAssemblyWorkstation(deck=deck, address="172.16.28.102", port="502", debug_mode=False)
|
||||||
"workstation": {
|
w.run_coin_cell_assembly_workflow()
|
||||||
"address": "172.16.28.102",
|
|
||||||
"port": "502",
|
|
||||||
"debug_mode": False,
|
|
||||||
},
|
|
||||||
"qiming": {
|
|
||||||
"fujipian_panshu": 1,
|
|
||||||
"fujipian_juzhendianwei": 2,
|
|
||||||
"gemopanshu": 3,
|
|
||||||
"gemo_juzhendianwei": 4,
|
|
||||||
"lvbodian": False,
|
|
||||||
"battery_pressure_mode": False,
|
|
||||||
"battery_pressure": 4200,
|
|
||||||
"battery_clean_ignore": False,
|
|
||||||
},
|
|
||||||
"packaging": {
|
|
||||||
"bottle_num": 16,
|
|
||||||
"command": {
|
|
||||||
"elec_num": 16,
|
|
||||||
"elec_use_num": 16,
|
|
||||||
"elec_vol": 50,
|
|
||||||
"assembly_type": 7,
|
|
||||||
"assembly_pressure": 4200,
|
|
||||||
"file_path": "/Users/calvincao/Desktop/work/Uni-Lab-OS-hhm",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
run_coin_cell_packaging_workflow(workflow_config)
|
|
||||||
@@ -821,6 +821,154 @@ bioyond_cell:
|
|||||||
title: resource_tree_transfer参数
|
title: resource_tree_transfer参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-run_feeding_stage:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles:
|
||||||
|
input: []
|
||||||
|
output:
|
||||||
|
- data_key: feeding_materials
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: feeding_materials
|
||||||
|
label: Feeding Materials
|
||||||
|
placeholder_keys: {}
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
feeding_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- feeding_materials
|
||||||
|
type: object
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: run_feeding_stage参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-run_liquid_preparation_stage:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles:
|
||||||
|
input:
|
||||||
|
- data_key: feeding_materials
|
||||||
|
data_source: handle
|
||||||
|
data_type: resource
|
||||||
|
handler_key: feeding_materials
|
||||||
|
label: Feeding Materials
|
||||||
|
output:
|
||||||
|
- data_key: liquid_materials
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: liquid_materials
|
||||||
|
label: Liquid Materials
|
||||||
|
placeholder_keys: {}
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
feeding_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
liquid_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- liquid_materials
|
||||||
|
type: object
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
feeding_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: run_liquid_preparation_stage参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-run_transfer_stage:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles:
|
||||||
|
input:
|
||||||
|
- data_key: liquid_materials
|
||||||
|
data_source: handle
|
||||||
|
data_type: resource
|
||||||
|
handler_key: liquid_materials
|
||||||
|
label: Liquid Materials
|
||||||
|
output:
|
||||||
|
- data_key: transfer_materials
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: transfer_materials
|
||||||
|
label: Transfer Materials
|
||||||
|
placeholder_keys: {}
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
liquid_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
transfer_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
transfer_summary:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- transfer_materials
|
||||||
|
type: object
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
liquid_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
liquid_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
transfer_materials:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
transfer_summary:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: run_transfer_stage参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
auto-scheduler_continue:
|
auto-scheduler_continue:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -1112,7 +1260,7 @@ bioyond_cell:
|
|||||||
device_id: String
|
device_id: String
|
||||||
type: python
|
type: python
|
||||||
config_info: []
|
config_info: []
|
||||||
description: ''
|
description: 配液工站
|
||||||
handles: []
|
handles: []
|
||||||
icon: benyao2.webp
|
icon: benyao2.webp
|
||||||
init_param_schema:
|
init_param_schema:
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ coincellassemblyworkstation_device:
|
|||||||
elec_num: null
|
elec_num: null
|
||||||
elec_use_num: null
|
elec_use_num: null
|
||||||
elec_vol: 50
|
elec_vol: 50
|
||||||
file_path: C:\Users\67484\Desktop
|
file_path: /Users/sml/work
|
||||||
handles: {}
|
handles: {}
|
||||||
placeholder_keys: {}
|
placeholder_keys: {}
|
||||||
result: {}
|
result: {}
|
||||||
@@ -103,7 +103,7 @@ coincellassemblyworkstation_device:
|
|||||||
default: 50
|
default: 50
|
||||||
type: integer
|
type: integer
|
||||||
file_path:
|
file_path:
|
||||||
default: C:\Users\67484\Desktop
|
default: /Users/sml/work
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- elec_num
|
- elec_num
|
||||||
@@ -332,7 +332,7 @@ coincellassemblyworkstation_device:
|
|||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
goal_default:
|
goal_default:
|
||||||
file_path: D:\coin_cell_data
|
file_path: /Users/sml/work
|
||||||
handles: {}
|
handles: {}
|
||||||
placeholder_keys: {}
|
placeholder_keys: {}
|
||||||
result: {}
|
result: {}
|
||||||
@@ -343,7 +343,7 @@ coincellassemblyworkstation_device:
|
|||||||
goal:
|
goal:
|
||||||
properties:
|
properties:
|
||||||
file_path:
|
file_path:
|
||||||
default: D:\coin_cell_data
|
default: /Users/sml/work
|
||||||
type: string
|
type: string
|
||||||
required: []
|
required: []
|
||||||
type: object
|
type: object
|
||||||
@@ -477,6 +477,171 @@ coincellassemblyworkstation_device:
|
|||||||
title: qiming_coin_cell_code参数
|
title: qiming_coin_cell_code参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-run_coin_cell_assembly_workflow:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
workflow_config:
|
||||||
|
type: object
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
goal_default:
|
||||||
|
workflow_config: {}
|
||||||
|
handles:
|
||||||
|
input:
|
||||||
|
- data_key: workflow_config
|
||||||
|
data_source: handle
|
||||||
|
data_type: resource
|
||||||
|
handler_key: WorkflowConfig
|
||||||
|
label: Workflow Config
|
||||||
|
output:
|
||||||
|
- data_key: qiming
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: QimingResult
|
||||||
|
label: Qiming Result
|
||||||
|
- data_key: workflow_steps
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: WorkflowSteps
|
||||||
|
label: Workflow Steps
|
||||||
|
- data_key: packaging
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: PackagingResult
|
||||||
|
label: Packaging Result
|
||||||
|
- data_key: finish
|
||||||
|
data_source: executor
|
||||||
|
data_type: resource
|
||||||
|
handler_key: FinishResult
|
||||||
|
label: Finish Result
|
||||||
|
placeholder_keys: {}
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
finish:
|
||||||
|
properties:
|
||||||
|
send_finished:
|
||||||
|
type: object
|
||||||
|
stop:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- send_finished
|
||||||
|
- stop
|
||||||
|
type: object
|
||||||
|
packaging:
|
||||||
|
properties:
|
||||||
|
bottle_num:
|
||||||
|
type: integer
|
||||||
|
command:
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- bottle_num
|
||||||
|
- command
|
||||||
|
- result
|
||||||
|
type: object
|
||||||
|
qiming:
|
||||||
|
properties:
|
||||||
|
params:
|
||||||
|
type: object
|
||||||
|
success:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- params
|
||||||
|
- success
|
||||||
|
type: object
|
||||||
|
workflow_steps:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- qiming
|
||||||
|
- workflow_steps
|
||||||
|
- packaging
|
||||||
|
- finish
|
||||||
|
type: object
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
workflow_config:
|
||||||
|
type: object
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
finish:
|
||||||
|
properties:
|
||||||
|
send_finished:
|
||||||
|
type: object
|
||||||
|
stop:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- send_finished
|
||||||
|
- stop
|
||||||
|
type: object
|
||||||
|
packaging:
|
||||||
|
properties:
|
||||||
|
bottle_num:
|
||||||
|
type: integer
|
||||||
|
command:
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- bottle_num
|
||||||
|
- command
|
||||||
|
- result
|
||||||
|
type: object
|
||||||
|
qiming:
|
||||||
|
properties:
|
||||||
|
params:
|
||||||
|
type: object
|
||||||
|
success:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- params
|
||||||
|
- success
|
||||||
|
type: object
|
||||||
|
workflow_steps:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- qiming
|
||||||
|
- workflow_steps
|
||||||
|
- packaging
|
||||||
|
- finish
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: run_coin_cell_assembly_workflow参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-run_packaging_workflow:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
workflow_config: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
workflow_config:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- workflow_config
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: run_packaging_workflow参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
module: unilabos.devices.workstation.coin_cell_assembly.coin_cell_assembly:CoinCellAssemblyWorkstation
|
module: unilabos.devices.workstation.coin_cell_assembly.coin_cell_assembly:CoinCellAssemblyWorkstation
|
||||||
status_types:
|
status_types:
|
||||||
data_assembly_coin_cell_num: int
|
data_assembly_coin_cell_num: int
|
||||||
@@ -500,20 +665,22 @@ coincellassemblyworkstation_device:
|
|||||||
sys_status: str
|
sys_status: str
|
||||||
type: python
|
type: python
|
||||||
config_info: []
|
config_info: []
|
||||||
description: ''
|
description: 扣电工站
|
||||||
handles: []
|
handles: []
|
||||||
icon: koudian.webp
|
icon: koudian.webp
|
||||||
init_param_schema:
|
init_param_schema:
|
||||||
config:
|
config:
|
||||||
properties:
|
properties:
|
||||||
address:
|
address:
|
||||||
default: 172.21.32.111
|
default: 172.16.28.102
|
||||||
type: string
|
type: string
|
||||||
|
config:
|
||||||
|
type: object
|
||||||
debug_mode:
|
debug_mode:
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
deck:
|
deck:
|
||||||
type: object
|
type: string
|
||||||
port:
|
port:
|
||||||
default: '502'
|
default: '502'
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
@@ -654,6 +654,31 @@ liquid_handler:
|
|||||||
title: iter_tips参数
|
title: iter_tips参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
auto-set_group:
|
auto-set_group:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -6170,6 +6195,31 @@ liquid_handler.prcxi:
|
|||||||
title: move_to参数
|
title: move_to参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
auto-run_protocol:
|
auto-run_protocol:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
|
|||||||
@@ -5,6 +5,73 @@ neware_battery_test_system:
|
|||||||
- battery_test
|
- battery_test
|
||||||
class:
|
class:
|
||||||
action_value_mappings:
|
action_value_mappings:
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-print_status_summary:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: print_status_summary参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-test_connection:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: test_connection参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
debug_resource_names:
|
debug_resource_names:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -320,28 +387,24 @@ neware_battery_test_system:
|
|||||||
config:
|
config:
|
||||||
properties:
|
properties:
|
||||||
devtype:
|
devtype:
|
||||||
default: '27'
|
|
||||||
type: string
|
type: string
|
||||||
ip:
|
ip:
|
||||||
default: 127.0.0.1
|
|
||||||
type: string
|
type: string
|
||||||
machine_id:
|
machine_id:
|
||||||
default: 1
|
default: 1
|
||||||
type: integer
|
type: integer
|
||||||
port:
|
port:
|
||||||
default: 502
|
|
||||||
type: integer
|
type: integer
|
||||||
size_x:
|
size_x:
|
||||||
default: 50.0
|
default: 50
|
||||||
type: number
|
type: number
|
||||||
size_y:
|
size_y:
|
||||||
default: 50.0
|
default: 50
|
||||||
type: number
|
type: number
|
||||||
size_z:
|
size_z:
|
||||||
default: 20.0
|
default: 20
|
||||||
type: number
|
type: number
|
||||||
timeout:
|
timeout:
|
||||||
default: 20
|
|
||||||
type: integer
|
type: integer
|
||||||
required: []
|
required: []
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@@ -45,6 +45,31 @@ virtual_centrifuge:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
centrifuge:
|
centrifuge:
|
||||||
feedback:
|
feedback:
|
||||||
current_speed: current_speed
|
current_speed: current_speed
|
||||||
@@ -335,6 +360,31 @@ virtual_column:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
run_column:
|
run_column:
|
||||||
feedback:
|
feedback:
|
||||||
current_status: current_status
|
current_status: current_status
|
||||||
@@ -732,6 +782,31 @@ virtual_filter:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
filter:
|
filter:
|
||||||
feedback:
|
feedback:
|
||||||
current_status: current_status
|
current_status: current_status
|
||||||
@@ -1358,6 +1433,31 @@ virtual_heatchill:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
heat_chill:
|
heat_chill:
|
||||||
feedback:
|
feedback:
|
||||||
status: status
|
status: status
|
||||||
@@ -2358,6 +2458,31 @@ virtual_rotavap:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
evaporate:
|
evaporate:
|
||||||
feedback:
|
feedback:
|
||||||
current_device: current_device
|
current_device: current_device
|
||||||
@@ -2690,6 +2815,31 @@ virtual_separator:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
separate:
|
separate:
|
||||||
feedback:
|
feedback:
|
||||||
current_status: status
|
current_status: status
|
||||||
@@ -3600,6 +3750,31 @@ virtual_solenoid_valve:
|
|||||||
title: is_closed参数
|
title: is_closed参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
auto-reset:
|
auto-reset:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -4177,6 +4352,31 @@ virtual_solid_dispenser:
|
|||||||
title: parse_mol_string参数
|
title: parse_mol_string参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
module: unilabos.devices.virtual.virtual_solid_dispenser:VirtualSolidDispenser
|
module: unilabos.devices.virtual.virtual_solid_dispenser:VirtualSolidDispenser
|
||||||
status_types:
|
status_types:
|
||||||
current_reagent: str
|
current_reagent: str
|
||||||
@@ -4278,6 +4478,31 @@ virtual_stirrer:
|
|||||||
title: initialize参数
|
title: initialize参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommandAsync
|
type: UniLabJsonCommandAsync
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
start_stir:
|
start_stir:
|
||||||
feedback:
|
feedback:
|
||||||
status: status
|
status: status
|
||||||
@@ -4995,6 +5220,31 @@ virtual_transfer_pump:
|
|||||||
title: is_full参数
|
title: is_full参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
|
auto-post_init:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
ros_node: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
ros_node:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- ros_node
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: post_init参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
auto-pull_plunger:
|
auto-pull_plunger:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
|
|||||||
@@ -1,16 +1,3 @@
|
|||||||
YB_qiang_tou:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottles:YB_qiang_tou
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_qiang_tou
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_20ml_fenyeping:
|
YB_20ml_fenyeping:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
@@ -37,6 +24,19 @@ YB_5ml_fenyeping:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
YB_jia_yang_tou_da:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
- YB_bottle
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.YB_bottles:YB_jia_yang_tou_da
|
||||||
|
type: pylabrobot
|
||||||
|
description: YB_jia_yang_tou_da
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
YB_pei_ye_da_Bottle:
|
YB_pei_ye_da_Bottle:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
@@ -63,14 +63,14 @@ YB_pei_ye_xiao_Bottle:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
YB_jia_yang_tou_da:
|
YB_qiang_tou:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
- YB_bottle
|
- YB_bottle
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.YB_bottles:YB_jia_yang_tou_da
|
module: unilabos.resources.bioyond.YB_bottles:YB_qiang_tou
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: YB_jia_yang_tou_da
|
description: YB_qiang_tou
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
@@ -80,6 +80,7 @@ YB_ye_Bottle:
|
|||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
- YB_bottle_carriers
|
- YB_bottle_carriers
|
||||||
|
- YB_bottle
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.YB_bottles:YB_ye_Bottle
|
module: unilabos.resources.bioyond.YB_bottles:YB_ye_Bottle
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
@@ -88,4 +89,4 @@ YB_ye_Bottle:
|
|||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|||||||
@@ -11,71 +11,6 @@ YB_100ml_yeti:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
# YB_1BottleCarrier:
|
|
||||||
# category:
|
|
||||||
# - yb3
|
|
||||||
# - YB_bottle_carriers
|
|
||||||
# class:
|
|
||||||
# module: unilabos.resources.bioyond.YB_bottle_carriers:YB_1BottleCarrier
|
|
||||||
# type: pylabrobot
|
|
||||||
# description: YB_1BottleCarrier
|
|
||||||
# handles: []
|
|
||||||
# icon: ''
|
|
||||||
# init_param_schema: {}
|
|
||||||
# registry_type: resource
|
|
||||||
# version: 1.0.0
|
|
||||||
YB_gaonianye:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle_carriers
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_gaonianye
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_gaonianye
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_peiyepingdaban:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle_carriers
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingdaban
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_peiyepingdaban
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_6StockCarrier:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle_carriers
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6StockCarrier
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_6StockCarrier
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_6VialCarrier:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle_carriers
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6VialCarrier
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_6VialCarrier
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_20ml_fenyepingban:
|
YB_20ml_fenyepingban:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
@@ -102,40 +37,27 @@ YB_5ml_fenyepingban:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
YB_peiyepingxiaoban:
|
YB_6StockCarrier:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
- YB_bottle_carriers
|
- YB_bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingxiaoban
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6StockCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: YB_peiyepingxiaoban
|
description: YB_6StockCarrier
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
YB_shi_pei_qi_kuai:
|
YB_6VialCarrier:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
- YB_bottle_carriers
|
- YB_bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_shi_pei_qi_kuai
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_6VialCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: YB_shi_pei_qi_kuai
|
description: YB_6VialCarrier
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema: {}
|
|
||||||
registry_type: resource
|
|
||||||
version: 1.0.0
|
|
||||||
YB_qiang_tou_he:
|
|
||||||
category:
|
|
||||||
- yb3
|
|
||||||
- YB_bottle_carriers
|
|
||||||
class:
|
|
||||||
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_qiang_tou_he
|
|
||||||
type: pylabrobot
|
|
||||||
description: YB_qiang_tou_he
|
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
@@ -154,19 +76,19 @@ YB_gao_nian_ye_Bottle:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
# YB_jia_yang_tou_da:
|
YB_gaonianye:
|
||||||
# category:
|
category:
|
||||||
# - yb3
|
- yb3
|
||||||
# - YB_bottle_carriers
|
- YB_bottle_carriers
|
||||||
# class:
|
class:
|
||||||
# module: unilabos.resources.bioyond.YB_bottles:YB_jia_yang_tou_da
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_gaonianye
|
||||||
# type: pylabrobot
|
type: pylabrobot
|
||||||
# description: YB_jia_yang_tou_da
|
description: YB_gaonianye
|
||||||
# handles: []
|
handles: []
|
||||||
# icon: ''
|
icon: ''
|
||||||
# init_param_schema: {}
|
init_param_schema: {}
|
||||||
# registry_type: resource
|
registry_type: resource
|
||||||
# version: 1.0.0
|
version: 1.0.0
|
||||||
YB_jia_yang_tou_da_Carrier:
|
YB_jia_yang_tou_da_Carrier:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
@@ -180,14 +102,53 @@ YB_jia_yang_tou_da_Carrier:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
YB_ye_100ml_Bottle:
|
YB_peiyepingdaban:
|
||||||
category:
|
category:
|
||||||
- yb3
|
- yb3
|
||||||
- YB_bottle_carriers
|
- YB_bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.YB_bottles:YB_ye_100ml_Bottle
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingdaban
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: YB_ye_100ml_Bottle
|
description: YB_peiyepingdaban
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
YB_peiyepingxiaoban:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
- YB_bottle_carriers
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_peiyepingxiaoban
|
||||||
|
type: pylabrobot
|
||||||
|
description: YB_peiyepingxiaoban
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
YB_qiang_tou_he:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
- YB_bottle_carriers
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_qiang_tou_he
|
||||||
|
type: pylabrobot
|
||||||
|
description: YB_qiang_tou_he
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
YB_shi_pei_qi_kuai:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
- YB_bottle_carriers
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.YB_bottle_carriers:YB_shi_pei_qi_kuai
|
||||||
|
type: pylabrobot
|
||||||
|
description: YB_shi_pei_qi_kuai
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
@@ -206,3 +167,16 @@ YB_ye:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
YB_ye_100ml_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
- YB_bottle_carriers
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.YB_bottles:YB_ye_100ml_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
description: YB_ye_100ml_Bottle
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|||||||
@@ -674,10 +674,15 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[st
|
|||||||
for loc in material.get("locations", []):
|
for loc in material.get("locations", []):
|
||||||
if hasattr(deck, "warehouses") and loc.get("whName") in deck.warehouses:
|
if hasattr(deck, "warehouses") and loc.get("whName") in deck.warehouses:
|
||||||
warehouse = deck.warehouses[loc["whName"]]
|
warehouse = deck.warehouses[loc["whName"]]
|
||||||
|
num_x = getattr(warehouse, "num_items_x", 0) or 0
|
||||||
|
num_y = getattr(warehouse, "num_items_y", 0) or 0
|
||||||
|
num_z = getattr(warehouse, "num_items_z", 0) or 0
|
||||||
|
if num_x <= 0 or num_y <= 0 or num_z <= 0:
|
||||||
|
continue
|
||||||
idx = (
|
idx = (
|
||||||
(loc.get("y", 0) - 1) * warehouse.num_items_x * warehouse.num_items_y
|
(loc.get("z", 0) - 1) * num_x * num_y
|
||||||
+ (loc.get("x", 0) - 1) * warehouse.num_items_x
|
+ (loc.get("y", 0) - 1) * num_x
|
||||||
+ (loc.get("z", 0) - 1)
|
+ (loc.get("x", 0) - 1)
|
||||||
)
|
)
|
||||||
if 0 <= idx < warehouse.capacity:
|
if 0 <= idx < warehouse.capacity:
|
||||||
if warehouse[idx] is None or isinstance(warehouse[idx], ResourceHolder):
|
if warehouse[idx] is None or isinstance(warehouse[idx], ResourceHolder):
|
||||||
|
|||||||
@@ -402,7 +402,6 @@ class ROS2WorkstationNode(BaseROS2DeviceNode):
|
|||||||
|
|
||||||
return result_future.result
|
return result_future.result
|
||||||
|
|
||||||
"""还没有改过的部分"""
|
|
||||||
|
|
||||||
def _setup_hardware_proxy(
|
def _setup_hardware_proxy(
|
||||||
self, device: ROS2DeviceNode, communication_device: ROS2DeviceNode, read_method, write_method
|
self, device: ROS2DeviceNode, communication_device: ROS2DeviceNode, read_method, write_method
|
||||||
|
|||||||
Reference in New Issue
Block a user