Files
Uni-Lab-OS/unilabos/devices/liquid_handling/prcxi/prcxi_modules.py
ALITTLELZ 9430be51a4 Merge remote-tracking branch 'upstream/prcix9320' into adaptors
# Conflicts:
#	unilabos/devices/liquid_handling/prcxi/prcxi.py
2026-03-25 16:04:17 +08:00

151 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Any, Dict, Optional
from .prcxi import PRCXI9300ModuleSite
class PRCXI9300FunctionalModule(PRCXI9300ModuleSite):
"""
PRCXI 9300 功能模块基类(加热/冷却/震荡/加热震荡/磁吸等)。
设计目标:
- 作为一个可以在工作台上拖拽摆放的实体资源(继承自 PRCXI9300ModuleSite -> ItemizedCarrier
- 顶面存在一个站点site可吸附标准板类资源plate / tip_rack / tube_rack 等)。
- 支持注入 `material_info` (UUID 等),并且在 serialize_state 时做安全过滤。
"""
def __init__(
self,
name: str,
size_x: float,
size_y: float,
size_z: float,
module_type: Optional[str] = None,
category: str = "module",
model: Optional[str] = None,
material_info: Optional[Dict[str, Any]] = None,
**kwargs: Any,
):
super().__init__(
name=name,
size_x=size_x,
size_y=size_y,
size_z=size_z,
material_info=material_info,
model=model,
category=category,
**kwargs,
)
# 记录模块类型(加热 / 冷却 / 震荡 / 加热震荡 / 磁吸)
self.module_type = module_type or "generic"
# 与 PRCXI9300PlateAdapter 一致,使用 _unilabos_state 保存扩展信息
if not hasattr(self, "_unilabos_state") or self._unilabos_state is None:
self._unilabos_state = {}
# super().__init__ 已经在有 material_info 时写入 "Material",这里仅确保存在
if material_info is not None and "Material" not in self._unilabos_state:
self._unilabos_state["Material"] = material_info
# 额外标记 category 和模块类型,便于前端或上层逻辑区分
self._unilabos_state.setdefault("category", category)
self._unilabos_state["module_type"] = module_type
# ============================================================================
# 具体功能模块定义
# 这里的尺寸和 material_info 目前为占位参数,后续可根据实际测量/JSON 配置进行更新。
# 顶面站点尺寸与模块外形一致,保证可以吸附标准 96 板/储液槽等。
# ============================================================================
def PRCXI_Heating_Module(name: str) -> PRCXI9300FunctionalModule:
"""加热模块(顶面可吸附标准板)。"""
return PRCXI9300FunctionalModule(
name=name,
size_x=127.76,
size_y=85.48,
size_z=40.0,
module_type="heating",
model="PRCXI_Heating_Module",
material_info={
"uuid": "TODO-HEATING-MODULE-UUID",
"Code": "HEAT-MOD",
"Name": "PRCXI 加热模块",
"SupplyType": 3,
},
)
def PRCXI_MetalCooling_Module(name: str) -> PRCXI9300FunctionalModule:
"""金属冷却模块(顶面可吸附标准板)。"""
return PRCXI9300FunctionalModule(
name=name,
size_x=127.76,
size_y=85.48,
size_z=40.0,
module_type="metal_cooling",
model="PRCXI_MetalCooling_Module",
material_info={
"uuid": "TODO-METAL-COOLING-MODULE-UUID",
"Code": "METAL-COOL-MOD",
"Name": "PRCXI 金属冷却模块",
"SupplyType": 3,
},
)
def PRCXI_Shaking_Module(name: str) -> PRCXI9300FunctionalModule:
"""震荡模块(顶面可吸附标准板)。"""
return PRCXI9300FunctionalModule(
name=name,
size_x=127.76,
size_y=85.48,
size_z=50.0,
module_type="shaking",
model="PRCXI_Shaking_Module",
material_info={
"uuid": "TODO-SHAKING-MODULE-UUID",
"Code": "SHAKE-MOD",
"Name": "PRCXI 震荡模块",
"SupplyType": 3,
},
)
def PRCXI_Heating_Shaking_Module(name: str) -> PRCXI9300FunctionalModule:
"""加热震荡模块(顶面可吸附标准板)。"""
return PRCXI9300FunctionalModule(
name=name,
size_x=127.76,
size_y=85.48,
size_z=55.0,
module_type="heating_shaking",
model="PRCXI_Heating_Shaking_Module",
material_info={
"uuid": "TODO-HEATING-SHAKING-MODULE-UUID",
"Code": "HEAT-SHAKE-MOD",
"Name": "PRCXI 加热震荡模块",
"SupplyType": 3,
},
)
def PRCXI_Magnetic_Module(name: str) -> PRCXI9300FunctionalModule:
"""磁吸模块(顶面可吸附标准板)。"""
return PRCXI9300FunctionalModule(
name=name,
size_x=127.76,
size_y=85.48,
size_z=30.0,
module_type="magnetic",
model="PRCXI_Magnetic_Module",
material_info={
"uuid": "TODO-MAGNETIC-MODULE-UUID",
"Code": "MAG-MOD",
"Name": "PRCXI 磁吸模块",
"SupplyType": 3,
},
)