mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-12 02:35:11 +00:00
Compare commits
8 Commits
e92d933968
...
6ad0157b50
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ad0157b50 | ||
|
|
55b678cd37 | ||
|
|
8101a22a0f | ||
|
|
667138baac | ||
|
|
01adf7ca92 | ||
|
|
f606062696 | ||
|
|
67d1c4acce | ||
|
|
7206e42bf1 |
@@ -24,13 +24,13 @@
|
||||
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
||||
},
|
||||
"material_type_mappings": {
|
||||
"烧杯": ["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"]
|
||||
"烧杯": ["YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"],
|
||||
"试剂瓶": ["YB_1BottleCarrier", ""],
|
||||
"样品板": ["YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"],
|
||||
"分装板": ["YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"],
|
||||
"样品瓶": ["YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"],
|
||||
"90%分装小瓶": ["YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"],
|
||||
"10%分装小瓶": ["YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"]
|
||||
}
|
||||
},
|
||||
"deck": {
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
||||
},
|
||||
"material_type_mappings": {
|
||||
"烧杯": "BIOYOND_PolymerStation_1FlaskCarrier",
|
||||
"试剂瓶": "BIOYOND_PolymerStation_1BottleCarrier",
|
||||
"样品板": "BIOYOND_PolymerStation_6VialCarrier"
|
||||
"烧杯": "YB_1FlaskCarrier",
|
||||
"试剂瓶": "YB_1BottleCarrier",
|
||||
"样品板": "YB_6VialCarrier"
|
||||
}
|
||||
},
|
||||
"deck": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from unilabos.resources.bioyond.bottle_carriers import BIOYOND_Electrolyte_6VialCarrier, BIOYOND_Electrolyte_1BottleCarrier
|
||||
from unilabos.resources.bioyond.bottles import BIOYOND_PolymerStation_Solid_Vial, BIOYOND_PolymerStation_Solution_Beaker, BIOYOND_PolymerStation_Reagent_Bottle
|
||||
from unilabos.resources.bioyond.bottles import YB_Solid_Vial, YB_Solution_Beaker, YB_Reagent_Bottle
|
||||
|
||||
|
||||
def test_bottle_carrier() -> "BottleCarrier":
|
||||
@@ -16,9 +16,9 @@ def test_bottle_carrier() -> "BottleCarrier":
|
||||
print(f"1烧杯载架: {beaker_carrier.name}, 位置数: {len(beaker_carrier.sites)}")
|
||||
|
||||
# 创建瓶子和烧杯
|
||||
powder_bottle = BIOYOND_PolymerStation_Solid_Vial("powder_bottle_01")
|
||||
solution_beaker = BIOYOND_PolymerStation_Solution_Beaker("solution_beaker_01")
|
||||
reagent_bottle = BIOYOND_PolymerStation_Reagent_Bottle("reagent_bottle_01")
|
||||
powder_bottle = YB_Solid_Vial("powder_bottle_01")
|
||||
solution_beaker = YB_Solution_Beaker("solution_beaker_01")
|
||||
reagent_bottle = YB_Reagent_Bottle("reagent_bottle_01")
|
||||
|
||||
print(f"\n创建的物料:")
|
||||
print(f"粉末瓶: {powder_bottle.name} - {powder_bottle.diameter}mm x {powder_bottle.height}mm, {powder_bottle.max_volume}μL")
|
||||
|
||||
@@ -12,13 +12,13 @@ lab_registry.setup()
|
||||
|
||||
|
||||
type_mapping = {
|
||||
"烧杯": ("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"),
|
||||
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||
"10%分装小瓶": ("YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ lab_registry.setup()
|
||||
|
||||
|
||||
type_mapping = {
|
||||
"烧杯": ("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"),
|
||||
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||
"10%分装小瓶": ("YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,14 +9,13 @@ import time
|
||||
from datetime import datetime, timedelta
|
||||
import re
|
||||
import threading
|
||||
import os
|
||||
import socket
|
||||
import json
|
||||
|
||||
from urllib3 import response
|
||||
from unilabos.devices.workstation.workstation_base import WorkstationBase
|
||||
from unilabos.devices.workstation.bioyond_studio.station import BioyondWorkstation, BioyondResourceSynchronizer
|
||||
from unilabos.devices.workstation.bioyond_studio.config import (
|
||||
BIOYOND_FULL_CONFIG, WORKFLOW_MAPPINGS, MATERIAL_TYPE_MAPPINGS, WAREHOUSE_MAPPING
|
||||
API_CONFIG, MATERIAL_TYPE_MAPPINGS, WAREHOUSE_MAPPING, SOLID_LIQUID_MAPPINGS
|
||||
)
|
||||
from unilabos.devices.workstation.workstation_http_service import WorkstationHTTPService
|
||||
from unilabos.utils.log import logger
|
||||
@@ -43,32 +42,52 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
*args, **kwargs,
|
||||
):
|
||||
|
||||
# 使用统一配置,支持自定义覆盖
|
||||
self.bioyond_config = bioyond_config or {
|
||||
**BIOYOND_FULL_CONFIG, # 从 config.py 加载完整配置
|
||||
"workflow_mappings": WORKFLOW_MAPPINGS,
|
||||
# 使用统一配置,支持自定义覆盖, 从 config.py 加载完整配置
|
||||
self.bioyond_config = bioyond_config or {
|
||||
**API_CONFIG,
|
||||
"material_type_mappings": MATERIAL_TYPE_MAPPINGS,
|
||||
"warehouse_mapping": WAREHOUSE_MAPPING
|
||||
}
|
||||
}
|
||||
|
||||
# "material_type_mappings": MATERIAL_TYPE_MAPPINGS
|
||||
# "warehouse_mapping": WAREHOUSE_MAPPING
|
||||
|
||||
print(self.bioyond_config)
|
||||
self.debug_mode = self.bioyond_config["debug_mode"]
|
||||
self.http_service_started = False
|
||||
self.http_service_started = self.debug_mode
|
||||
deck = kwargs.pop("deck", None)
|
||||
self.device_id = kwargs.pop("device_id", "bioyond_cell_workstation")
|
||||
super().__init__(bioyond_config=self.bioyond_config, deck=deck, station_resource=station_resource, *args, **kwargs)
|
||||
# 步骤通量任务通知铃
|
||||
self._pending_events: dict[str, threading.Event] = {}
|
||||
self.update_push_ip() #直接修改奔耀端的报送ip地址
|
||||
logger.info("已更新奔耀端推送 IP 地址")
|
||||
|
||||
# 启动 HTTP 服务线程
|
||||
t = threading.Thread(target=self._start_http_service, daemon=True, name="unilab_http")
|
||||
t.start()
|
||||
logger.info("HTTP 服务线程已启动")
|
||||
# 等到任务报送成功
|
||||
self.order_finish_event = threading.Event()
|
||||
self.last_order_status = None
|
||||
self.last_order_code = None
|
||||
logger.info(f"Bioyond工作站初始化完成 (debug_mode={self.debug_mode})")
|
||||
|
||||
# 实例化并在后台线程启动 HTTP 报送服务
|
||||
self.order_status = {} # 记录任务完成情况,用于接受bioyond post信息和反馈信息,尤其用于硬件查询和物料信息变化
|
||||
def _start_http_service(self):
|
||||
"""启动 HTTP 服务"""
|
||||
host = self.bioyond_config.get("HTTP_host", "")
|
||||
port = self.bioyond_config.get("HTTP_port", None)
|
||||
try:
|
||||
logger.info("准备开始unilab_HTTP后台线程")
|
||||
t = threading.Thread(target=self._start_http_service, daemon=True, name="unilab_http")
|
||||
t.start()
|
||||
self.service = WorkstationHTTPService(self, host=host, port=port)
|
||||
self.service.start()
|
||||
self.http_service_started = True
|
||||
logger.info(f"WorkstationHTTPService 成功启动: {host}:{port}")
|
||||
while True:
|
||||
time.sleep(1) #一直挂着,直到进程退出
|
||||
except Exception as e:
|
||||
logger.error(f"unilab-HTTP后台线程启动失败: {e}")
|
||||
self.http_service_started = False
|
||||
logger.error(f"启动 WorkstationHTTPService 失败: {e}", exc_info=True)
|
||||
|
||||
# http报送服务
|
||||
|
||||
# http报送服务,返回数据部分
|
||||
def process_step_finish_report(self, report_request):
|
||||
stepId = report_request.data.get("stepId")
|
||||
logger.info(f"步骤完成: stepId: {stepId}, stepName:{report_request.data.get('stepName')}")
|
||||
@@ -82,147 +101,65 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
order_code = report_request.data.get("orderCode")
|
||||
status = report_request.data.get("status")
|
||||
logger.info(f"report_request: {report_request}")
|
||||
|
||||
logger.info(f"任务完成: {order_code}, status={status}")
|
||||
|
||||
# 记录订单状态码
|
||||
if order_code:
|
||||
self.order_status[order_code] = status
|
||||
|
||||
self._set_pending_event(order_code)
|
||||
|
||||
# 保存完整报文
|
||||
self.last_order_report = report_request.data
|
||||
# 如果是当前等待的订单,触发事件
|
||||
if self.last_order_code == order_code:
|
||||
self.order_finish_event.set()
|
||||
|
||||
return {"status": "received"}
|
||||
|
||||
def _set_pending_event(self, taskname: Optional[str]) -> None:
|
||||
if not taskname:
|
||||
return
|
||||
event = self._pending_events.get(taskname)
|
||||
if event is None:
|
||||
event = threading.Event()
|
||||
self._pending_events[taskname] = event
|
||||
event.set()
|
||||
|
||||
def _wait_for_order_completion(self, order_code: Optional[str], timeout: int = 600) -> bool:
|
||||
def wait_for_order_finish(self, order_code: str, timeout: int = 1800) -> Dict[str, Any]:
|
||||
"""
|
||||
等待指定 orderCode 的 /report/order_finish 报送。
|
||||
Args:
|
||||
order_code: 任务编号
|
||||
timeout: 超时时间(秒)
|
||||
Returns:
|
||||
完整的报送数据 + 状态判断结果
|
||||
"""
|
||||
if not order_code:
|
||||
logger.warning("无法等待任务完成:order_code 为空")
|
||||
return False
|
||||
event = self._pending_events.get(order_code)
|
||||
if event is None:
|
||||
event = threading.Event()
|
||||
self._pending_events[order_code] = event
|
||||
elif event.is_set():
|
||||
logger.info(f"任务 {order_code} 在等待之前已完成")
|
||||
self._pending_events.pop(order_code, None)
|
||||
return True
|
||||
logger.info(f"等待任务 {order_code} 完成 (timeout={timeout}s)")
|
||||
finished = event.wait(timeout)
|
||||
if not finished:
|
||||
logger.warning(f"等待任务 {order_code} 完成超时({timeout}s)")
|
||||
self._pending_events.pop(order_code, None)
|
||||
return finished
|
||||
logger.error("wait_for_order_finish() 被调用,但 order_code 为空!")
|
||||
return {"status": "error", "message": "empty order_code"}
|
||||
|
||||
def _wait_for_response_orders(self, response: Dict[str, Any], context: str, timeout: int = 600) -> None:
|
||||
order_codes = self._extract_order_codes(response)
|
||||
if not order_codes:
|
||||
logger.warning(f"{context} 响应中未找到 orderCode,无法跟踪任务完成")
|
||||
return
|
||||
for code in order_codes:
|
||||
finished = self._wait_for_order_completion(code, timeout=timeout)
|
||||
if finished:
|
||||
# 检查订单返回码是否为30(正常完成)
|
||||
status = self.order_status.get(code)
|
||||
if status == 30 or status == "30":
|
||||
logger.info(f"订单 {code} 成功完成,状态码: {status}")
|
||||
else:
|
||||
logger.warning(f"订单 {code} 完成但状态码异常: {status} (期望: 30, -11=异常停止, -12=人工停止)")
|
||||
# 清理状态记录
|
||||
self.order_status.pop(code, None)
|
||||
else:
|
||||
logger.error(f"订单 {code} 等待超时,未收到完成通知")
|
||||
self.last_order_code = order_code
|
||||
self.last_order_report = None
|
||||
self.order_finish_event.clear()
|
||||
|
||||
@staticmethod
|
||||
def _extract_order_codes(response: Dict[str, Any]) -> List[str]:
|
||||
order_codes: List[str] = []
|
||||
if not isinstance(response, dict):
|
||||
return order_codes
|
||||
data = response.get("data")
|
||||
keys = ["orderCode", "order_code", "orderId", "order_id"]
|
||||
if isinstance(data, dict):
|
||||
for key in keys:
|
||||
if key in data and data[key]:
|
||||
order_codes.append(str(data[key]))
|
||||
if not order_codes and "orders" in data and isinstance(data["orders"], list):
|
||||
for order in data["orders"]:
|
||||
if isinstance(order, dict):
|
||||
for key in keys:
|
||||
if key in order and order[key]:
|
||||
order_codes.append(str(order[key]))
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
if isinstance(item, dict):
|
||||
for key in keys:
|
||||
if key in item and item[key]:
|
||||
order_codes.append(str(item[key]))
|
||||
elif isinstance(data, str):
|
||||
if data:
|
||||
order_codes.append(data)
|
||||
meta = response.get("orderCode")
|
||||
if meta:
|
||||
order_codes.append(str(meta))
|
||||
# 去重
|
||||
seen = set()
|
||||
unique_codes: List[str] = []
|
||||
for code in order_codes:
|
||||
if code not in seen:
|
||||
seen.add(code)
|
||||
unique_codes.append(code)
|
||||
return unique_codes
|
||||
logger.info(f"等待任务完成报送: orderCode={order_code} (timeout={timeout}s)")
|
||||
|
||||
if not self.order_finish_event.wait(timeout=timeout):
|
||||
logger.error(f"等待任务超时: orderCode={order_code}")
|
||||
return {"status": "timeout", "orderCode": order_code}
|
||||
|
||||
def _start_http_service(self, host: Optional[str] = None, port: Optional[int] = None) -> None:
|
||||
host = host or self.bioyond_config.get("HTTP_host", "")
|
||||
port = port or self.bioyond_config.get("HTTP_port", )
|
||||
# 报送数据匹配验证
|
||||
report = self.last_order_report or {}
|
||||
report_code = report.get("orderCode")
|
||||
status = str(report.get("status", ""))
|
||||
|
||||
if report_code != order_code:
|
||||
logger.warning(f"收到的报送 orderCode 不匹配: {report_code} ≠ {order_code}")
|
||||
return {"status": "mismatch", "report": report}
|
||||
|
||||
if status == "30":
|
||||
logger.info(f"任务成功完成 (orderCode={order_code})")
|
||||
return {"status": "success", "report": report}
|
||||
elif status == "-11":
|
||||
logger.error(f"任务异常停止 (orderCode={order_code})")
|
||||
return {"status": "abnormal_stop", "report": report}
|
||||
elif status == "-12":
|
||||
logger.warning(f"任务人工停止 (orderCode={order_code})")
|
||||
return {"status": "manual_stop", "report": report}
|
||||
else:
|
||||
logger.warning(f"任务未知状态 ({status}) (orderCode={order_code})")
|
||||
return {"status": f"unknown_{status}", "report": report}
|
||||
|
||||
logger.info("准备开始unilab_HTTP服务")
|
||||
try:
|
||||
self.service = WorkstationHTTPService(self, host=host, port=port)
|
||||
logger.info("WorkstationHTTPService 实例化完成")
|
||||
self.service.start()
|
||||
self.http_service_started = True
|
||||
logger.info(f"WorkstationHTTPService成功启动: {host}:{port}")
|
||||
|
||||
# 启动成功后,上报本机推送地址(3.36)
|
||||
try:
|
||||
# 优先使用配置中的 report_ip
|
||||
report_ip = self.bioyond_config.get("report_ip", "").strip()
|
||||
|
||||
# 如果配置中没有指定 report_ip,且监听地址是 0.0.0.0,则自动检测
|
||||
if not report_ip and host in ("0.0.0.0", ""):
|
||||
# 从 Bioyond 配置中提取服务器地址
|
||||
bioyond_server = self.bioyond_config.get("base_url", "")
|
||||
if bioyond_server:
|
||||
import urllib.parse
|
||||
parsed = urllib.parse.urlparse(bioyond_server)
|
||||
|
||||
elif not report_ip:
|
||||
# 如果没有配置 report_ip,使用监听地址
|
||||
report_ip = host
|
||||
|
||||
r = self.update_push_ip(report_ip, port)
|
||||
logger.info(f"向 Bioyond 报送推送地址: {report_ip}:{port}, 结果: {r}")
|
||||
except Exception as e:
|
||||
logger.warning(f"调用更新推送IP接口失败: {e}")
|
||||
|
||||
#一直挂着,直到进程退出
|
||||
while True:
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
self.http_service_started = False # 调试用
|
||||
logger.error(f"启动WorkstationHTTPService失败: {e}", exc_info=True)
|
||||
|
||||
# -------------------- 基础HTTP封装 --------------------
|
||||
def _url(self, path: str) -> str:
|
||||
|
||||
return f"{self.bioyond_config['base_url'].rstrip('/')}/{path.lstrip('/')}"
|
||||
return f"{self.bioyond_config['api_host'].rstrip('/')}/{path.lstrip('/')}"
|
||||
|
||||
def _post_lims(self, path: str, data: Optional[Any] = None) -> Dict[str, Any]:
|
||||
"""LIMS API:大多数接口用 {apiKey/requestTime,data} 包装"""
|
||||
@@ -236,9 +173,11 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
if self.debug_mode:
|
||||
# 模拟返回,不发真实请求
|
||||
logger.info(f"[DEBUG] POST {path} with payload={payload}")
|
||||
|
||||
return {"debug": True, "url": self._url(path), "payload": payload, "status": "ok"}
|
||||
|
||||
try:
|
||||
logger.info(json.dumps(payload, ensure_ascii=False))
|
||||
response = requests.post(
|
||||
self._url(path),
|
||||
json=payload,
|
||||
@@ -248,7 +187,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
logger.info(f"{self.bioyond_config['base_url'].rstrip('/')}/{path.lstrip('/')}")
|
||||
logger.info(f"{self.bioyond_config['api_host'].rstrip('/')}/{path.lstrip('/')}")
|
||||
logger.error(f"POST {path} 失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
@@ -263,7 +202,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
|
||||
if self.debug_mode:
|
||||
logger.info(f"[DEBUG] PUT {path} with payload={payload}")
|
||||
return {"debug": True, "url": self._url(path), "payload": payload, "status": "ok"}
|
||||
return {"debug_mode": True, "url": self._url(path), "payload": payload, "status": "ok"}
|
||||
|
||||
try:
|
||||
response = requests.put(
|
||||
@@ -275,7 +214,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
logger.info(f"{self.bioyond_config['base_url'].rstrip('/')}/{path.lstrip('/')}")
|
||||
logger.info(f"{self.bioyond_config['api_host'].rstrip('/')}/{path.lstrip('/')}")
|
||||
logger.error(f"PUT {path} 失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
@@ -310,11 +249,10 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
return self._post_lims("/api/lims/storage/batch-inbound", items)
|
||||
|
||||
|
||||
|
||||
def auto_feeding4to3(
|
||||
self,
|
||||
# ★ 修改点:默认模板路径
|
||||
xlsx_path: Optional[str] = "/Users/calvincao/Desktop/work/uni-lab-all/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/样品导入模板.xlsx",
|
||||
xlsx_path: Optional[str] = "unilabos\\devices\\workstation\\bioyond_studio\\bioyond_cell\\样品导入模板.xlsx",
|
||||
# ---------------- WH4 - 加样头面 (Z=1, 12个点位) ----------------
|
||||
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,
|
||||
@@ -443,9 +381,15 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
return {"code": 0, "message": "no valid items", "data": []}
|
||||
logger.info(items)
|
||||
response = self._post_lims("/api/lims/order/auto-feeding4to3", items)
|
||||
self._wait_for_response_orders(response, "auto_feeding4to3")
|
||||
return response
|
||||
|
||||
# 等待任务报送成功
|
||||
order_code = response.get("data", {}).get("orderCode")
|
||||
if not order_code:
|
||||
logger.error("上料任务未返回有效 orderCode!")
|
||||
return response
|
||||
# 等待完成报送
|
||||
result = self.wait_for_order_finish(order_code)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
@@ -681,31 +625,17 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
}
|
||||
orders.append(order_data)
|
||||
|
||||
# print(orders)
|
||||
while True:
|
||||
time.sleep(5)
|
||||
response = self._post_lims("/api/lims/order/orders", orders)
|
||||
if response.get("data", []):
|
||||
break
|
||||
logger.info(f"等待配液实验创建完成")
|
||||
|
||||
|
||||
|
||||
# self.order_status[response["data"]["orderCode"]] = "running"
|
||||
|
||||
# while True:
|
||||
# time.sleep(5)
|
||||
# if self.order_status.get(response["data"]["orderCode"], None) == "finished":
|
||||
# logger.info(f"配液实验已完成 ,即将执行 3-2-1 转运")
|
||||
# break
|
||||
# logger.info(f"等待配液实验完成")
|
||||
|
||||
# self.transfer_3_to_2_to_1()
|
||||
# self.wait_for_transfer_task()
|
||||
# logger.info(f"3-2-1 转运完成,返回结果")
|
||||
# return r321
|
||||
self._wait_for_response_orders(response, "create_orders", timeout=1800)
|
||||
return response
|
||||
response = self._post_lims("/api/lims/order/orders", orders)
|
||||
print(response)
|
||||
# 等待任务报送成功
|
||||
order_code = response.get("data", {}).get("orderCode")
|
||||
if not order_code:
|
||||
logger.error("上料任务未返回有效 orderCode!")
|
||||
return response
|
||||
# 等待完成报送
|
||||
result = self.wait_for_order_finish(order_code)
|
||||
return result
|
||||
|
||||
# 2.7 启动调度
|
||||
def scheduler_start(self) -> Dict[str, Any]:
|
||||
@@ -726,6 +656,13 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
请求体只包含 apiKey 和 requestTime
|
||||
"""
|
||||
return self._post_lims("/api/lims/scheduler/continue")
|
||||
def scheduler_reset(self) -> Dict[str, Any]:
|
||||
"""
|
||||
复位调度 (2.11)
|
||||
请求体只包含 apiKey 和 requestTime
|
||||
"""
|
||||
return self._post_lims("/api/lims/scheduler/reset")
|
||||
|
||||
|
||||
# 2.24 物料变更推送
|
||||
def report_material_change(self, material_obj: Dict[str, Any]) -> Dict[str, Any]:
|
||||
@@ -744,7 +681,16 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
}
|
||||
if source_wh_id:
|
||||
payload["sourceWHID"] = source_wh_id
|
||||
return self._post_lims("/api/lims/order/transfer-task3To2To1", payload)
|
||||
|
||||
response = self._post_lims("/api/lims/order/transfer-task3To2To1", payload)
|
||||
# 等待任务报送成功
|
||||
order_code = response.get("data", {}).get("orderCode")
|
||||
if not order_code:
|
||||
logger.error("上料任务未返回有效 orderCode!")
|
||||
return response
|
||||
# 等待完成报送
|
||||
result = self.wait_for_order_finish(order_code)
|
||||
return result
|
||||
|
||||
# 3.35 1→2 物料转运
|
||||
def transfer_1_to_2(self) -> Dict[str, Any]:
|
||||
@@ -753,7 +699,15 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
URL: /api/lims/order/transfer-task1To2
|
||||
只需要 apiKey 和 requestTime
|
||||
"""
|
||||
return self._post_lims("/api/lims/order/transfer-task1To2")
|
||||
response = self._post_lims("/api/lims/order/transfer-task1To2")
|
||||
# 等待任务报送成功
|
||||
order_code = response.get("data", {}).get("orderCode")
|
||||
if not order_code:
|
||||
logger.error("上料任务未返回有效 orderCode!")
|
||||
return response
|
||||
# 等待完成报送
|
||||
result = self.wait_for_order_finish(order_code)
|
||||
return result
|
||||
|
||||
# 2.5 批量查询实验报告(post过滤关键字查询)
|
||||
def order_list_v2(self,
|
||||
@@ -825,28 +779,23 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
logger.warning("超时未找到成功的物料转移任务")
|
||||
return False
|
||||
|
||||
def create_solid_materials(self, material_names: List[str], type_id: str = "3a190ca0-b2f6-9aeb-8067-547e72c11469") -> List[Dict[str, Any]]:
|
||||
def create_materials(self, mappings: Dict[str, Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
批量创建固体物料
|
||||
|
||||
Args:
|
||||
material_names: 物料名称列表
|
||||
type_id: 物料类型ID(默认为固体物料类型)
|
||||
|
||||
Returns:
|
||||
创建的物料列表,每个元素包含物料信息和ID
|
||||
将 SOLID_LIQUID_MAPPINGS 中的所有物料逐个 POST 到 /api/lims/storage/material
|
||||
"""
|
||||
created_materials = []
|
||||
total = len(material_names)
|
||||
|
||||
for i, name in enumerate(material_names, 1):
|
||||
# 根据接口文档构建完整的请求体
|
||||
material_data = {
|
||||
"typeId": type_id,
|
||||
"name": name,
|
||||
"unit": "g", # 添加单位
|
||||
"quantity": 1, # 添加数量(默认1)
|
||||
"parameters": "" # 参数字段(空字符串表示无参数)
|
||||
results = []
|
||||
|
||||
for name, data in mappings.items():
|
||||
data = {
|
||||
"typeId": data["typeId"],
|
||||
"code": data.get("code", ""),
|
||||
"barCode": data.get("barCode", ""),
|
||||
"name": data["name"],
|
||||
"unit": data.get("unit", "g"),
|
||||
"parameters": data.get("parameters", ""),
|
||||
"quantity": data.get("quantity", ""),
|
||||
"warningQuantity": data.get("warningQuantity", ""),
|
||||
"details": data.get("details", [])
|
||||
}
|
||||
|
||||
logger.info(f"正在创建第 {i}/{total} 个固体物料: {name}")
|
||||
@@ -1019,20 +968,24 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
||||
|
||||
if __name__ == "__main__":
|
||||
ws = BioyondCellWorkstation()
|
||||
logger.info(ws.scheduler_start())
|
||||
logger.info(ws.scheduler_stop())
|
||||
|
||||
|
||||
results = ws.create_materials(SOLID_LIQUID_MAPPINGS)
|
||||
for r in results:
|
||||
logger.info(r)
|
||||
# 从CSV文件读取物料列表并批量创建入库
|
||||
result = ws.create_and_inbound_materials()
|
||||
|
||||
# 继续后续流程
|
||||
logger.info(ws.auto_feeding4to3()) #搬运物料到3号箱
|
||||
# 使用正斜杠或 Path 对象来指定文件路径
|
||||
excel_path = Path("unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx")
|
||||
logger.info(ws.create_orders(excel_path))
|
||||
logger.info(ws.transfer_3_to_2_to_1())
|
||||
|
||||
logger.info(ws.transfer_1_to_2())
|
||||
# logger.info(ws.auto_feeding4to3()) #搬运物料到3号箱
|
||||
# # 使用正斜杠或 Path 对象来指定文件路径
|
||||
# excel_path = Path("unilabos\\devices\\workstation\\bioyond_studio\\bioyond_cell\\2025092701.xlsx")
|
||||
# logger.info(ws.create_orders(excel_path))
|
||||
# logger.info(ws.transfer_3_to_2_to_1())
|
||||
|
||||
# logger.info(ws.transfer_1_to_2())
|
||||
# logger.info(ws.scheduler_start())
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
@@ -5,17 +5,13 @@
|
||||
import os
|
||||
|
||||
# ==================== API 基础配置 ====================
|
||||
# 支持通过环境变量覆盖默认值
|
||||
API_CONFIG = {
|
||||
"api_key": os.getenv("BIOYOND_API_KEY", "8A819E5C"),
|
||||
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.11.219:44388"),
|
||||
}
|
||||
|
||||
|
||||
# ==================== 完整的 Bioyond 配置 ====================
|
||||
# BioyondCellWorkstation 默认配置(包含所有必需参数)
|
||||
BIOYOND_FULL_CONFIG = {
|
||||
API_CONFIG = {
|
||||
# API 连接配置
|
||||
"base_url": os.getenv("BIOYOND_API_HOST", "http://172.16.11.219:44388"),
|
||||
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.11.219:44388"),
|
||||
"api_key": os.getenv("BIOYOND_API_KEY", "8A819E5C"),
|
||||
"timeout": int(os.getenv("BIOYOND_TIMEOUT", "30")),
|
||||
|
||||
@@ -25,97 +21,17 @@ BIOYOND_FULL_CONFIG = {
|
||||
# HTTP 服务配置
|
||||
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "0.0.0.0"), # HTTP服务监听地址(0.0.0.0 表示监听所有网络接口)
|
||||
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
|
||||
"report_ip": os.getenv("BIOYOND_REPORT_IP", "172.21.32.172"), # 报送给 Bioyond 的本机IP地址(留空则自动检测)
|
||||
"report_ip": os.getenv("BIOYOND_REPORT_IP", "172.21.32.22"), # 报送给 Bioyond 的本机IP地址(留空则自动检测)
|
||||
# 调试模式
|
||||
"debug_mode": os.getenv("BIOYOND_DEBUG_MODE", "False").lower() == "true",
|
||||
}
|
||||
|
||||
# 工作流映射配置
|
||||
WORKFLOW_MAPPINGS = {
|
||||
"reactor_taken_out": "",
|
||||
"reactor_taken_in": "",
|
||||
"Solid_feeding_vials": "",
|
||||
"Liquid_feeding_vials(non-titration)": "",
|
||||
"Liquid_feeding_solvents": "",
|
||||
"Liquid_feeding(titration)": "",
|
||||
"liquid_feeding_beaker": "",
|
||||
"Drip_back": "",
|
||||
}
|
||||
|
||||
# 工作流名称到DisplaySectionName的映射
|
||||
WORKFLOW_TO_SECTION_MAP = {
|
||||
'reactor_taken_in': '反应器放入',
|
||||
'liquid_feeding_beaker': '液体投料-烧杯',
|
||||
'Liquid_feeding_vials(non-titration)': '液体投料-小瓶(非滴定)',
|
||||
'Liquid_feeding_solvents': '液体投料-溶剂',
|
||||
'Solid_feeding_vials': '固体投料-小瓶',
|
||||
'Liquid_feeding(titration)': '液体投料-滴定',
|
||||
'reactor_taken_out': '反应器取出'
|
||||
"debug_mode": False,
|
||||
}
|
||||
|
||||
# 库位映射配置
|
||||
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"
|
||||
}
|
||||
},
|
||||
"粉末加样头堆栈": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19da56-1379-20c8-5886-f7c4fbcb5733",
|
||||
"A01": "3a19da56-1379-ff7c-1745-07e200b44ce2",
|
||||
"B01": "3a19da56-1379-2424-d751-fe6e94cef938",
|
||||
"C01": "3a19da56-1379-271c-03e3-6bdb590e395e",
|
||||
"D01": "3a19da56-1379-277f-2b1b-0d11f7cf92c6",
|
||||
@@ -136,65 +52,192 @@ WAREHOUSE_MAPPING = {
|
||||
"S01": "3a19da56-1379-f924-7f68-df1fa51489f4",
|
||||
"T01": "3a19da56-1379-ff7c-1745-07e200b44ce2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"配液站内试剂仓库": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19da43-57b5-294f-d663-154a1cc32270",
|
||||
"B01": "3a19da43-57b5-7394-5f49-54efe2c9bef2",
|
||||
"C01": "3a19da43-57b5-5e75-552f-8dbd0ad1075f",
|
||||
"A02": "3a19da43-57b5-8441-db94-b4d3875a4b6c",
|
||||
"B02": "3a19da43-57b5-3e41-c181-5119dddaf50c",
|
||||
"C02": "3a19da43-57b5-269b-282d-fba61fe8ce96",
|
||||
"A03": "3a19da43-57b5-7c1e-d02e-c40e8c33f8a1",
|
||||
"B03": "3a19da43-57b5-659f-621f-1dcf3f640363",
|
||||
"C03": "3a19da43-57b5-855a-6e71-f398e376dee1",
|
||||
}
|
||||
},
|
||||
"试剂替换仓库": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19da51-8f4e-30f3-ea08-4f8498e9b097",
|
||||
"B01": "3a19da51-8f4e-1da7-beb0-80a4a01e67a8",
|
||||
"C01": "3a19da51-8f4e-337d-2675-bfac46880b06",
|
||||
"D01": "3a19da51-8f4e-e514-b92c-9c44dc5e489d",
|
||||
"E01": "3a19da51-8f4e-22d1-dd5b-9774ddc80402",
|
||||
"F01": "3a19da51-8f4e-273a-4871-dff41c29bfd9",
|
||||
"G01": "3a19da51-8f4e-b32f-454f-74bc1a665653",
|
||||
"H01": "3a19da51-8f4e-8c93-68c9-0b4382320f59",
|
||||
"I01": "3a19da51-8f4e-360c-0149-291b47c6089b",
|
||||
"J01": "3a19da51-8f4e-4152-9bca-8d64df8c1af0"
|
||||
}
|
||||
},
|
||||
"自动堆栈-左": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19debc-84b5-4c1c-d3a1-26830cf273ff",
|
||||
"A02": "3a19debc-84b5-033b-b31f-6b87f7c2bf52",
|
||||
"B01": "3a19debc-84b5-3924-172f-719ab01b125c",
|
||||
"B02": "3a19debc-84b5-aad8-70c6-b8c6bb2d8750"
|
||||
}
|
||||
},
|
||||
"自动堆栈-右": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19debe-5200-7df2-1dd9-7d202f158864",
|
||||
"A02": "3a19debe-5200-573b-6120-8b51f50e1e50",
|
||||
"B01": "3a19debe-5200-7cd8-7666-851b0a97e309",
|
||||
"B02": "3a19debe-5200-e6d3-96a3-baa6e3d5e484"
|
||||
}
|
||||
},
|
||||
"手动堆栈": {
|
||||
"uuid": "",
|
||||
"site_uuids": {
|
||||
"A01": "3a19deae-2c7a-36f5-5e41-02c5b66feaea",
|
||||
"A02": "3a19deae-2c7a-dc6d-c41e-ef285d946cfe",
|
||||
"A03": "3a19deae-2c7a-5876-c454-6b7e224ca927",
|
||||
"B01": "3a19deae-2c7a-2426-6d71-e9de3cb158b1",
|
||||
"B02": "3a19deae-2c7a-79b0-5e44-efaafd1e4cf3",
|
||||
"B03": "3a19deae-2c7a-b9eb-f4e3-e308e0cf839a",
|
||||
"C01": "3a19deae-2c7a-32bc-768e-556647e292f3",
|
||||
"C02": "3a19deae-2c7a-e97a-8484-f5a4599447c4",
|
||||
"C03": "3a19deae-2c7a-3056-6504-10dc73fbc276",
|
||||
"D01": "3a19deae-2c7a-ffad-875e-8c4cda61d440",
|
||||
"D02": "3a19deae-2c7a-61be-601c-b6fb5610499a",
|
||||
"D03": "3a19deae-2c7a-c0f7-05a7-e3fe2491e560",
|
||||
"E01": "3a19deae-2c7a-a6f4-edd1-b436a7576363",
|
||||
"E02": "3a19deae-2c7a-4367-96dd-1ca2186f4910",
|
||||
"E03": "3a19deae-2c7a-b163-2219-23df15200311",
|
||||
"F01": "3a19deae-2c7a-d594-fd6a-0d20de3c7c4a",
|
||||
"F02": "3a19deae-2c7a-a194-ea63-8b342b8d8679",
|
||||
"F03": "3a19deae-2c7a-f7c4-12bd-425799425698",
|
||||
"G01": "3a19deae-2c7a-0b56-72f1-8ab86e53b955",
|
||||
"G02": "3a19deae-2c7a-204e-95ed-1f1950f28343",
|
||||
"G03": "3a19deae-2c7a-392b-62f1-4907c66343f8",
|
||||
"H01": "3a19deae-2c7a-5602-e876-d27aca4e3201",
|
||||
"H02": "3a19deae-2c7a-f15c-70e0-25b58a8c9702",
|
||||
"H03": "3a19deae-2c7a-780b-8965-2e1345f7e834",
|
||||
"I01": "3a19deae-2c7a-8849-e172-07de14ede928",
|
||||
"I02": "3a19deae-2c7a-4772-a37f-ff99270bafc0",
|
||||
"I03": "3a19deae-2c7a-cce7-6e4a-25ea4a2068c4",
|
||||
"J01": "3a19deae-2c7a-1848-de92-b5d5ed054cc6",
|
||||
"J02": "3a19deae-2c7a-1d45-b4f8-6f866530e205",
|
||||
"J03": "3a19deae-2c7a-f237-89d9-8fe19025dee9"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
# 物料类型配置
|
||||
MATERIAL_TYPE_MAPPINGS = {
|
||||
"烧杯": ("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"),
|
||||
"20ml分液瓶": ("BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"100ml液体": ("BIOYOND_PolymerStation_100ml_Liquid_Bottle", "d37166b3-ecaa-481e-bd84-3032b795ba07"),
|
||||
"液": ("BIOYOND_PolymerStation_Liquid_Bottle", "3a190ca1-2add-2b23-f8e1-bbd348b7f790"),
|
||||
"高粘液": ("BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle", "abe8df30-563d-43d2-85e0-cabec59ddc16"),
|
||||
"加样头(大)": ("BIOYOND_PolymerStation_Large_Dispense_Head", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
"5ml分液瓶板": ("BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier", "3a192fa4-007d-ec7b-456e-2a8be7a13f23"),
|
||||
"5ml分液瓶": ("BIOYOND_PolymerStation_5ml_Dispensing_Vial", "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"),
|
||||
"20ml分液瓶板": ("BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier", "3a192fa4-47db-3449-162a-eaf8aba57e27"),
|
||||
"配液瓶(小)板": ("BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier", "3a190c8b-3284-af78-d29f-9a69463ad047"),
|
||||
"配液瓶(小)": ("BIOYOND_PolymerStation_Small_Solution_Bottle", "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"),
|
||||
"配液瓶(大)板": ("BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier", "53e50377-32dc-4781-b3c0-5ce45bc7dc27"),
|
||||
"配液瓶(大)": ("BIOYOND_PolymerStation_Large_Solution_Bottle", "19c52ad1-51c5-494f-8854-576f4ca9c6ca"),
|
||||
"加样头(大)板": ("BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier", "a8e714ae-2a4e-4eb9-9614-e4c140ec3f16"),
|
||||
"适配器块": ("BIOYOND_PolymerStation_AdapterBlock", "efc3bb32-d504-4890-91c0-b64ed3ac80cf"),
|
||||
"枪头盒": ("BIOYOND_PolymerStation_TipBox", "3a192c2e-20f3-a44a-0334-c8301839d0b3"),
|
||||
"枪头": ("BIOYOND_PolymerStation_Pipette_Tip", "b6196971-1050-46da-9927-333e8dea062d"),
|
||||
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||
"10%分装小瓶": ("YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||
"20ml分液瓶": ("YB_20ml_Dispensing_Vial", "3a192c2b-19e8-f0a3-035e-041ca8ca1035"),
|
||||
"100ml液体": ("YB_100ml_Liquid_Bottle", "d37166b3-ecaa-481e-bd84-3032b795ba07"),
|
||||
"液": ("YB_Liquid_Bottle", "3a190ca1-2add-2b23-f8e1-bbd348b7f790"),
|
||||
"高粘液": ("YB_High_Viscosity_Liquid_Bottle", "abe8df30-563d-43d2-85e0-cabec59ddc16"),
|
||||
"加样头(大)": ("YB_Large_Dispense_Head", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
"5ml分液瓶板": ("YB_6x5ml_DispensingVialCarrier", "3a192fa4-007d-ec7b-456e-2a8be7a13f23"),
|
||||
"5ml分液瓶": ("YB_5ml_Dispensing_Vial", "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"),
|
||||
"20ml分液瓶板": ("YB_6x20ml_DispensingVialCarrier", "3a192fa4-47db-3449-162a-eaf8aba57e27"),
|
||||
"配液瓶(小)板": ("YB_6x_SmallSolutionBottleCarrier", "3a190c8b-3284-af78-d29f-9a69463ad047"),
|
||||
"配液瓶(小)": ("YB_Small_Solution_Bottle", "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"),
|
||||
"配液瓶(大)板": ("YB_4x_LargeSolutionBottleCarrier", "53e50377-32dc-4781-b3c0-5ce45bc7dc27"),
|
||||
"配液瓶(大)": ("YB_Large_Solution_Bottle", "19c52ad1-51c5-494f-8854-576f4ca9c6ca"),
|
||||
"加样头(大)板": ("YB_6x_LargeDispenseHeadCarrier", "a8e714ae-2a4e-4eb9-9614-e4c140ec3f16"),
|
||||
"适配器块": ("YB_AdapterBlock", "efc3bb32-d504-4890-91c0-b64ed3ac80cf"),
|
||||
"枪头盒": ("YB_TipBox", "3a192c2e-20f3-a44a-0334-c8301839d0b3"),
|
||||
"枪头": ("YB_Pipette_Tip", "b6196971-1050-46da-9927-333e8dea062d"),
|
||||
}
|
||||
|
||||
# 步骤参数配置(各工作流的步骤UUID)
|
||||
WORKFLOW_STEP_IDS = {
|
||||
"reactor_taken_in": {
|
||||
"config": ""
|
||||
SOLID_LIQUID_MAPPINGS = {
|
||||
# 固体
|
||||
"LiDFOB": {
|
||||
"typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||
"code": "",
|
||||
"barCode": "",
|
||||
"name": "LiDFOB",
|
||||
"unit": "g",
|
||||
"parameters": "",
|
||||
"quantity": "2",
|
||||
"warningQuantity": "1",
|
||||
"details": []
|
||||
},
|
||||
"liquid_feeding_beaker": {
|
||||
"liquid": "",
|
||||
"observe": ""
|
||||
},
|
||||
"liquid_feeding_vials_non_titration": {
|
||||
"liquid": "",
|
||||
"observe": ""
|
||||
},
|
||||
"liquid_feeding_solvents": {
|
||||
"liquid": "",
|
||||
"observe": ""
|
||||
},
|
||||
"solid_feeding_vials": {
|
||||
"feeding": "",
|
||||
"observe": ""
|
||||
},
|
||||
"liquid_feeding_titration": {
|
||||
"liquid": "",
|
||||
"observe": ""
|
||||
},
|
||||
"drip_back": {
|
||||
"liquid": "",
|
||||
"observe": ""
|
||||
}
|
||||
# "LiPF6": {
|
||||
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||
# "code": "",
|
||||
# "barCode": "",
|
||||
# "name": "LiPF6",
|
||||
# "unit": "g",
|
||||
# "parameters": "",
|
||||
# "quantity": 2,
|
||||
# "warningQuantity": 1,
|
||||
# "details": []
|
||||
# },
|
||||
# "LiFSI": {
|
||||
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||
# "code": "",
|
||||
# "barCode": "",
|
||||
# "name": "LiFSI",
|
||||
# "unit": "g",
|
||||
# "parameters": "",
|
||||
# "quantity": 2,
|
||||
# "warningQuantity": 1,
|
||||
# "details": []
|
||||
# },
|
||||
# "DTC": {
|
||||
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||
# "code": "",
|
||||
# "barCode": "",
|
||||
# "name": "DTC",
|
||||
# "unit": "g",
|
||||
# "parameters": "",
|
||||
# "quantity": 2,
|
||||
# "warningQuantity": 1,
|
||||
# "details": []
|
||||
# },
|
||||
# "LiPO2F2": {
|
||||
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||
# "code": "",
|
||||
# "barCode": "",
|
||||
# "name": "LiPO2F2",
|
||||
# "unit": "g",
|
||||
# "parameters": "",
|
||||
# "quantity": 2,
|
||||
# "warningQuantity": 1,
|
||||
# "details": []
|
||||
# },
|
||||
# 液体
|
||||
# "SA": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "EC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "VC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "AND": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "HTCN": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "DENE": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "TMSP": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "TMSB": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "EP": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "DEC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "EMC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "SN": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "DMC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
# "FEC": ("BIOYOND_PolymerStation_Solid_Stock", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
|
||||
}
|
||||
|
||||
WORKFLOW_MAPPINGS = {}
|
||||
|
||||
LOCATION_MAPPING = {}
|
||||
@@ -71,11 +71,11 @@ class WorkstationHTTPHandler(BaseHTTPRequestHandler):
|
||||
if content_length > 0:
|
||||
post_data = self.rfile.read(content_length)
|
||||
request_data = json.loads(post_data.decode('utf-8'))
|
||||
|
||||
else:
|
||||
request_data = {}
|
||||
logger.info(f"收到工作站报送: {endpoint} 收到接受数据:{request_data}")
|
||||
# logger.info(f"收到的json数据: {request_data}")
|
||||
|
||||
logger.info(f"收到工作站报送: {endpoint} - {request_data.get('token', 'unknown')}")
|
||||
|
||||
# 统一的报送端点路由(基于LIMS协议规范)
|
||||
if endpoint == '/report/step_finish':
|
||||
response = self._handle_step_finish_report(request_data)
|
||||
@@ -668,7 +668,7 @@ __all__ = [
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 简单测试HTTP服务
|
||||
class BioyondWorkstation:
|
||||
class DummyWorkstation:
|
||||
device_id = "WS-001"
|
||||
|
||||
def process_step_finish_report(self, report_request):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
category:
|
||||
- bottle_carriers
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_1BottleCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_1BottleCarrier
|
||||
type: pylabrobot
|
||||
description: 1BottleCarrier
|
||||
handles: []
|
||||
@@ -14,7 +14,7 @@
|
||||
category:
|
||||
- bottle_carriers
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_1FlaskCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_1FlaskCarrier
|
||||
type: pylabrobot
|
||||
description: 1FlaskCarrier
|
||||
handles: []
|
||||
@@ -26,7 +26,7 @@
|
||||
category:
|
||||
- bottle_carriers
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6StockCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6StockCarrier
|
||||
type: pylabrobot
|
||||
description: 6StockCarrier
|
||||
handles: []
|
||||
@@ -38,7 +38,7 @@
|
||||
category:
|
||||
- bottle_carriers
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6VialCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6VialCarrier
|
||||
type: pylabrobot
|
||||
description: 6VialCarrier
|
||||
handles: []
|
||||
@@ -50,7 +50,7 @@
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6x5ml_DispensingVialCarrier
|
||||
type: pylabrobot
|
||||
description: 6x5ml_DispensingVialCarrier
|
||||
handles: []
|
||||
@@ -62,7 +62,7 @@
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6x20ml_DispensingVialCarrier
|
||||
type: pylabrobot
|
||||
description: 6x20ml_DispensingVialCarrier
|
||||
handles: []
|
||||
@@ -74,7 +74,7 @@
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6x_SmallSolutionBottleCarrier
|
||||
type: pylabrobot
|
||||
description: 6x_SmallSolutionBottleCarrier
|
||||
handles: []
|
||||
@@ -86,7 +86,7 @@
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_4x_LargeSolutionBottleCarrier
|
||||
type: pylabrobot
|
||||
description: 4x_LargeSolutionBottleCarrier
|
||||
handles: []
|
||||
@@ -98,7 +98,7 @@
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_6x_LargeDispenseHeadCarrier
|
||||
type: pylabrobot
|
||||
description: 6x_LargeDispenseHeadCarrier
|
||||
handles: []
|
||||
@@ -110,7 +110,7 @@ AdapterBlock:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_AdapterBlock
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_AdapterBlock
|
||||
type: pylabrobot
|
||||
description: AdapterBlock
|
||||
handles: []
|
||||
@@ -122,7 +122,7 @@ TipBox:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_TipBox
|
||||
module: unilabos.resources.bioyond.bottle_carriers:YB_TipBox
|
||||
type: pylabrobot
|
||||
description: TipBox
|
||||
handles: []
|
||||
|
||||
@@ -2,7 +2,7 @@ Liquid_Vial:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Liquid_Vial
|
||||
module: unilabos.resources.bioyond.bottles:YB_Liquid_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -12,7 +12,7 @@ Reagent_Bottle:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Reagent_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_Reagent_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -22,7 +22,7 @@ Solid_Stock:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solid_Stock
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solid_Stock
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -32,7 +32,7 @@ Solid_Vial:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solid_Vial
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solid_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -42,7 +42,7 @@ Solution_Beaker:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solution_Beaker
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solution_Beaker
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -52,7 +52,7 @@ Solution_Beaker:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_100ml_Liquid_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_100ml_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -62,7 +62,7 @@ Liquid_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Liquid_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -72,7 +72,7 @@ High_Viscosity_Liquid_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_High_Viscosity_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -82,7 +82,7 @@ Large_Dispense_Head:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Large_Dispense_Head
|
||||
module: unilabos.resources.bioyond.bottles:YB_Large_Dispense_Head
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -92,7 +92,7 @@ Large_Dispense_Head:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_5ml_Dispensing_Vial
|
||||
module: unilabos.resources.bioyond.bottles:YB_5ml_Dispensing_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -102,7 +102,7 @@ Large_Dispense_Head:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_20ml_Dispensing_Vial
|
||||
module: unilabos.resources.bioyond.bottles:YB_20ml_Dispensing_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -112,7 +112,7 @@ Small_Solution_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Small_Solution_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_Small_Solution_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -122,7 +122,7 @@ Large_Solution_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Large_Solution_Bottle
|
||||
module: unilabos.resources.bioyond.bottles:YB_Large_Solution_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
@@ -132,9 +132,150 @@ Pipette_Tip:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Pipette_Tip
|
||||
module: unilabos.resources.bioyond.bottles:YB_Pipette_Tip
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
|
||||
YB_Liquid_Vial:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Liquid_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Reagent_Bottle:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Reagent_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Solid_Stock:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solid_Stock
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Solid_Vial:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solid_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Solution_Beaker:
|
||||
category:
|
||||
- bottles
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Solution_Beaker
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_100ml_Liquid_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_100ml_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Liquid_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_High_Viscosity_Liquid_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_High_Viscosity_Liquid_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Large_Dispense_Head:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Large_Dispense_Head
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_5ml_Dispensing_Vial:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_5ml_Dispensing_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_20ml_Dispensing_Vial:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_20ml_Dispensing_Vial
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Small_Solution_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Small_Solution_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Large_Solution_Bottle:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Large_Solution_Bottle
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
YB_Pipette_Tip:
|
||||
category:
|
||||
- yb3
|
||||
class:
|
||||
module: unilabos.resources.bioyond.bottles:YB_Pipette_Tip
|
||||
type: pylabrobot
|
||||
handles: []
|
||||
icon: ''
|
||||
init_param_schema: {}
|
||||
version: 1.0.0
|
||||
|
||||
@@ -22,7 +22,7 @@ BIOYOND_PolymerReactionStation_Deck:
|
||||
init_param_schema: {}
|
||||
registry_type: resource
|
||||
version: 1.0.0
|
||||
YB_Deck15:
|
||||
YB_Deck16:
|
||||
category:
|
||||
- deck
|
||||
class:
|
||||
|
||||
@@ -2,17 +2,17 @@ from pylabrobot.resources import create_homogeneous_resources, Coordinate, Resou
|
||||
|
||||
from unilabos.resources.itemized_carrier import Bottle, BottleCarrier
|
||||
from unilabos.resources.bioyond.bottles import (
|
||||
BIOYOND_PolymerStation_Solid_Stock,
|
||||
BIOYOND_PolymerStation_Solid_Vial,
|
||||
BIOYOND_PolymerStation_Liquid_Vial,
|
||||
BIOYOND_PolymerStation_Solution_Beaker,
|
||||
BIOYOND_PolymerStation_Reagent_Bottle,
|
||||
BIOYOND_PolymerStation_5ml_Dispensing_Vial,
|
||||
BIOYOND_PolymerStation_20ml_Dispensing_Vial,
|
||||
BIOYOND_PolymerStation_Small_Solution_Bottle,
|
||||
BIOYOND_PolymerStation_Large_Solution_Bottle,
|
||||
BIOYOND_PolymerStation_Large_Dispense_Head,
|
||||
BIOYOND_PolymerStation_Pipette_Tip
|
||||
YB_Solid_Stock,
|
||||
YB_Solid_Vial,
|
||||
YB_Liquid_Vial,
|
||||
YB_Solution_Beaker,
|
||||
YB_Reagent_Bottle,
|
||||
YB_5ml_Dispensing_Vial,
|
||||
YB_20ml_Dispensing_Vial,
|
||||
YB_Small_Solution_Bottle,
|
||||
YB_Large_Solution_Bottle,
|
||||
YB_Large_Dispense_Head,
|
||||
YB_Pipette_Tip
|
||||
)
|
||||
# 命名约定:试剂瓶-Bottle,烧杯-Beaker,烧瓶-Flask,小瓶-Vial
|
||||
|
||||
@@ -63,7 +63,7 @@ def BIOYOND_Electrolyte_6VialCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_y = 2
|
||||
carrier.num_items_z = 1
|
||||
for i in range(6):
|
||||
carrier[i] = BIOYOND_PolymerStation_Solid_Vial(f"{name}_vial_{i+1}")
|
||||
carrier[i] = YB_Solid_Vial(f"{name}_vial_{i+1}")
|
||||
return carrier
|
||||
|
||||
|
||||
@@ -100,11 +100,11 @@ def BIOYOND_Electrolyte_1BottleCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_x = 1
|
||||
carrier.num_items_y = 1
|
||||
carrier.num_items_z = 1
|
||||
carrier[0] = BIOYOND_PolymerStation_Solution_Beaker(f"{name}_beaker_1")
|
||||
carrier[0] = YB_Solution_Beaker(f"{name}_beaker_1")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6StockCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6StockCarrier(name: str) -> BottleCarrier:
|
||||
"""6瓶载架 - 2x3布局"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -151,11 +151,11 @@ def BIOYOND_PolymerStation_6StockCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
||||
for i in range(6):
|
||||
carrier[i] = BIOYOND_PolymerStation_Solid_Stock(f"{name}_vial_{ordering[i]}")
|
||||
carrier[i] = YB_Solid_Stock(f"{name}_vial_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6VialCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6VialCarrier(name: str) -> BottleCarrier:
|
||||
"""6瓶载架 - 2x3布局"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -202,13 +202,13 @@ def BIOYOND_PolymerStation_6VialCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
||||
for i in range(3):
|
||||
carrier[i] = BIOYOND_PolymerStation_Solid_Vial(f"{name}_solidvial_{ordering[i]}")
|
||||
carrier[i] = YB_Solid_Vial(f"{name}_solidvial_{ordering[i]}")
|
||||
for i in range(3, 6):
|
||||
carrier[i] = BIOYOND_PolymerStation_Liquid_Vial(f"{name}_liquidvial_{ordering[i]}")
|
||||
carrier[i] = YB_Liquid_Vial(f"{name}_liquidvial_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_1BottleCarrier(name: str) -> BottleCarrier:
|
||||
def YB_1BottleCarrier(name: str) -> BottleCarrier:
|
||||
"""1瓶载架 - 单个中央位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -241,11 +241,11 @@ def BIOYOND_PolymerStation_1BottleCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_x = 1
|
||||
carrier.num_items_y = 1
|
||||
carrier.num_items_z = 1
|
||||
carrier[0] = BIOYOND_PolymerStation_Reagent_Bottle(f"{name}_flask_1")
|
||||
carrier[0] = YB_Reagent_Bottle(f"{name}_flask_1")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_1FlaskCarrier(name: str) -> BottleCarrier:
|
||||
def YB_1FlaskCarrier(name: str) -> BottleCarrier:
|
||||
"""1瓶载架 - 单个中央位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -278,11 +278,11 @@ def BIOYOND_PolymerStation_1FlaskCarrier(name: str) -> BottleCarrier:
|
||||
carrier.num_items_x = 1
|
||||
carrier.num_items_y = 1
|
||||
carrier.num_items_z = 1
|
||||
carrier[0] = BIOYOND_PolymerStation_Reagent_Bottle(f"{name}_bottle_1")
|
||||
carrier[0] = YB_Reagent_Bottle(f"{name}_bottle_1")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6x5ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||
"""5ml分液瓶板 - 4x2布局,8个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -328,11 +328,11 @@ def BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier(name: str) -> BottleCarri
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||
for i in range(8):
|
||||
carrier[i] = BIOYOND_PolymerStation_5ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||
carrier[i] = YB_5ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6x20ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||
"""20ml分液瓶板 - 4x2布局,8个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -378,11 +378,11 @@ def BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier(name: str) -> BottleCarr
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||
for i in range(8):
|
||||
carrier[i] = BIOYOND_PolymerStation_20ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||
carrier[i] = YB_20ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6x_SmallSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||
"""配液瓶(小)板 - 4x2布局,8个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -428,11 +428,11 @@ def BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier(name: str) -> BottleCar
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||
for i in range(8):
|
||||
carrier[i] = BIOYOND_PolymerStation_Small_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||
carrier[i] = YB_Small_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||
def YB_4x_LargeSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||
"""配液瓶(大)板 - 2x2布局,4个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -478,11 +478,11 @@ def BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier(name: str) -> BottleCar
|
||||
carrier.num_items_z = 1
|
||||
ordering = ["A1", "A2", "B1", "B2"]
|
||||
for i in range(4):
|
||||
carrier[i] = BIOYOND_PolymerStation_Large_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||
carrier[i] = YB_Large_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier(name: str) -> BottleCarrier:
|
||||
def YB_6x_LargeDispenseHeadCarrier(name: str) -> BottleCarrier:
|
||||
"""加样头(大)板 - 1x1布局,1个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -526,11 +526,11 @@ def BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier(name: str) -> BottleCarri
|
||||
carrier.num_items_x = 1
|
||||
carrier.num_items_y = 1
|
||||
carrier.num_items_z = 1
|
||||
carrier[0] = BIOYOND_PolymerStation_Large_Dispense_Head(f"{name}_head_1")
|
||||
carrier[0] = YB_Large_Dispense_Head(f"{name}_head_1")
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_AdapterBlock(name: str) -> BottleCarrier:
|
||||
def YB_AdapterBlock(name: str) -> BottleCarrier:
|
||||
"""适配器块 - 单个中央位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -567,7 +567,7 @@ def BIOYOND_PolymerStation_AdapterBlock(name: str) -> BottleCarrier:
|
||||
return carrier
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_TipBox(name: str) -> BottleCarrier:
|
||||
def YB_TipBox(name: str) -> BottleCarrier:
|
||||
"""枪头盒 - 8x12布局,96个位置"""
|
||||
|
||||
# 载架尺寸 (mm)
|
||||
@@ -615,6 +615,6 @@ def BIOYOND_PolymerStation_TipBox(name: str) -> BottleCarrier:
|
||||
for i in range(96):
|
||||
row = chr(65 + i // 12) # A-H
|
||||
col = (i % 12) + 1 # 1-12
|
||||
carrier[i] = BIOYOND_PolymerStation_Pipette_Tip(f"{name}_tip_{row}{col}")
|
||||
carrier[i] = YB_Pipette_Tip(f"{name}_tip_{row}{col}")
|
||||
return carrier
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from unilabos.resources.itemized_carrier import Bottle, BottleCarrier
|
||||
# 工厂函数
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Solid_Stock(
|
||||
def YB_Solid_Stock(
|
||||
name: str,
|
||||
diameter: float = 20.0,
|
||||
height: float = 100.0,
|
||||
@@ -12,7 +12,7 @@ def BIOYOND_PolymerStation_Solid_Stock(
|
||||
"""创建粉末瓶"""
|
||||
return Bottle(
|
||||
name=name,
|
||||
diameter=diameter,
|
||||
diameter=diameter,# 未知
|
||||
height=height,
|
||||
max_volume=max_volume,
|
||||
barcode=barcode,
|
||||
@@ -20,7 +20,7 @@ def BIOYOND_PolymerStation_Solid_Stock(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Solid_Vial(
|
||||
def YB_Solid_Vial(
|
||||
name: str,
|
||||
diameter: float = 25.0,
|
||||
height: float = 60.0,
|
||||
@@ -38,7 +38,7 @@ def BIOYOND_PolymerStation_Solid_Vial(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Liquid_Vial(
|
||||
def YB_Liquid_Vial(
|
||||
name: str,
|
||||
diameter: float = 25.0,
|
||||
height: float = 60.0,
|
||||
@@ -56,7 +56,7 @@ def BIOYOND_PolymerStation_Liquid_Vial(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Solution_Beaker(
|
||||
def YB_Solution_Beaker(
|
||||
name: str,
|
||||
diameter: float = 60.0,
|
||||
height: float = 70.0,
|
||||
@@ -74,7 +74,7 @@ def BIOYOND_PolymerStation_Solution_Beaker(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Reagent_Bottle(
|
||||
def YB_Reagent_Bottle(
|
||||
name: str,
|
||||
diameter: float = 70.0,
|
||||
height: float = 120.0,
|
||||
@@ -92,7 +92,7 @@ def BIOYOND_PolymerStation_Reagent_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_100ml_Liquid_Bottle(
|
||||
def YB_100ml_Liquid_Bottle(
|
||||
name: str,
|
||||
diameter: float = 50.0,
|
||||
height: float = 80.0,
|
||||
@@ -110,7 +110,7 @@ def BIOYOND_PolymerStation_100ml_Liquid_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Liquid_Bottle(
|
||||
def YB_Liquid_Bottle(
|
||||
name: str,
|
||||
diameter: float = 40.0,
|
||||
height: float = 70.0,
|
||||
@@ -128,7 +128,7 @@ def BIOYOND_PolymerStation_Liquid_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle(
|
||||
def YB_High_Viscosity_Liquid_Bottle(
|
||||
name: str,
|
||||
diameter: float = 45.0,
|
||||
height: float = 75.0,
|
||||
@@ -146,7 +146,7 @@ def BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Large_Dispense_Head(
|
||||
def YB_Large_Dispense_Head(
|
||||
name: str,
|
||||
diameter: float = 35.0,
|
||||
height: float = 90.0,
|
||||
@@ -164,7 +164,7 @@ def BIOYOND_PolymerStation_Large_Dispense_Head(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_5ml_Dispensing_Vial(
|
||||
def YB_5ml_Dispensing_Vial(
|
||||
name: str,
|
||||
diameter: float = 15.0,
|
||||
height: float = 45.0,
|
||||
@@ -182,7 +182,7 @@ def BIOYOND_PolymerStation_5ml_Dispensing_Vial(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_20ml_Dispensing_Vial(
|
||||
def YB_20ml_Dispensing_Vial(
|
||||
name: str,
|
||||
diameter: float = 20.0,
|
||||
height: float = 65.0,
|
||||
@@ -200,7 +200,7 @@ def BIOYOND_PolymerStation_20ml_Dispensing_Vial(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Small_Solution_Bottle(
|
||||
def YB_Small_Solution_Bottle(
|
||||
name: str,
|
||||
diameter: float = 35.0,
|
||||
height: float = 60.0,
|
||||
@@ -218,7 +218,7 @@ def BIOYOND_PolymerStation_Small_Solution_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Large_Solution_Bottle(
|
||||
def YB_Large_Solution_Bottle(
|
||||
name: str,
|
||||
diameter: float = 55.0,
|
||||
height: float = 90.0,
|
||||
@@ -236,7 +236,7 @@ def BIOYOND_PolymerStation_Large_Solution_Bottle(
|
||||
)
|
||||
|
||||
|
||||
def BIOYOND_PolymerStation_Pipette_Tip(
|
||||
def YB_Pipette_Tip(
|
||||
name: str,
|
||||
diameter: float = 10.0,
|
||||
height: float = 50.0,
|
||||
|
||||
@@ -48,7 +48,7 @@ def bioyond_warehouse_1x2x2(name: str) -> WareHouse:
|
||||
item_dx=137.0,
|
||||
item_dy=96.0,
|
||||
item_dz=120.0,
|
||||
category="warehouse",
|
||||
category="YB_warehouse",
|
||||
)
|
||||
def bioyond_warehouse_10x1x1(name: str) -> WareHouse:
|
||||
"""创建BioYond 4x1x4仓库"""
|
||||
|
||||
@@ -624,6 +624,8 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[st
|
||||
Returns:
|
||||
pylabrobot 格式的物料列表
|
||||
"""
|
||||
print("1:bioyond_materials:",bioyond_materials)
|
||||
# print("2:type_mapping:",type_mapping)
|
||||
plr_materials = []
|
||||
|
||||
for material in bioyond_materials:
|
||||
|
||||
Reference in New Issue
Block a user