mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
更新配置文件中的 report_ip 默认值,优化 bioyond_cell_workstation.py 中的订单状态处理逻辑,新增多个瓶子和载架类型的定义,调整仓库结构以支持更灵活的物料管理。
This commit is contained in:
@@ -80,8 +80,15 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
|
|
||||||
def process_order_finish_report(self, report_request, used_materials=None):
|
def process_order_finish_report(self, report_request, used_materials=None):
|
||||||
order_code = report_request.data.get("orderCode")
|
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
|
||||||
|
|
||||||
logger.info(f"任务完成: {order_code}, status={report_request.data.get('status')}")
|
|
||||||
self._set_pending_event(order_code)
|
self._set_pending_event(order_code)
|
||||||
return {"status": "received"}
|
return {"status": "received"}
|
||||||
|
|
||||||
@@ -119,7 +126,18 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
logger.warning(f"{context} 响应中未找到 orderCode,无法跟踪任务完成")
|
logger.warning(f"{context} 响应中未找到 orderCode,无法跟踪任务完成")
|
||||||
return
|
return
|
||||||
for code in order_codes:
|
for code in order_codes:
|
||||||
self._wait_for_order_completion(code, timeout=timeout)
|
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} 等待超时,未收到完成通知")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_order_codes(response: Dict[str, Any]) -> List[str]:
|
def _extract_order_codes(response: Dict[str, Any]) -> List[str]:
|
||||||
@@ -296,7 +314,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
def auto_feeding4to3(
|
def auto_feeding4to3(
|
||||||
self,
|
self,
|
||||||
# ★ 修改点:默认模板路径
|
# ★ 修改点:默认模板路径
|
||||||
xlsx_path: Optional[str] = "unilabos/devices/workstation/bioyond_studio/bioyond_cell/样品导入模板.xlsx",
|
xlsx_path: Optional[str] = "/Users/calvincao/Desktop/work/uni-lab-all/Uni-Lab-OS/unilabos/devices/workstation/bioyond_studio/bioyond_cell/样品导入模板.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,
|
||||||
@@ -812,8 +830,8 @@ class BioyondCellWorkstation(BioyondWorkstation):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
ws = BioyondCellWorkstation()
|
ws = BioyondCellWorkstation()
|
||||||
logger.info(ws.scheduler_start())
|
logger.info(ws.scheduler_start())
|
||||||
|
#TODO:新建入库
|
||||||
logger.info(ws.auto_feeding4to3())
|
logger.info(ws.auto_feeding4to3()) #搬运物料到3号箱
|
||||||
# 使用正斜杠或 Path 对象来指定文件路径
|
# 使用正斜杠或 Path 对象来指定文件路径
|
||||||
excel_path = Path("unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx")
|
excel_path = Path("unilabos/devices/workstation/bioyond_studio/bioyond_cell/2025092701.xlsx")
|
||||||
logger.info(ws.create_orders(excel_path))
|
logger.info(ws.create_orders(excel_path))
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ BIOYOND_FULL_CONFIG = {
|
|||||||
# HTTP 服务配置
|
# HTTP 服务配置
|
||||||
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "0.0.0.0"), # HTTP服务监听地址(0.0.0.0 表示监听所有网络接口)
|
"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")),
|
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
|
||||||
"report_ip": os.getenv("BIOYOND_REPORT_IP", "172.21.33.141"), # 报送给 Bioyond 的本机IP地址(留空则自动检测)
|
"report_ip": os.getenv("BIOYOND_REPORT_IP", "172.21.32.57"), # 报送给 Bioyond 的本机IP地址(留空则自动检测)
|
||||||
|
|
||||||
# 调试模式
|
# 调试模式
|
||||||
"debug_mode": os.getenv("BIOYOND_DEBUG_MODE", "False").lower() == "true",
|
"debug_mode": os.getenv("BIOYOND_DEBUG_MODE", "False").lower() == "true",
|
||||||
|
|||||||
@@ -46,3 +46,87 @@ BIOYOND_PolymerStation_6VialCarrier:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_AdapterBlock:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_AdapterBlock
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_AdapterBlock
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_TipBox:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_TipBox
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND_PolymerStation_TipBox
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|||||||
@@ -48,3 +48,93 @@ BIOYOND_PolymerStation_Solution_Beaker:
|
|||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_100ml_Liquid_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_100ml_Liquid_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_Liquid_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Liquid_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_Large_Dispense_Head:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Large_Dispense_Head
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_5ml_Dispensing_Vial:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_5ml_Dispensing_Vial
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_20ml_Dispensing_Vial:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_20ml_Dispensing_Vial
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_Small_Solution_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Small_Solution_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_Large_Solution_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Large_Solution_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
BIOYOND_PolymerStation_Pipette_Tip:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Pipette_Tip
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ BIOYOND_PolymerReactionStation_Deck:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
YB_Deck14:
|
YB_Deck15:
|
||||||
category:
|
category:
|
||||||
- deck
|
- deck
|
||||||
class:
|
class:
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ from unilabos.resources.bioyond.bottles import (
|
|||||||
BIOYOND_PolymerStation_Solid_Vial,
|
BIOYOND_PolymerStation_Solid_Vial,
|
||||||
BIOYOND_PolymerStation_Liquid_Vial,
|
BIOYOND_PolymerStation_Liquid_Vial,
|
||||||
BIOYOND_PolymerStation_Solution_Beaker,
|
BIOYOND_PolymerStation_Solution_Beaker,
|
||||||
BIOYOND_PolymerStation_Reagent_Bottle
|
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
|
||||||
)
|
)
|
||||||
# 命名约定:试剂瓶-Bottle,烧杯-Beaker,烧瓶-Flask,小瓶-Vial
|
# 命名约定:试剂瓶-Bottle,烧杯-Beaker,烧瓶-Flask,小瓶-Vial
|
||||||
|
|
||||||
@@ -274,3 +280,343 @@ def BIOYOND_PolymerStation_1FlaskCarrier(name: str) -> BottleCarrier:
|
|||||||
carrier.num_items_z = 1
|
carrier.num_items_z = 1
|
||||||
carrier[0] = BIOYOND_PolymerStation_Reagent_Bottle(f"{name}_bottle_1")
|
carrier[0] = BIOYOND_PolymerStation_Reagent_Bottle(f"{name}_bottle_1")
|
||||||
return carrier
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""5ml分液瓶板 - 2x3布局,6个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 50.0
|
||||||
|
|
||||||
|
# 瓶位尺寸
|
||||||
|
bottle_diameter = 15.0
|
||||||
|
bottle_spacing_x = 42.0 # X方向间距
|
||||||
|
bottle_spacing_y = 35.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (3 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (2 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=2,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=bottle_spacing_x,
|
||||||
|
item_dy=bottle_spacing_y,
|
||||||
|
size_x=bottle_diameter,
|
||||||
|
size_y=bottle_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_6x5ml_DispensingVialCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 3
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"]
|
||||||
|
for i in range(6):
|
||||||
|
carrier[i] = BIOYOND_PolymerStation_5ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""20ml分液瓶板 - 2x3布局,6个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 70.0
|
||||||
|
|
||||||
|
# 瓶位尺寸
|
||||||
|
bottle_diameter = 20.0
|
||||||
|
bottle_spacing_x = 42.0 # X方向间距
|
||||||
|
bottle_spacing_y = 35.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (3 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (2 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=2,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=bottle_spacing_x,
|
||||||
|
item_dy=bottle_spacing_y,
|
||||||
|
size_x=bottle_diameter,
|
||||||
|
size_y=bottle_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_6x20ml_DispensingVialCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 3
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"]
|
||||||
|
for i in range(6):
|
||||||
|
carrier[i] = BIOYOND_PolymerStation_20ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""配液瓶(小)板 - 2x3布局,6个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 65.0
|
||||||
|
|
||||||
|
# 瓶位尺寸
|
||||||
|
bottle_diameter = 35.0
|
||||||
|
bottle_spacing_x = 42.0 # X方向间距
|
||||||
|
bottle_spacing_y = 35.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (3 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (2 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=2,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=bottle_spacing_x,
|
||||||
|
item_dy=bottle_spacing_y,
|
||||||
|
size_x=bottle_diameter,
|
||||||
|
size_y=bottle_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_6x_SmallSolutionBottleCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 3
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"]
|
||||||
|
for i in range(6):
|
||||||
|
carrier[i] = BIOYOND_PolymerStation_Small_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""配液瓶(大)板 - 2x2布局,4个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 95.0
|
||||||
|
|
||||||
|
# 瓶位尺寸
|
||||||
|
bottle_diameter = 55.0
|
||||||
|
bottle_spacing_x = 60.0 # X方向间距
|
||||||
|
bottle_spacing_y = 60.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (2 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (2 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=2,
|
||||||
|
num_items_y=2,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=bottle_spacing_x,
|
||||||
|
item_dy=bottle_spacing_y,
|
||||||
|
size_x=bottle_diameter,
|
||||||
|
size_y=bottle_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_4x_LargeSolutionBottleCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 2
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
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]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""加样头(大)板 - 2x3布局,6个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 95.0
|
||||||
|
|
||||||
|
# 瓶位尺寸
|
||||||
|
bottle_diameter = 35.0
|
||||||
|
bottle_spacing_x = 42.0 # X方向间距
|
||||||
|
bottle_spacing_y = 35.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (3 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (2 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=2,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=bottle_spacing_x,
|
||||||
|
item_dy=bottle_spacing_y,
|
||||||
|
size_x=bottle_diameter,
|
||||||
|
size_y=bottle_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_6x_LargeDispenseHeadCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 3
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"]
|
||||||
|
for i in range(6):
|
||||||
|
carrier[i] = BIOYOND_PolymerStation_Large_Dispense_Head(f"{name}_head_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_AdapterBlock(name: str) -> BottleCarrier:
|
||||||
|
"""适配器块 - 单个中央位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 30.0
|
||||||
|
|
||||||
|
# 适配器尺寸
|
||||||
|
adapter_diameter = 80.0
|
||||||
|
|
||||||
|
# 计算中央位置
|
||||||
|
center_x = (carrier_size_x - adapter_diameter) / 2
|
||||||
|
center_y = (carrier_size_y - adapter_diameter) / 2
|
||||||
|
center_z = 0.0
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=create_homogeneous_resources(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
locations=[Coordinate(center_x, center_y, center_z)],
|
||||||
|
resource_size_x=adapter_diameter,
|
||||||
|
resource_size_y=adapter_diameter,
|
||||||
|
name_prefix=name,
|
||||||
|
),
|
||||||
|
model="BIOYOND_PolymerStation_AdapterBlock",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 1
|
||||||
|
carrier.num_items_y = 1
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
# 适配器块本身不包含瓶子,只是一个支撑结构
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_TipBox(name: str) -> BottleCarrier:
|
||||||
|
"""枪头盒 - 8x12布局,96个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (mm)
|
||||||
|
carrier_size_x = 127.8
|
||||||
|
carrier_size_y = 85.5
|
||||||
|
carrier_size_z = 55.0
|
||||||
|
|
||||||
|
# 枪头尺寸
|
||||||
|
tip_diameter = 10.0
|
||||||
|
tip_spacing_x = 9.0 # X方向间距
|
||||||
|
tip_spacing_y = 9.0 # Y方向间距
|
||||||
|
|
||||||
|
# 计算起始位置 (居中排列)
|
||||||
|
start_x = (carrier_size_x - (12 - 1) * tip_spacing_x - tip_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (8 - 1) * tip_spacing_y - tip_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=12,
|
||||||
|
num_items_y=8,
|
||||||
|
dx=start_x,
|
||||||
|
dy=start_y,
|
||||||
|
dz=5.0,
|
||||||
|
item_dx=tip_spacing_x,
|
||||||
|
item_dy=tip_spacing_y,
|
||||||
|
size_x=tip_diameter,
|
||||||
|
size_y=tip_diameter,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
)
|
||||||
|
for k, v in sites.items():
|
||||||
|
v.name = f"{name}_{v.name}"
|
||||||
|
|
||||||
|
carrier = BottleCarrier(
|
||||||
|
name=name,
|
||||||
|
size_x=carrier_size_x,
|
||||||
|
size_y=carrier_size_y,
|
||||||
|
size_z=carrier_size_z,
|
||||||
|
sites=sites,
|
||||||
|
model="BIOYOND_PolymerStation_TipBox",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 12
|
||||||
|
carrier.num_items_y = 8
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
# 创建96个枪头
|
||||||
|
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}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|||||||
@@ -90,3 +90,166 @@ def BIOYOND_PolymerStation_Reagent_Bottle(
|
|||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Reagent_Bottle",
|
model="BIOYOND_PolymerStation_Reagent_Bottle",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_100ml_Liquid_Bottle(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 50.0,
|
||||||
|
height: float = 80.0,
|
||||||
|
max_volume: float = 100000.0, # 100mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建100ml液体瓶"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_100ml_Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_Liquid_Bottle(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 40.0,
|
||||||
|
height: float = 70.0,
|
||||||
|
max_volume: float = 50000.0, # 50mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建液体瓶"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 45.0,
|
||||||
|
height: float = 75.0,
|
||||||
|
max_volume: float = 60000.0, # 60mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建高粘液瓶"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_High_Viscosity_Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_Large_Dispense_Head(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 35.0,
|
||||||
|
height: float = 90.0,
|
||||||
|
max_volume: float = 50000.0, # 50mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建加样头(大)"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_Large_Dispense_Head",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_5ml_Dispensing_Vial(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 15.0,
|
||||||
|
height: float = 45.0,
|
||||||
|
max_volume: float = 5000.0, # 5mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建5ml分液瓶"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_5ml_Dispensing_Vial",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_20ml_Dispensing_Vial(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 20.0,
|
||||||
|
height: float = 65.0,
|
||||||
|
max_volume: float = 20000.0, # 20mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建20ml分液瓶"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_20ml_Dispensing_Vial",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_Small_Solution_Bottle(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 35.0,
|
||||||
|
height: float = 60.0,
|
||||||
|
max_volume: float = 40000.0, # 40mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建配液瓶(小)"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_Small_Solution_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_Large_Solution_Bottle(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 55.0,
|
||||||
|
height: float = 90.0,
|
||||||
|
max_volume: float = 150000.0, # 150mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建配液瓶(大)"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_Large_Solution_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def BIOYOND_PolymerStation_Pipette_Tip(
|
||||||
|
name: str,
|
||||||
|
diameter: float = 10.0,
|
||||||
|
height: float = 50.0,
|
||||||
|
max_volume: float = 1000.0, # 1mL
|
||||||
|
barcode: str = None,
|
||||||
|
) -> Bottle:
|
||||||
|
"""创建枪头"""
|
||||||
|
return Bottle(
|
||||||
|
name=name,
|
||||||
|
diameter=diameter,
|
||||||
|
height=height,
|
||||||
|
max_volume=max_volume,
|
||||||
|
barcode=barcode,
|
||||||
|
model="BIOYOND_PolymerStation_Pipette_Tip",
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ def bioyond_warehouse_1x2x2(name: str) -> WareHouse:
|
|||||||
"""创建BioYond 4x1x4仓库"""
|
"""创建BioYond 4x1x4仓库"""
|
||||||
return warehouse_factory(
|
return warehouse_factory(
|
||||||
name=name,
|
name=name,
|
||||||
num_items_x=1,
|
num_items_x=2,
|
||||||
num_items_y=2,
|
num_items_y=2,
|
||||||
num_items_z=2,
|
num_items_z=1,
|
||||||
dx=10.0,
|
dx=10.0,
|
||||||
dy=10.0,
|
dy=10.0,
|
||||||
dz=10.0,
|
dz=10.0,
|
||||||
|
|||||||
Reference in New Issue
Block a user