mirror of
https://github.com/deepmodeling/Uni-Lab-OS
synced 2026-05-23 16:19:53 +00:00
feat: RNA simplify station action signatures and add order query
- Add explicit reset_operations default; keep hidden plumbing kwargs-only. - Add read-only get_order_list manual_confirm action that calls order_query with latest_only and exposes order_id/order_ids handles. - Collapse start_experiment visible signature to (order_id, materials_loaded, timeout_seconds, assignee_user_ids); legacy params consumed from kwargs to preserve runtime contract. - Reduce submit_experiment_1 graph handles to order_id, resource, coin_cell_code, mount_resource; result dict gains order_id while keeping existing keys.
This commit is contained in:
@@ -377,7 +377,11 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
always_free=True,
|
||||
node_type=NodeType.MANUAL_CONFIRM,
|
||||
placeholder_keys={"assignee_user_ids": "unilabos_manual_confirm"},
|
||||
goal_default={"timeout_seconds": 3600, "assignee_user_ids": []},
|
||||
goal_default={
|
||||
"reset_operations": ["scheduler_reset", "reset_order_status", "reset_location"],
|
||||
"timeout_seconds": 3600,
|
||||
"assignee_user_ids": [],
|
||||
},
|
||||
feedback_interval=300,
|
||||
description="复位小核酸实验前状态",
|
||||
)
|
||||
@@ -423,35 +427,14 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
description="提交小核酸实验1(报告基因检测)",
|
||||
handles=[
|
||||
ActionOutputHandle(
|
||||
key="order_ids",
|
||||
data_type="bioyond_order_ids",
|
||||
key="order_id",
|
||||
data_type="bioyond_order_id",
|
||||
label="实验ID",
|
||||
data_key="order_ids",
|
||||
data_key="order_id",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
ActionOutputHandle(
|
||||
key="order_code",
|
||||
data_type="bioyond_order_code",
|
||||
label="订单编号",
|
||||
data_key="order_code",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
ActionOutputHandle(
|
||||
key="order_name",
|
||||
data_type="bioyond_order_name",
|
||||
label="订单名称",
|
||||
data_key="order_name",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
ActionOutputHandle(
|
||||
key="target_device",
|
||||
data_type="device_id",
|
||||
label="目标设备",
|
||||
data_key="target_device",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
ActionOutputHandle(
|
||||
# TEMP frontend-compat key: material/resource name.
|
||||
# TEMP frontend-compat key: material/resource name display (renderer compat).
|
||||
key="resource",
|
||||
data_type="resource",
|
||||
label="待装载物料",
|
||||
@@ -592,6 +575,7 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
"success": self._create_result_success(parsed_result, order_ids, material_records),
|
||||
"order_code": resolved_order_code,
|
||||
"order_name": resolved_order_name,
|
||||
"order_id": order_ids[0] if order_ids else "",
|
||||
"order_ids": order_ids,
|
||||
"target_device": target_device,
|
||||
"workflow": workflow,
|
||||
@@ -657,7 +641,6 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
node_type=NodeType.MANUAL_CONFIRM,
|
||||
placeholder_keys={
|
||||
"resource": "unilabos_resources",
|
||||
"target_device": "unilabos_devices",
|
||||
"mount_resource": "unilabos_resources",
|
||||
"assignee_user_ids": "unilabos_manual_confirm",
|
||||
},
|
||||
@@ -670,14 +653,7 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
description="请核对并装载实验物料;勾选装载确认后方可启动调度",
|
||||
handles=[
|
||||
ActionInputHandle(
|
||||
key="target_device",
|
||||
data_type="device_id",
|
||||
label="目标设备",
|
||||
data_key="target_device",
|
||||
data_source=DataSource.HANDLE,
|
||||
io_type="source",
|
||||
),
|
||||
ActionInputHandle(
|
||||
# TEMP frontend-compat key: material/resource name (renderer compat).
|
||||
key="resource",
|
||||
data_type="resource",
|
||||
label="待装载物料",
|
||||
@@ -705,8 +681,8 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
),
|
||||
# Order metadata for scheduler start.
|
||||
ActionInputHandle(
|
||||
key="order_ids", data_type="bioyond_order_ids",
|
||||
label="实验ID", data_key="order_ids",
|
||||
key="order_id", data_type="bioyond_order_id",
|
||||
label="实验ID", data_key="order_id",
|
||||
data_source=DataSource.HANDLE,
|
||||
io_type="source",
|
||||
),
|
||||
@@ -714,23 +690,29 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
)
|
||||
def start_experiment(
|
||||
self,
|
||||
target_device: DeviceSlot = "",
|
||||
resource: Optional[List[ResourceSlot]] = None,
|
||||
coin_cell_code: Optional[List[str]] = None,
|
||||
mount_resource: Optional[List[ResourceSlot]] = None,
|
||||
submit_experiment_result: Optional[Dict[str, Any]] = None,
|
||||
order_id: str = "",
|
||||
order_ids: Optional[List[str]] = None,
|
||||
materials_loaded: bool = False,
|
||||
api_host: str = "",
|
||||
api_key: str = "",
|
||||
ready_signal: str = "READY",
|
||||
timeout_seconds: int = 3600,
|
||||
assignee_user_ids: Optional[List[str]] = None,
|
||||
**kwargs: Any,
|
||||
) -> Dict[str, Any]:
|
||||
"""Guided manual-load checkpoint that gates ``rpc.scheduler_start()``."""
|
||||
del target_device, timeout_seconds, assignee_user_ids, kwargs
|
||||
"""Guided manual-load checkpoint that gates ``rpc.scheduler_start()``.
|
||||
|
||||
Args:
|
||||
order_id: 上游 ``submit_experiment_1`` 创建的订单 ID(可选;若上游连接则自动传入)。
|
||||
materials_loaded: 操作员勾选确认物料已装载。未勾选且存在物料显示则阻断启动。
|
||||
timeout_seconds: 超时时间(秒,框架参数)。
|
||||
assignee_user_ids: 分配用户 ID 列表(框架参数)。
|
||||
"""
|
||||
resource = kwargs.get("resource")
|
||||
coin_cell_code = kwargs.get("coin_cell_code")
|
||||
mount_resource = kwargs.get("mount_resource")
|
||||
order_ids = kwargs.get("order_ids")
|
||||
submit_experiment_result = kwargs.get("submit_experiment_result")
|
||||
api_host = self._kwarg_text(kwargs, "api_host")
|
||||
api_key = self._kwarg_text(kwargs, "api_key")
|
||||
ready_signal = self._kwarg_text(kwargs, "ready_signal") or DEFAULT_READY_SIGNAL
|
||||
del timeout_seconds, assignee_user_ids
|
||||
self._update_runtime_api_config(api_host=api_host, api_key=api_key)
|
||||
self._require_ready_signal(ready_signal)
|
||||
|
||||
@@ -768,6 +750,120 @@ class BioyondSirnaStation(BioyondWorkstation):
|
||||
"confirmation_message": "调度器启动成功" if result == 1 else "调度器启动失败,请检查 LIMS 状态",
|
||||
})
|
||||
|
||||
@action(
|
||||
always_free=True,
|
||||
node_type=NodeType.MANUAL_CONFIRM,
|
||||
placeholder_keys={"assignee_user_ids": "unilabos_manual_confirm"},
|
||||
goal_default={
|
||||
"filter_text": "",
|
||||
"status": "",
|
||||
"latest_only": True,
|
||||
"max_results": 20,
|
||||
"timeout_seconds": 3600,
|
||||
"assignee_user_ids": [],
|
||||
},
|
||||
feedback_interval=300,
|
||||
description="只读查询 Bioyond LIMS 订单列表,可作为下游节点的 order_id 来源",
|
||||
handles=[
|
||||
ActionOutputHandle(
|
||||
key="order_id",
|
||||
data_type="bioyond_order_id",
|
||||
label="实验ID",
|
||||
data_key="order_id",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
ActionOutputHandle(
|
||||
key="order_ids",
|
||||
data_type="bioyond_order_ids",
|
||||
label="实验ID列表",
|
||||
data_key="order_ids",
|
||||
data_source=DataSource.EXECUTOR,
|
||||
),
|
||||
],
|
||||
)
|
||||
def get_order_list(
|
||||
self,
|
||||
filter_text: str = "",
|
||||
status: str = "",
|
||||
latest_only: bool = True,
|
||||
max_results: int = 20,
|
||||
timeout_seconds: int = 3600,
|
||||
assignee_user_ids: Optional[List[str]] = None,
|
||||
**kwargs: Any,
|
||||
) -> Dict[str, Any]:
|
||||
"""只读查询 Bioyond LIMS 订单列表。
|
||||
|
||||
``api_host`` / ``api_key`` 隐藏不再作为前端可见参数;缺失会沿用现有 RPC 配置错误。
|
||||
|
||||
Args:
|
||||
filter_text: 订单编号 / 名称模糊匹配字符串,对应 LIMS ``order_query.filter``。
|
||||
status: 订单状态字段过滤值(透传给 ``order_query.status``,留空表示不过滤)。
|
||||
latest_only: 默认 ``True``,仅返回最新(创建时间最大)的一条订单作为 ``order_id``。
|
||||
max_results: 一次返回的最大订单条数(透传给 ``pageCount``,默认 20)。
|
||||
timeout_seconds: 超时时间(秒,框架参数)。
|
||||
assignee_user_ids: 分配用户 ID 列表(框架参数)。
|
||||
|
||||
Returns:
|
||||
``{"success": bool, "orders": [...], "order_id": str, "order_ids": [...], "query": {...}}``。
|
||||
"""
|
||||
del timeout_seconds, assignee_user_ids, kwargs
|
||||
try:
|
||||
normalized_max = int(max_results)
|
||||
except (TypeError, ValueError):
|
||||
normalized_max = 20
|
||||
if normalized_max <= 0:
|
||||
normalized_max = 20
|
||||
rpc = self._require_hardware_interface("order_query")
|
||||
query_payload = {
|
||||
"timeType": "",
|
||||
"beginTime": None,
|
||||
"endTime": None,
|
||||
"status": str(status or ""),
|
||||
"filter": str(filter_text or ""),
|
||||
"skipCount": 0,
|
||||
"pageCount": normalized_max,
|
||||
"sorting": "creationTime desc",
|
||||
}
|
||||
logger.info(
|
||||
"正在查询 Bioyond LIMS 订单列表 filter=%r status=%r latest_only=%s",
|
||||
filter_text,
|
||||
status,
|
||||
latest_only,
|
||||
)
|
||||
raw_result = rpc.order_query(json.dumps(query_payload, ensure_ascii=False))
|
||||
items = self._order_items(raw_result)
|
||||
|
||||
orders: List[Dict[str, Any]] = []
|
||||
for item in items:
|
||||
order_id = str(item.get("id") or "")
|
||||
if not order_id:
|
||||
continue
|
||||
orders.append({
|
||||
"order_id": order_id,
|
||||
"order_code": str(item.get("orderCode") or ""),
|
||||
"order_name": str(item.get("name") or item.get("orderName") or ""),
|
||||
"status": str(item.get("status") or item.get("statusName") or ""),
|
||||
"created_at": str(item.get("creationTime") or item.get("createTime") or ""),
|
||||
"raw": item,
|
||||
})
|
||||
|
||||
order_ids = [order["order_id"] for order in orders]
|
||||
if latest_only and orders:
|
||||
chosen = orders[0]
|
||||
order_id_value = chosen["order_id"]
|
||||
elif len(order_ids) == 1:
|
||||
order_id_value = order_ids[0]
|
||||
else:
|
||||
order_id_value = ""
|
||||
|
||||
return {
|
||||
"success": bool(orders),
|
||||
"orders": orders,
|
||||
"order_id": order_id_value,
|
||||
"order_ids": order_ids,
|
||||
"query": query_payload,
|
||||
}
|
||||
|
||||
def _require_hardware_interface(self, method_name: str) -> Any:
|
||||
rpc = getattr(self, "hardware_interface", None)
|
||||
if rpc is None:
|
||||
|
||||
Reference in New Issue
Block a user