mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-11 02:05:12 +00:00
Compare commits
30 Commits
feat/add_c
...
2901d72b4b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2901d72b4b | ||
|
|
6ad0157b50 | ||
|
|
55b678cd37 | ||
|
|
8101a22a0f | ||
|
|
667138baac | ||
|
|
01adf7ca92 | ||
|
|
f606062696 | ||
|
|
67d1c4acce | ||
|
|
7206e42bf1 | ||
|
|
e92d933968 | ||
|
|
f0ebcc60bb | ||
|
|
e2097f0b22 | ||
|
|
fd73731130 | ||
|
|
ab7f2081c9 | ||
|
|
9e850d8a81 | ||
|
|
1af6ffafc6 | ||
|
|
35fc2f5ea6 | ||
|
|
d3d8ba6500 | ||
|
|
5a7845d8ca | ||
|
|
9c4d0256cf | ||
|
|
de7c80c3c2 | ||
|
|
e70c545ec8 | ||
|
|
2c2d1e5569 | ||
|
|
4638611fe7 | ||
|
|
37641c4389 | ||
|
|
ab697ce973 | ||
|
|
d4724b8664 | ||
|
|
2f25063bf1 | ||
|
|
00b4b9cd87 | ||
|
|
d2352cc514 |
14486
bioyond_yihua_YB.json
Normal file
14486
bioyond_yihua_YB.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,13 +24,13 @@
|
|||||||
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
||||||
},
|
},
|
||||||
"material_type_mappings": {
|
"material_type_mappings": {
|
||||||
"烧杯": ["BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"],
|
"烧杯": ["YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"],
|
||||||
"试剂瓶": ["BIOYOND_PolymerStation_1BottleCarrier", ""],
|
"试剂瓶": ["YB_1BottleCarrier", ""],
|
||||||
"样品板": ["BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"],
|
"样品板": ["YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"],
|
||||||
"分装板": ["BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"],
|
"分装板": ["YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"],
|
||||||
"样品瓶": ["BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"],
|
"样品瓶": ["YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"],
|
||||||
"90%分装小瓶": ["BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"],
|
"90%分装小瓶": ["YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"],
|
||||||
"10%分装小瓶": ["BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"]
|
"10%分装小瓶": ["YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deck": {
|
"deck": {
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
"Drip_back": "3a162cf9-6aac-565a-ddd7-682ba1796a4a"
|
||||||
},
|
},
|
||||||
"material_type_mappings": {
|
"material_type_mappings": {
|
||||||
"烧杯": "BIOYOND_PolymerStation_1FlaskCarrier",
|
"烧杯": "YB_1FlaskCarrier",
|
||||||
"试剂瓶": "BIOYOND_PolymerStation_1BottleCarrier",
|
"试剂瓶": "YB_1BottleCarrier",
|
||||||
"样品板": "BIOYOND_PolymerStation_6VialCarrier"
|
"样品板": "YB_6VialCarrier"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deck": {
|
"deck": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from unilabos.resources.bioyond.bottle_carriers import BIOYOND_Electrolyte_6VialCarrier, BIOYOND_Electrolyte_1BottleCarrier
|
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":
|
def test_bottle_carrier() -> "BottleCarrier":
|
||||||
@@ -16,9 +16,9 @@ def test_bottle_carrier() -> "BottleCarrier":
|
|||||||
print(f"1烧杯载架: {beaker_carrier.name}, 位置数: {len(beaker_carrier.sites)}")
|
print(f"1烧杯载架: {beaker_carrier.name}, 位置数: {len(beaker_carrier.sites)}")
|
||||||
|
|
||||||
# 创建瓶子和烧杯
|
# 创建瓶子和烧杯
|
||||||
powder_bottle = BIOYOND_PolymerStation_Solid_Vial("powder_bottle_01")
|
powder_bottle = YB_Solid_Vial("powder_bottle_01")
|
||||||
solution_beaker = BIOYOND_PolymerStation_Solution_Beaker("solution_beaker_01")
|
solution_beaker = YB_Solution_Beaker("solution_beaker_01")
|
||||||
reagent_bottle = BIOYOND_PolymerStation_Reagent_Bottle("reagent_bottle_01")
|
reagent_bottle = YB_Reagent_Bottle("reagent_bottle_01")
|
||||||
|
|
||||||
print(f"\n创建的物料:")
|
print(f"\n创建的物料:")
|
||||||
print(f"粉末瓶: {powder_bottle.name} - {powder_bottle.diameter}mm x {powder_bottle.height}mm, {powder_bottle.max_volume}μL")
|
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 = {
|
type_mapping = {
|
||||||
"烧杯": ("BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||||
"试剂瓶": ("BIOYOND_PolymerStation_1BottleCarrier", ""),
|
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||||
"样品板": ("BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||||
"分装板": ("BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||||
"样品瓶": ("BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||||
"90%分装小瓶": ("BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||||
"10%分装小瓶": ("BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
"10%分装小瓶": ("YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ lab_registry.setup()
|
|||||||
|
|
||||||
|
|
||||||
type_mapping = {
|
type_mapping = {
|
||||||
"烧杯": ("BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||||
"试剂瓶": ("BIOYOND_PolymerStation_1BottleCarrier", ""),
|
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||||
"样品板": ("BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||||
"分装板": ("BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||||
"样品瓶": ("BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||||
"90%分装小瓶": ("BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||||
"10%分装小瓶": ("BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
"10%分装小瓶": ("YB_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,715 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from typing import Dict, Any, List, Optional
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
import pandas as pd
|
||||||
|
import time
|
||||||
|
from datetime import datetime, timezone, timedelta
|
||||||
|
import re
|
||||||
|
import threading
|
||||||
|
from unilabos.devices.workstation.workstation_base import WorkstationBase
|
||||||
|
from unilabos.devices.workstation.workstation_http_service import WorkstationHTTPService
|
||||||
|
from unilabos.utils.log import logger
|
||||||
|
from pylabrobot.resources.deck import Deck
|
||||||
|
|
||||||
|
|
||||||
|
def _iso_utc_now_ms() -> str:
|
||||||
|
# 文档要求:到毫秒 + Z,例如 2025-08-15T05:43:22.814Z
|
||||||
|
dt = datetime.now(timezone.utc)
|
||||||
|
return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{int(dt.microsecond/1000):03d}Z"
|
||||||
|
|
||||||
|
|
||||||
|
class BioyondWorkstation(WorkstationBase):
|
||||||
|
"""
|
||||||
|
集成 Bioyond LIMS 的工作站示例,
|
||||||
|
覆盖:入库(2.17/2.18) → 新建实验(2.14) → 启动调度(2.7) →
|
||||||
|
运行中推送:物料变更(2.24)、步骤完成(2.21)、订单完成(2.23) →
|
||||||
|
查询实验(2.5/2.6) → 3-2-1 转运(2.32) → 样品/废料取出(2.28)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
bioyond_config: Optional[Dict[str, Any]] = None,
|
||||||
|
station_resource: Optional[Dict[str, Any]] = None,
|
||||||
|
debug_mode: bool = False, # 增加调试模式开关
|
||||||
|
*args, **kwargs,
|
||||||
|
):
|
||||||
|
self.bioyond_config = bioyond_config or {
|
||||||
|
"base_url": "http://192.168.1.200:44386",
|
||||||
|
"api_key": "8A819E5C",
|
||||||
|
"timeout": 30,
|
||||||
|
"report_token": "CHANGE_ME_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.http_service_started = False
|
||||||
|
self.debug_mode = debug_mode
|
||||||
|
super().__init__(deck=Deck, station_resource=station_resource, *args, **kwargs)
|
||||||
|
logger.info(f"Bioyond工作站初始化完成 (debug_mode={self.debug_mode})")
|
||||||
|
|
||||||
|
# 实例化并在后台线程启动 HTTP 报送服务
|
||||||
|
self.order_status = {}
|
||||||
|
try:
|
||||||
|
t = threading.Thread(target=self._start_http_service_bg, daemon=True, name="unilab_http")
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"unilab-server后台启动报送服务失败: {e}")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_id(self) -> str:
|
||||||
|
try:
|
||||||
|
return getattr(self, "_ros_node").device_id # 兼容 ROS 场景
|
||||||
|
except Exception:
|
||||||
|
return "bioyond_workstation"
|
||||||
|
|
||||||
|
def _start_http_service_bg(self, host: str = "192.168.1.104", port: int = 8080) -> None:
|
||||||
|
logger.info("进入 _start_http_service_bg 函数")
|
||||||
|
try:
|
||||||
|
self.service = WorkstationHTTPService(self, host=host, port=port)
|
||||||
|
logger.info("WorkstationHTTPService 实例化完成")
|
||||||
|
self.service.start()
|
||||||
|
self.http_service_started = True
|
||||||
|
logger.info(f"unilab_HTTP 服务成功启动: {host}:{port}")
|
||||||
|
|
||||||
|
#一直挂着,直到进程退出
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.http_service_started = False
|
||||||
|
logger.error(f"启动unilab_HTTP服务失败: {e}", exc_info=True)
|
||||||
|
|
||||||
|
# -------------------- 基础HTTP封装 --------------------
|
||||||
|
def _url(self, path: str) -> str:
|
||||||
|
return f"{self.bioyond_config['base_url'].rstrip('/')}/{path.lstrip('/')}"
|
||||||
|
|
||||||
|
def _post_lims(self, path: str, data: Optional[Any] = None) -> Dict[str, Any]:
|
||||||
|
"""LIMS API:大多数接口用 {apiKey/requestTime,data} 包装"""
|
||||||
|
payload = {
|
||||||
|
"apiKey": self.bioyond_config["api_key"],
|
||||||
|
"requestTime": _iso_utc_now_ms()
|
||||||
|
}
|
||||||
|
if data is not None:
|
||||||
|
payload["data"] = data
|
||||||
|
|
||||||
|
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:
|
||||||
|
r = requests.post(
|
||||||
|
self._url(path),
|
||||||
|
json=payload,
|
||||||
|
timeout=self.bioyond_config.get("timeout", 30),
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"POST {path} 失败: {e}")
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
# --- 修正:_post_report / _post_report_raw 同样走 debug_mode ---
|
||||||
|
def _post_report(self, path: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
payload = {
|
||||||
|
"token": self.bioyond_config.get("report_token", ""),
|
||||||
|
"request_time": _iso_utc_now_ms(),
|
||||||
|
"data": data
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
r = requests.post(self._url(path), json=payload,
|
||||||
|
timeout=self.bioyond_config.get("timeout", 30),
|
||||||
|
headers={"Content-Type": "application/json"})
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"POST {path} 失败: {e}")
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
def _post_report_raw(self, path: str, body: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
if self.debug_mode:
|
||||||
|
logger.info(f"[DEBUG] POST {path} with body={body}")
|
||||||
|
return {"debug": True, "url": self._url(path), "payload": body, "status": "ok"}
|
||||||
|
try:
|
||||||
|
r = requests.post(self._url(path), json=body,
|
||||||
|
timeout=self.bioyond_config.get("timeout", 30),
|
||||||
|
headers={"Content-Type": "application/json"})
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"POST {path} 失败: {e}")
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------- 单点接口封装 --------------------
|
||||||
|
# 2.17 入库物料(单个)
|
||||||
|
def storage_inbound(self, material_id: str, location_id: str) -> Dict[str, Any]:
|
||||||
|
return self._post_lims("/api/lims/storage/inbound", {
|
||||||
|
"materialId": material_id,
|
||||||
|
"locationId": location_id
|
||||||
|
})
|
||||||
|
|
||||||
|
# 2.18 批量入库(多个)
|
||||||
|
def storage_batch_inbound(self, items: List[Dict[str, str]]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
items = [{"materialId": "...", "locationId": "..."}, ...]
|
||||||
|
"""
|
||||||
|
return self._post_lims("/api/lims/storage/batch-inbound", items)
|
||||||
|
|
||||||
|
# 3.30 自动化上料(Excel -> JSON -> POST /api/lims/order/auto-feeding4to3)
|
||||||
|
def auto_feeding4to3_from_xlsx(self, xlsx_path: str) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
根据固定模板解析 Excel:
|
||||||
|
- 四号手套箱加样头面 (2-13行, 3-7列)
|
||||||
|
- 四号手套箱原液瓶面 (15-23行, 3-9列)
|
||||||
|
- 三号手套箱人工堆栈 (26-40行, 3-7列)
|
||||||
|
"""
|
||||||
|
path = Path(xlsx_path)
|
||||||
|
if not path.exists():
|
||||||
|
raise FileNotFoundError(f"未找到 Excel 文件:{path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
df = pd.read_excel(path, sheet_name=0, header=None, engine="openpyxl")
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeError(f"读取 Excel 失败:{e}")
|
||||||
|
|
||||||
|
items: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
# 四号手套箱 - 加样头面(2-13行, 3-7列)
|
||||||
|
for _, row in df.iloc[1:13, 2:7].iterrows():
|
||||||
|
item = {
|
||||||
|
"sourceWHName": "四号手套箱堆栈",
|
||||||
|
"posX": int(row[2]),
|
||||||
|
"posY": int(row[3]),
|
||||||
|
"posZ": int(row[4]),
|
||||||
|
"materialName": str(row[5]).strip() if pd.notna(row[5]) else "",
|
||||||
|
"quantity": float(row[6]) if pd.notna(row[6]) else 0.0,
|
||||||
|
}
|
||||||
|
if item["materialName"]:
|
||||||
|
items.append(item)
|
||||||
|
|
||||||
|
# 四号手套箱 - 原液瓶面(15-23行, 3-9列)
|
||||||
|
for _, row in df.iloc[14:23, 2:9].iterrows():
|
||||||
|
item = {
|
||||||
|
"sourceWHName": "四号手套箱堆栈",
|
||||||
|
"posX": int(row[2]),
|
||||||
|
"posY": int(row[3]),
|
||||||
|
"posZ": int(row[4]),
|
||||||
|
"materialName": str(row[5]).strip() if pd.notna(row[5]) else "",
|
||||||
|
"quantity": float(row[6]) if pd.notna(row[6]) else 0.0,
|
||||||
|
"materialType": str(row[7]).strip() if pd.notna(row[7]) else "",
|
||||||
|
"targetWH": str(row[8]).strip() if pd.notna(row[8]) else "",
|
||||||
|
}
|
||||||
|
if item["materialName"]:
|
||||||
|
items.append(item)
|
||||||
|
|
||||||
|
# 三号手套箱人工堆栈(26-40行, 3-7列)
|
||||||
|
for _, row in df.iloc[25:40, 2:7].iterrows():
|
||||||
|
item = {
|
||||||
|
"sourceWHName": "三号手套箱人工堆栈",
|
||||||
|
"posX": int(row[2]),
|
||||||
|
"posY": int(row[3]),
|
||||||
|
"posZ": int(row[4]),
|
||||||
|
"materialType": str(row[5]).strip() if pd.notna(row[5]) else "",
|
||||||
|
"materialId": str(row[6]).strip() if pd.notna(row[6]) else "",
|
||||||
|
"quantity": 1 # 默认数量1
|
||||||
|
}
|
||||||
|
if item["materialId"] or item["materialType"]:
|
||||||
|
items.append(item)
|
||||||
|
|
||||||
|
return self._post_lims("/api/lims/order/auto-feeding4to3", items)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def auto_batch_outbound_from_xlsx(self, xlsx_path: str) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
3.31 自动化下料(Excel -> JSON -> POST /api/lims/storage/auto-batch-out-bound)
|
||||||
|
"""
|
||||||
|
path = Path(xlsx_path)
|
||||||
|
if not path.exists():
|
||||||
|
raise FileNotFoundError(f"未找到 Excel 文件:{path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
df = pd.read_excel(path, sheet_name=0, engine="openpyxl")
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeError(f"读取 Excel 失败:{e}")
|
||||||
|
|
||||||
|
def pick(names: List[str]) -> Optional[str]:
|
||||||
|
for n in names:
|
||||||
|
if n in df.columns:
|
||||||
|
return n
|
||||||
|
return None
|
||||||
|
|
||||||
|
c_loc = pick(["locationId", "库位ID", "库位Id", "库位id"])
|
||||||
|
c_wh = pick(["warehouseId", "仓库ID", "仓库Id", "仓库id"])
|
||||||
|
c_qty = pick(["数量", "quantity"])
|
||||||
|
c_x = pick(["x", "X", "posX", "坐标X"])
|
||||||
|
c_y = pick(["y", "Y", "posY", "坐标Y"])
|
||||||
|
c_z = pick(["z", "Z", "posZ", "坐标Z"])
|
||||||
|
|
||||||
|
required = [c_loc, c_wh, c_qty, c_x, c_y, c_z]
|
||||||
|
if any(c is None for c in required):
|
||||||
|
raise KeyError("Excel 缺少必要列:locationId/warehouseId/数量/x/y/z(支持多别名,至少要能匹配到)。")
|
||||||
|
|
||||||
|
def as_int(v, d=0):
|
||||||
|
try:
|
||||||
|
if pd.isna(v): return d
|
||||||
|
return int(v)
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
return int(float(v))
|
||||||
|
except Exception:
|
||||||
|
return d
|
||||||
|
|
||||||
|
def as_float(v, d=0.0):
|
||||||
|
try:
|
||||||
|
if pd.isna(v): return d
|
||||||
|
return float(v)
|
||||||
|
except Exception:
|
||||||
|
return d
|
||||||
|
|
||||||
|
def as_str(v, d=""):
|
||||||
|
if v is None or (isinstance(v, float) and pd.isna(v)): return d
|
||||||
|
s = str(v).strip()
|
||||||
|
return s if s else d
|
||||||
|
|
||||||
|
items: List[Dict[str, Any]] = []
|
||||||
|
for _, row in df.iterrows():
|
||||||
|
items.append({
|
||||||
|
"locationId": as_str(row[c_loc]),
|
||||||
|
"warehouseId": as_str(row[c_wh]),
|
||||||
|
"quantity": as_float(row[c_qty]),
|
||||||
|
"x": as_int(row[c_x]),
|
||||||
|
"y": as_int(row[c_y]),
|
||||||
|
"z": as_int(row[c_z]),
|
||||||
|
})
|
||||||
|
|
||||||
|
return self._post_lims("/api/lims/storage/auto-batch-out-bound", items)
|
||||||
|
|
||||||
|
# 2.14 新建实验
|
||||||
|
def create_orders(self, xlsx_path: str) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
从 Excel 解析并创建实验(2.14)
|
||||||
|
约定:
|
||||||
|
- batchId = Excel 文件名(不含扩展名)
|
||||||
|
- 物料列:所有以 "(g)" 结尾(不再读取“总质量(g)”列)
|
||||||
|
- totalMass 自动计算为所有物料质量之和
|
||||||
|
- createTime 缺失或为空时自动填充为当前日期(YYYY/M/D)
|
||||||
|
"""
|
||||||
|
path = Path(xlsx_path)
|
||||||
|
if not path.exists():
|
||||||
|
raise FileNotFoundError(f"未找到 Excel 文件:{path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
df = pd.read_excel(path, sheet_name=0, engine="openpyxl")
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeError(f"读取 Excel 失败:{e}")
|
||||||
|
|
||||||
|
# 列名容错:返回可选列名,找不到则返回 None
|
||||||
|
def _pick(col_names: List[str]) -> Optional[str]:
|
||||||
|
for c in col_names:
|
||||||
|
if c in df.columns:
|
||||||
|
return c
|
||||||
|
return None
|
||||||
|
|
||||||
|
col_order_name = _pick(["配方ID", "orderName", "订单编号"])
|
||||||
|
col_create_time = _pick(["创建日期", "createTime"])
|
||||||
|
col_bottle_type = _pick(["配液瓶类型", "bottleType"])
|
||||||
|
col_mix_time = _pick(["混匀时间(s)", "mixTime"])
|
||||||
|
col_load = _pick(["扣电组装分液体积", "loadSheddingInfo"])
|
||||||
|
col_pouch = _pick(["软包组装分液体积", "pouchCellInfo"])
|
||||||
|
col_cond = _pick(["电导测试分液体积", "conductivityInfo"])
|
||||||
|
col_cond_cnt = _pick(["电导测试分液瓶数", "conductivityBottleCount"])
|
||||||
|
|
||||||
|
# 物料列:所有以 (g) 结尾
|
||||||
|
material_cols = [c for c in df.columns if isinstance(c, str) and c.endswith("(g)")]
|
||||||
|
if not material_cols:
|
||||||
|
raise KeyError("未发现任何以“(g)”结尾的物料列,请检查表头。")
|
||||||
|
|
||||||
|
batch_id = path.stem
|
||||||
|
|
||||||
|
def _to_ymd_slash(v) -> str:
|
||||||
|
# 统一为 "YYYY/M/D";为空或解析失败则用当前日期
|
||||||
|
if v is None or (isinstance(v, float) and pd.isna(v)) or str(v).strip() == "":
|
||||||
|
ts = datetime.now()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
ts = pd.to_datetime(v)
|
||||||
|
except Exception:
|
||||||
|
ts = datetime.now()
|
||||||
|
return f"{ts.year}/{ts.month}/{ts.day}"
|
||||||
|
|
||||||
|
def _as_int(val, default=0) -> int:
|
||||||
|
try:
|
||||||
|
if pd.isna(val):
|
||||||
|
return default
|
||||||
|
return int(val)
|
||||||
|
except Exception:
|
||||||
|
return default
|
||||||
|
|
||||||
|
def _as_str(val, default="") -> str:
|
||||||
|
if val is None or (isinstance(val, float) and pd.isna(val)):
|
||||||
|
return default
|
||||||
|
s = str(val).strip()
|
||||||
|
return s if s else default
|
||||||
|
|
||||||
|
orders: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
for idx, row in df.iterrows():
|
||||||
|
mats: List[Dict[str, Any]] = []
|
||||||
|
total_mass = 0.0
|
||||||
|
|
||||||
|
for mcol in material_cols:
|
||||||
|
val = row.get(mcol, None)
|
||||||
|
if val is None or (isinstance(val, float) and pd.isna(val)):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
mass = float(val)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
if mass > 0:
|
||||||
|
mats.append({"name": mcol.replace("(g)", ""), "mass": mass})
|
||||||
|
total_mass += mass
|
||||||
|
|
||||||
|
order_data = {
|
||||||
|
"batchId": batch_id,
|
||||||
|
"orderName": _as_str(row[col_order_name], default=f"{batch_id}_order_{idx+1}") if col_order_name else f"{batch_id}_order_{idx+1}",
|
||||||
|
"createTime": _to_ymd_slash(row[col_create_time]) if col_create_time else _to_ymd_slash(None),
|
||||||
|
"bottleType": _as_str(row[col_bottle_type], default="配液小瓶") if col_bottle_type else "配液小瓶",
|
||||||
|
"mixTime": _as_int(row[col_mix_time]) if col_mix_time else 0,
|
||||||
|
"loadSheddingInfo": _as_int(row[col_load]) if col_load else 0,
|
||||||
|
"pouchCellInfo": _as_int(row[col_pouch]) if col_pouch else 0,
|
||||||
|
"conductivityInfo": _as_int(row[col_cond]) if col_cond else 0,
|
||||||
|
"conductivityBottleCount": _as_int(row[col_cond_cnt]) if col_cond_cnt else 0,
|
||||||
|
"materialInfos": mats,
|
||||||
|
"totalMass": round(total_mass, 4) # 自动汇总
|
||||||
|
}
|
||||||
|
orders.append(order_data)
|
||||||
|
|
||||||
|
# print(orders)
|
||||||
|
|
||||||
|
response = self._post_lims("/api/lims/order/orders", orders)
|
||||||
|
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()
|
||||||
|
r321 = self.wait_for_transfer_task()
|
||||||
|
logger.info(f"3-2-1 转运完成,返回结果")
|
||||||
|
return r321
|
||||||
|
|
||||||
|
|
||||||
|
# 2.7 启动调度
|
||||||
|
def scheduler_start(self) -> Dict[str, Any]:
|
||||||
|
return self._post_lims("/api/lims/scheduler/start")
|
||||||
|
# 3.10 停止调度
|
||||||
|
def scheduler_stop(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
停止调度 (3.10)
|
||||||
|
请求体只包含 apiKey 和 requestTime
|
||||||
|
"""
|
||||||
|
return self._post_lims("/api/lims/scheduler/stop")
|
||||||
|
# 2.9 继续调度
|
||||||
|
def scheduler_continue(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
继续调度 (2.9)
|
||||||
|
请求体只包含 apiKey 和 requestTime
|
||||||
|
"""
|
||||||
|
return self._post_lims("/api/lims/scheduler/continue")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 2.24 物料变更推送
|
||||||
|
def report_material_change(self, material_obj: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
material_obj 按 2.24 的裸对象格式(包含 id/typeName/locations/detail 等)
|
||||||
|
"""
|
||||||
|
return self._post_report_raw("/report/material_change", material_obj)
|
||||||
|
|
||||||
|
# 2.21 步骤完成推送(BS → LIMS)
|
||||||
|
def report_step_finish(self,
|
||||||
|
order_code: str,
|
||||||
|
order_name: str,
|
||||||
|
step_name: str,
|
||||||
|
step_id: str,
|
||||||
|
sample_id: str,
|
||||||
|
start_time: str,
|
||||||
|
end_time: str,
|
||||||
|
execution_status: str = "completed") -> Dict[str, Any]:
|
||||||
|
data = {
|
||||||
|
"orderCode": order_code,
|
||||||
|
"orderName": order_name,
|
||||||
|
"stepName": step_name,
|
||||||
|
"stepId": step_id,
|
||||||
|
"sampleId": sample_id,
|
||||||
|
"startTime": start_time,
|
||||||
|
"endTime": end_time,
|
||||||
|
"executionStatus": execution_status
|
||||||
|
}
|
||||||
|
return self._post_report("/report/step_finish", data)
|
||||||
|
|
||||||
|
# 2.23 订单完成推送(BS → LIMS)
|
||||||
|
def report_order_finish(self,
|
||||||
|
order_code: str,
|
||||||
|
order_name: str,
|
||||||
|
start_time: str,
|
||||||
|
end_time: str,
|
||||||
|
status: str = "30", # 30 完成 / -11 异常停止 / -12 人工停止
|
||||||
|
workflow_status: str = "Finished",
|
||||||
|
completion_time: Optional[str] = None,
|
||||||
|
used_materials: Optional[List[Dict[str, Any]]] = None) -> Dict[str, Any]:
|
||||||
|
data = {
|
||||||
|
"orderCode": order_code,
|
||||||
|
"orderName": order_name,
|
||||||
|
"startTime": start_time,
|
||||||
|
"endTime": end_time,
|
||||||
|
"status": status,
|
||||||
|
"workflowStatus": workflow_status,
|
||||||
|
"completionTime": completion_time or end_time,
|
||||||
|
"usedMaterials": used_materials or []
|
||||||
|
}
|
||||||
|
return self._post_report("/report/order_finish", data)
|
||||||
|
|
||||||
|
# 2.5 批量查询实验报告(用于轮询是否完成)
|
||||||
|
def order_list(self,
|
||||||
|
status: Optional[str] = None,
|
||||||
|
begin_time: Optional[str] = None,
|
||||||
|
end_time: Optional[str] = None,
|
||||||
|
filter_text: Optional[str] = None,
|
||||||
|
skip: int = 0, page: int = 10) -> Dict[str, Any]:
|
||||||
|
data: Dict[str, Any] = {"skipCount": skip, "pageCount": page}
|
||||||
|
if status is not None: # 80 成功 / 90 失败 / 100 执行中
|
||||||
|
data["status"] = status
|
||||||
|
if begin_time:
|
||||||
|
data["timeType"] = "CreationTime"
|
||||||
|
data["beginTime"] = begin_time
|
||||||
|
if end_time:
|
||||||
|
data["endTime"] = end_time
|
||||||
|
if filter_text:
|
||||||
|
data["filter"] = filter_text
|
||||||
|
return self._post_lims("/api/lims/order/order-list", data)
|
||||||
|
|
||||||
|
# 2.6 实验报告查询(根据任务ID拿详情)
|
||||||
|
def order_report(self, order_id: str) -> Dict[str, Any]:
|
||||||
|
return self._post_lims("/api/lims/order/order-report", order_id)
|
||||||
|
|
||||||
|
# 2.32 3-2-1 物料转运
|
||||||
|
def transfer_3_to_2_to_1(self,
|
||||||
|
# source_wh_id: Optional[str] = None,
|
||||||
|
source_wh_id: Optional[str] = '3a19debc-84b4-0359-e2d4-b3beea49348b',
|
||||||
|
source_x: int = 1, source_y: int = 1, source_z: int = 1) -> Dict[str, Any]:
|
||||||
|
payload: Dict[str, Any] = {
|
||||||
|
"sourcePosX": source_x, "sourcePosY": source_y, "sourcePosZ": source_z
|
||||||
|
}
|
||||||
|
if source_wh_id:
|
||||||
|
payload["sourceWHID"] = source_wh_id
|
||||||
|
return self._post_lims("/api/lims/order/transfer-task3To2To1", payload)
|
||||||
|
|
||||||
|
# 2.28 样品/废料取出
|
||||||
|
def take_out(self,
|
||||||
|
order_id: str,
|
||||||
|
preintake_ids: Optional[List[str]] = None,
|
||||||
|
material_ids: Optional[List[str]] = None) -> Dict[str, Any]:
|
||||||
|
data = {
|
||||||
|
"orderId": order_id,
|
||||||
|
"preintakeIds": preintake_ids or [],
|
||||||
|
"materialIds": material_ids or []
|
||||||
|
}
|
||||||
|
return self._post_lims("/api/lims/order/take-out", data)
|
||||||
|
|
||||||
|
# --------(可选)占位方法:文档未定义的“1号站内部流程 / 1-2转运”--------
|
||||||
|
def start_station1_internal_flow(self, **kwargs) -> None:
|
||||||
|
logger.info("启动1号站内部流程(占位,按现场系统填充具体指令)")
|
||||||
|
|
||||||
|
|
||||||
|
# 3.x 1→2 物料转运
|
||||||
|
def transfer_1_to_2(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
1→2 物料转运
|
||||||
|
URL: /api/lims/order/transfer-task1To2
|
||||||
|
只需要 apiKey 和 requestTime
|
||||||
|
"""
|
||||||
|
return self._post_lims("/api/lims/order/transfer-task1To2")
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------- 整体编排 --------------------
|
||||||
|
def run_full_workflow(self,
|
||||||
|
inbound_items: List[Dict[str, str]],
|
||||||
|
orders: List[Dict[str, Any]],
|
||||||
|
poll_filter_code: Optional[str] = None,
|
||||||
|
poll_timeout_s: int = 600,
|
||||||
|
poll_interval_s: int = 5,
|
||||||
|
transfer_source: Optional[Dict[str, Any]] = None,
|
||||||
|
takeout_order_id: Optional[str] = None) -> None:
|
||||||
|
"""
|
||||||
|
一键串联:
|
||||||
|
1) 入库 3-4 个物料 → 2) 新建实验 → 3) 启动调度
|
||||||
|
运行中(如需):4) 物料变更推送 5) 步骤完成推送 6) 订单完成推送
|
||||||
|
完成后:查询实验(2.5/2.6)→ 7) 3-2-1 转运 → 8) 1号站内部流程
|
||||||
|
→ 9) 1-2 转运 → 10) 样品/废料取出
|
||||||
|
"""
|
||||||
|
# 1. 入库(多于1个就用批量接口 2.18)
|
||||||
|
if len(inbound_items) == 1:
|
||||||
|
r = self.storage_inbound(inbound_items[0]["materialId"], inbound_items[0]["locationId"])
|
||||||
|
logger.info(f"单个入库结果: {r}")
|
||||||
|
else:
|
||||||
|
r = self.storage_batch_inbound(inbound_items)
|
||||||
|
logger.info(f"批量入库结果: {r}")
|
||||||
|
|
||||||
|
# 2. 新建实验(2.14)
|
||||||
|
r = self.create_orders(orders)
|
||||||
|
logger.info(f"新建实验结果: {r}")
|
||||||
|
|
||||||
|
# 3. 启动调度(2.7)
|
||||||
|
r = self.scheduler_start()
|
||||||
|
logger.info(f"启动调度结果: {r}")
|
||||||
|
|
||||||
|
# —— 运行中各类推送(2.24 / 2.21 / 2.23),通常由实际任务驱动,这里提供调用方式 —— #
|
||||||
|
# self.report_material_change({...})
|
||||||
|
# self.report_step_finish(order_code="BSO...", order_name="配液分液", step_name="xxx", step_id="...", sample_id="...",
|
||||||
|
# start_time=_iso_utc_now_ms(), end_time=_iso_utc_now_ms(), execution_status="completed")
|
||||||
|
# self.report_order_finish(order_code="BSO...", order_name="配液分液", start_time="...", end_time=_iso_utc_now_ms())
|
||||||
|
|
||||||
|
# 完成后才能转运:用 2.5 批量查询配合 filter=任务编码 轮询到 status=80(成功)
|
||||||
|
if poll_filter_code:
|
||||||
|
import time
|
||||||
|
deadline = time.time() + poll_timeout_s
|
||||||
|
while time.time() < deadline:
|
||||||
|
res = self.order_list(status="80", filter_text=poll_filter_code, page=5)
|
||||||
|
if isinstance(res, dict) and res.get("data", {}).get("items"):
|
||||||
|
logger.info(f"实验 {poll_filter_code} 已完成:{res['data']['items'][0]}")
|
||||||
|
break
|
||||||
|
time.sleep(poll_interval_s)
|
||||||
|
else:
|
||||||
|
logger.warning(f"等待实验 {poll_filter_code} 完成超时(未到 status=80)")
|
||||||
|
|
||||||
|
# 7. 启动 3-2-1 转运(2.32)
|
||||||
|
if transfer_source:
|
||||||
|
r = self.transfer_3_to_2_to_1(
|
||||||
|
source_wh_id=transfer_source.get("sourceWHID"),
|
||||||
|
source_x=transfer_source.get("sourcePosX", 1),
|
||||||
|
source_y=transfer_source.get("sourcePosY", 1),
|
||||||
|
source_z=transfer_source.get("sourcePosZ", 1),
|
||||||
|
)
|
||||||
|
logger.info(f"3-2-1 转运结果: {r}")
|
||||||
|
|
||||||
|
# 8. 1号站内部流程(占位)
|
||||||
|
self.start_station1_internal_flow()
|
||||||
|
|
||||||
|
# 9. 1→2 转运(占位)
|
||||||
|
self.transfer_1_to_2()
|
||||||
|
|
||||||
|
# 10. 样品/废料取出(2.28)
|
||||||
|
if takeout_order_id:
|
||||||
|
r = self.take_out(order_id=takeout_order_id)
|
||||||
|
logger.info(f"样品/废料取出结果: {r}")
|
||||||
|
|
||||||
|
# 2.5 批量查询实验报告
|
||||||
|
def order_list_v2(self,
|
||||||
|
timeType: str = "string",
|
||||||
|
beginTime: str = "",
|
||||||
|
endTime: str = "",
|
||||||
|
status: str = "",
|
||||||
|
filter: str = "物料转移任务",
|
||||||
|
skipCount: int = 0,
|
||||||
|
pageCount: int = 1,
|
||||||
|
sorting: str = "") -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
批量查询实验报告的详细信息 (2.5)
|
||||||
|
URL: /api/lims/order/order-list
|
||||||
|
参数默认值和接口文档保持一致
|
||||||
|
"""
|
||||||
|
data: Dict[str, Any] = {
|
||||||
|
"timeType": timeType,
|
||||||
|
"beginTime": beginTime,
|
||||||
|
"endTime": endTime,
|
||||||
|
"status": status,
|
||||||
|
"filter": filter,
|
||||||
|
"skipCount": skipCount,
|
||||||
|
"pageCount": pageCount,
|
||||||
|
"sorting": sorting
|
||||||
|
}
|
||||||
|
return self._post_lims("/api/lims/order/order-list", data)
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_transfer_task(self, timeout: int = 600, interval: int = 3) -> bool:
|
||||||
|
"""
|
||||||
|
轮询查询物料转移任务是否成功完成 (status=80)
|
||||||
|
- timeout: 最大等待秒数 (默认600秒)
|
||||||
|
- interval: 轮询间隔秒数 (默认3秒)
|
||||||
|
返回 True 表示找到并成功完成,False 表示超时未找到
|
||||||
|
"""
|
||||||
|
now = datetime.now()
|
||||||
|
beginTime = now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
endTime = (now + timedelta(minutes=5)).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
print(beginTime, endTime)
|
||||||
|
|
||||||
|
deadline = time.time() + timeout
|
||||||
|
|
||||||
|
while time.time() < deadline:
|
||||||
|
result = self.order_list_v2(
|
||||||
|
timeType="string",
|
||||||
|
beginTime=beginTime,
|
||||||
|
endTime=endTime,
|
||||||
|
status="",
|
||||||
|
filter="物料转移任务",
|
||||||
|
skipCount=0,
|
||||||
|
pageCount=1,
|
||||||
|
sorting=""
|
||||||
|
)
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
items = result.get("data", {}).get("items", [])
|
||||||
|
for item in items:
|
||||||
|
name = item.get("name", "")
|
||||||
|
status = item.get("status")
|
||||||
|
if name.startswith("物料转移任务") and status == 80:
|
||||||
|
logger.info(f"硬件转移动作完成: {name}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
time.sleep(interval)
|
||||||
|
|
||||||
|
logger.warning("超时未找到成功的物料转移任务")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ws = BioyondWorkstation()
|
||||||
|
# ws.scheduler_stop()
|
||||||
|
ws.scheduler_start()
|
||||||
|
logger.info("调度启动完成")
|
||||||
|
|
||||||
|
# ws.scheduler_continue()
|
||||||
|
# 3.30 上料:读取模板 Excel 自动解析并 POST
|
||||||
|
r1 = ws.auto_feeding4to3_from_xlsx(r"C:\ML\GitHub\Uni-Lab-OS\unilabos\devices\workstation\bioyond_cell\样品导入模板 (8).xlsx")
|
||||||
|
ws.wait_for_transfer_task()
|
||||||
|
logger.info("4号箱向3号箱转运物料转移任务已完成")
|
||||||
|
|
||||||
|
# ws.scheduler_start()
|
||||||
|
# print(r1["payload"]["data"]) # 调试模式下可直接看到要发的 JSON items
|
||||||
|
|
||||||
|
# 新建实验
|
||||||
|
res = ws.create_orders("C:/ML/GitHub/Uni-Lab-OS/unilabos/devices/workstation/bioyond_cell/2025092501.xlsx")
|
||||||
|
# ws.scheduler_start()
|
||||||
|
# print(res)
|
||||||
|
|
||||||
|
#1号站启动
|
||||||
|
ws.transfer_1_to_2()
|
||||||
|
ws.wait_for_transfer_task()
|
||||||
|
logger.info("1号站向2号站转移任务完成")
|
||||||
|
logger.info("全流程结束")
|
||||||
|
|
||||||
|
# 3.31 下料:同理
|
||||||
|
# r2 = ws.auto_batch_outbound_from_xlsx(r"C:/path/样品导入模板 (8).xlsx")
|
||||||
|
# print(r2["payload"]["data"])
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
material_name
|
||||||
|
LiPF6
|
||||||
|
LiDFOB
|
||||||
|
DTD
|
||||||
|
LiFSI
|
||||||
|
LiPO2F2
|
||||||
|
|
||||||
|
Binary file not shown.
@@ -47,8 +47,8 @@ class BioyondV1RPC(BaseRequest):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
print("开始初始化 BioyondV1RPC")
|
print("开始初始化 BioyondV1RPC")
|
||||||
self.config = config
|
self.config = config
|
||||||
self.api_key = config["api_key"]
|
self.api_key = config.get("api_key", "")
|
||||||
self.host = config["api_host"]
|
self.host = config.get("api_host", "") or config.get("base_url", "")
|
||||||
self._logger = SimpleLogger()
|
self._logger = SimpleLogger()
|
||||||
self.material_cache = {}
|
self.material_cache = {}
|
||||||
self._load_material_cache()
|
self._load_material_cache()
|
||||||
@@ -61,7 +61,7 @@ class BioyondV1RPC(BaseRequest):
|
|||||||
|
|
||||||
:return: 当前时间的 ISO 8601 格式字符串
|
:return: 当前时间的 ISO 8601 格式字符串
|
||||||
"""
|
"""
|
||||||
current_time = datetime.now(timezone.utc).isoformat(
|
current_time = datetime.now().isoformat(
|
||||||
timespec='milliseconds'
|
timespec='milliseconds'
|
||||||
)
|
)
|
||||||
# 替换时区部分为 'Z'
|
# 替换时区部分为 'Z'
|
||||||
|
|||||||
@@ -2,137 +2,242 @@
|
|||||||
"""
|
"""
|
||||||
配置文件 - 包含所有配置信息和映射关系
|
配置文件 - 包含所有配置信息和映射关系
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
# API配置
|
# ==================== API 基础配置 ====================
|
||||||
|
|
||||||
|
|
||||||
|
# ==================== 完整的 Bioyond 配置 ====================
|
||||||
|
# BioyondCellWorkstation 默认配置(包含所有必需参数)
|
||||||
API_CONFIG = {
|
API_CONFIG = {
|
||||||
"api_key": "",
|
# API 连接配置
|
||||||
"api_host": ""
|
"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")),
|
||||||
# 工作流映射配置
|
|
||||||
WORKFLOW_MAPPINGS = {
|
# 报送配置
|
||||||
"reactor_taken_out": "",
|
"report_token": os.getenv("BIOYOND_REPORT_TOKEN", "CHANGE_ME_TOKEN"),
|
||||||
"reactor_taken_in": "",
|
|
||||||
"Solid_feeding_vials": "",
|
# HTTP 服务配置
|
||||||
"Liquid_feeding_vials(non-titration)": "",
|
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "0.0.0.0"), # HTTP服务监听地址(0.0.0.0 表示监听所有网络接口)
|
||||||
"Liquid_feeding_solvents": "",
|
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
|
||||||
"Liquid_feeding(titration)": "",
|
"report_ip": os.getenv("BIOYOND_REPORT_IP", "172.21.32.22"), # 报送给 Bioyond 的本机IP地址(留空则自动检测)
|
||||||
"liquid_feeding_beaker": "",
|
# 调试模式
|
||||||
"Drip_back": "",
|
"debug_mode": False,
|
||||||
}
|
|
||||||
|
|
||||||
# 工作流名称到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': '反应器取出'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 库位映射配置
|
# 库位映射配置
|
||||||
WAREHOUSE_MAPPING = {
|
WAREHOUSE_MAPPING = {
|
||||||
"粉末堆栈": {
|
"粉末加样头堆栈": {
|
||||||
"uuid": "",
|
"uuid": "",
|
||||||
"site_uuids": {
|
"site_uuids": {
|
||||||
# 样品板
|
"A01": "3a19da56-1379-ff7c-1745-07e200b44ce2",
|
||||||
"A1": "3a14198e-6929-31f0-8a22-0f98f72260df",
|
"B01": "3a19da56-1379-2424-d751-fe6e94cef938",
|
||||||
"A2": "3a14198e-6929-4379-affa-9a2935c17f99",
|
"C01": "3a19da56-1379-271c-03e3-6bdb590e395e",
|
||||||
"A3": "3a14198e-6929-56da-9a1c-7f5fbd4ae8af",
|
"D01": "3a19da56-1379-277f-2b1b-0d11f7cf92c6",
|
||||||
"A4": "3a14198e-6929-5e99-2b79-80720f7cfb54",
|
"E01": "3a19da56-1379-2f1c-a15b-e01db90eb39a",
|
||||||
"B1": "3a14198e-6929-f525-9a1b-1857552b28ee",
|
"F01": "3a19da56-1379-3fa1-846b-088158ac0b3d",
|
||||||
"B2": "3a14198e-6929-bf98-0fd5-26e1d68bf62d",
|
"G01": "3a19da56-1379-5aeb-d0cd-d3b4609d66e1",
|
||||||
"B3": "3a14198e-6929-2d86-a468-602175a2b5aa",
|
"H01": "3a19da56-1379-6077-8258-bdc036870b78",
|
||||||
"B4": "3a14198e-6929-1a98-ae57-e97660c489ad",
|
"I01": "3a19da56-1379-863b-a120-f606baf04617",
|
||||||
# 分装板
|
"J01": "3a19da56-1379-8a74-74e5-35a9b41d4fd5",
|
||||||
"C1": "3a14198e-6929-46fe-841e-03dd753f1e4a",
|
"K01": "3a19da56-1379-b270-b7af-f18773918abe",
|
||||||
"C2": "3a14198e-6929-1bc9-a9bd-3b7ca66e7f95",
|
"L01": "3a19da56-1379-ba54-6d78-fd770a671ffc",
|
||||||
"C3": "3a14198e-6929-72ac-32ce-9b50245682b8",
|
"M01": "3a19da56-1379-c22d-c96f-0ceb5eb54a04",
|
||||||
"C4": "3a14198e-6929-3bd8-e6c7-4a9fd93be118",
|
"N01": "3a19da56-1379-d64e-c6c5-c72ea4829888",
|
||||||
"D1": "3a14198e-6929-8a0b-b686-6f4a2955c4e2",
|
"O01": "3a19da56-1379-d887-1a3c-6f9cce90f90e",
|
||||||
"D2": "3a14198e-6929-dde1-fc78-34a84b71afdf",
|
"P01": "3a19da56-1379-e77d-0e65-7463b238a3b9",
|
||||||
"D3": "3a14198e-6929-a0ec-5f15-c0f9f339f963",
|
"Q01": "3a19da56-1379-edf6-1472-802ddb628774",
|
||||||
"D4": "3a14198e-6929-7ac8-915a-fea51cb2e884"
|
"R01": "3a19da56-1379-f281-0273-e0ef78f0fd97",
|
||||||
|
"S01": "3a19da56-1379-f924-7f68-df1fa51489f4",
|
||||||
|
"T01": "3a19da56-1379-ff7c-1745-07e200b44ce2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"溶液堆栈": {
|
"配液站内试剂仓库": {
|
||||||
"uuid": "",
|
"uuid": "",
|
||||||
"site_uuids": {
|
"site_uuids": {
|
||||||
"A1": "3a14198e-d724-e036-afdc-2ae39a7f3383",
|
"A01": "3a19da43-57b5-294f-d663-154a1cc32270",
|
||||||
"A2": "3a14198e-d724-afa4-fc82-0ac8a9016791",
|
"B01": "3a19da43-57b5-7394-5f49-54efe2c9bef2",
|
||||||
"A3": "3a14198e-d724-ca48-bb9e-7e85751e55b6",
|
"C01": "3a19da43-57b5-5e75-552f-8dbd0ad1075f",
|
||||||
"A4": "3a14198e-d724-df6d-5e32-5483b3cab583",
|
"A02": "3a19da43-57b5-8441-db94-b4d3875a4b6c",
|
||||||
"B1": "3a14198e-d724-d818-6d4f-5725191a24b5",
|
"B02": "3a19da43-57b5-3e41-c181-5119dddaf50c",
|
||||||
"B2": "3a14198e-d724-be8a-5e0b-012675e195c6",
|
"C02": "3a19da43-57b5-269b-282d-fba61fe8ce96",
|
||||||
"B3": "3a14198e-d724-cc1e-5c2c-228a130f40a8",
|
"A03": "3a19da43-57b5-7c1e-d02e-c40e8c33f8a1",
|
||||||
"B4": "3a14198e-d724-1e28-c885-574c3df468d0",
|
"B03": "3a19da43-57b5-659f-621f-1dcf3f640363",
|
||||||
"C1": "3a14198e-d724-b5bb-adf3-4c5a0da6fb31",
|
"C03": "3a19da43-57b5-855a-6e71-f398e376dee1",
|
||||||
"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": "",
|
"uuid": "",
|
||||||
"site_uuids": {
|
"site_uuids": {
|
||||||
"A1": "3a14198c-c2cf-8b40-af28-b467808f1c36",
|
"A01": "3a19da51-8f4e-30f3-ea08-4f8498e9b097",
|
||||||
"A2": "3a14198c-c2d0-f3e7-871a-e470d144296f",
|
"B01": "3a19da51-8f4e-1da7-beb0-80a4a01e67a8",
|
||||||
"A3": "3a14198c-c2d0-dc7d-b8d0-e1d88cee3094",
|
"C01": "3a19da51-8f4e-337d-2675-bfac46880b06",
|
||||||
"A4": "3a14198c-c2d0-2070-efc8-44e245f10c6f",
|
"D01": "3a19da51-8f4e-e514-b92c-9c44dc5e489d",
|
||||||
"B1": "3a14198c-c2d0-354f-39ad-642e1a72fcb8",
|
"E01": "3a19da51-8f4e-22d1-dd5b-9774ddc80402",
|
||||||
"B2": "3a14198c-c2d0-1559-105d-0ea30682cab4",
|
"F01": "3a19da51-8f4e-273a-4871-dff41c29bfd9",
|
||||||
"B3": "3a14198c-c2d0-725e-523d-34c037ac2440",
|
"G01": "3a19da51-8f4e-b32f-454f-74bc1a665653",
|
||||||
"B4": "3a14198c-c2d0-efce-0939-69ca5a7dfd39"
|
"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 = {
|
MATERIAL_TYPE_MAPPINGS = {
|
||||||
"烧杯": ("BIOYOND_PolymerStation_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
"烧杯": ("YB_1FlaskCarrier", "3a14196b-24f2-ca49-9081-0cab8021bf1a"),
|
||||||
"试剂瓶": ("BIOYOND_PolymerStation_1BottleCarrier", ""),
|
"试剂瓶": ("YB_1BottleCarrier", ""),
|
||||||
"样品板": ("BIOYOND_PolymerStation_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
"样品板": ("YB_6StockCarrier", "3a14196e-b7a0-a5da-1931-35f3000281e9"),
|
||||||
"分装板": ("BIOYOND_PolymerStation_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
"分装板": ("YB_6VialCarrier", "3a14196e-5dfe-6e21-0c79-fe2036d052c4"),
|
||||||
"样品瓶": ("BIOYOND_PolymerStation_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
"样品瓶": ("YB_Solid_Stock", "3a14196a-cf7d-8aea-48d8-b9662c7dba94"),
|
||||||
"90%分装小瓶": ("BIOYOND_PolymerStation_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
"90%分装小瓶": ("YB_Solid_Vial", "3a14196c-cdcf-088d-dc7d-5cf38f0ad9ea"),
|
||||||
"10%分装小瓶": ("BIOYOND_PolymerStation_Liquid_Vial", "3a14196c-76be-2279-4e22-7310d69aed68"),
|
"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)
|
SOLID_LIQUID_MAPPINGS = {
|
||||||
WORKFLOW_STEP_IDS = {
|
# 固体
|
||||||
"reactor_taken_in": {
|
"LiDFOB": {
|
||||||
"config": ""
|
"typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||||
|
"code": "",
|
||||||
|
"barCode": "",
|
||||||
|
"name": "LiDFOB",
|
||||||
|
"unit": "g",
|
||||||
|
"parameters": "",
|
||||||
|
"quantity": "2",
|
||||||
|
"warningQuantity": "1",
|
||||||
|
"details": []
|
||||||
},
|
},
|
||||||
"liquid_feeding_beaker": {
|
# "LiPF6": {
|
||||||
"liquid": "",
|
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||||
"observe": ""
|
# "code": "",
|
||||||
},
|
# "barCode": "",
|
||||||
"liquid_feeding_vials_non_titration": {
|
# "name": "LiPF6",
|
||||||
"liquid": "",
|
# "unit": "g",
|
||||||
"observe": ""
|
# "parameters": "",
|
||||||
},
|
# "quantity": 2,
|
||||||
"liquid_feeding_solvents": {
|
# "warningQuantity": 1,
|
||||||
"liquid": "",
|
# "details": []
|
||||||
"observe": ""
|
# },
|
||||||
},
|
# "LiFSI": {
|
||||||
"solid_feeding_vials": {
|
# "typeId": "3a190ca0-b2f6-9aeb-8067-547e72c11469",
|
||||||
"feeding": "",
|
# "code": "",
|
||||||
"observe": ""
|
# "barCode": "",
|
||||||
},
|
# "name": "LiFSI",
|
||||||
"liquid_feeding_titration": {
|
# "unit": "g",
|
||||||
"liquid": "",
|
# "parameters": "",
|
||||||
"observe": ""
|
# "quantity": 2,
|
||||||
},
|
# "warningQuantity": 1,
|
||||||
"drip_back": {
|
# "details": []
|
||||||
"liquid": "",
|
# },
|
||||||
"observe": ""
|
# "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 = {}
|
LOCATION_MAPPING = {}
|
||||||
@@ -20,6 +20,7 @@ from unilabos.ros.nodes.base_device_node import ROS2DeviceNode, BaseROS2DeviceNo
|
|||||||
from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
|
from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
|
||||||
from pylabrobot.resources.resource import Resource as ResourcePLR
|
from pylabrobot.resources.resource import Resource as ResourcePLR
|
||||||
|
|
||||||
|
from unilabos.resources.bioyond.decks import YB_Deck
|
||||||
from unilabos.devices.workstation.bioyond_studio.config import (
|
from unilabos.devices.workstation.bioyond_studio.config import (
|
||||||
API_CONFIG, WORKFLOW_MAPPINGS, MATERIAL_TYPE_MAPPINGS, WAREHOUSE_MAPPING
|
API_CONFIG, WORKFLOW_MAPPINGS, MATERIAL_TYPE_MAPPINGS, WAREHOUSE_MAPPING
|
||||||
)
|
)
|
||||||
@@ -135,7 +136,7 @@ class BioyondWorkstation(WorkstationBase):
|
|||||||
# 初始化父类
|
# 初始化父类
|
||||||
super().__init__(
|
super().__init__(
|
||||||
# 桌子
|
# 桌子
|
||||||
deck=deck,
|
deck=YB_Deck("YB_Deck14"),
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
@@ -164,8 +165,8 @@ class BioyondWorkstation(WorkstationBase):
|
|||||||
self.workflow_sequence = []
|
self.workflow_sequence = []
|
||||||
self.pending_task_params = []
|
self.pending_task_params = []
|
||||||
|
|
||||||
if "workflow_mappings" in bioyond_config:
|
if self.bioyond_config and "workflow_mappings" in self.bioyond_config:
|
||||||
self._set_workflow_mappings(bioyond_config["workflow_mappings"])
|
self._set_workflow_mappings(self.bioyond_config["workflow_mappings"])
|
||||||
logger.info(f"Bioyond工作站初始化完成")
|
logger.info(f"Bioyond工作站初始化完成")
|
||||||
|
|
||||||
def post_init(self, ros_node: ROS2WorkstationNode):
|
def post_init(self, ros_node: ROS2WorkstationNode):
|
||||||
@@ -467,7 +468,7 @@ def create_bioyond_workstation_example():
|
|||||||
"""创建Bioyond工作站示例"""
|
"""创建Bioyond工作站示例"""
|
||||||
|
|
||||||
# 配置参数
|
# 配置参数
|
||||||
device_id = "bioyond_workstation_001"
|
device_id = "bioyond_cell_workstation_001"
|
||||||
|
|
||||||
# 子资源配置
|
# 子资源配置
|
||||||
children = {
|
children = {
|
||||||
@@ -486,8 +487,8 @@ def create_bioyond_workstation_example():
|
|||||||
|
|
||||||
# Bioyond配置
|
# Bioyond配置
|
||||||
bioyond_config = {
|
bioyond_config = {
|
||||||
"base_url": "http://bioyond.example.com/api",
|
"base_url": "http://172.16.11.219:44388",
|
||||||
"api_key": "your_api_key_here",
|
"api_key": "8A819E5C",
|
||||||
"sync_interval": 60, # 60秒同步一次
|
"sync_interval": 60, # 60秒同步一次
|
||||||
"timeout": 30
|
"timeout": 30
|
||||||
}
|
}
|
||||||
@@ -511,4 +512,18 @@ def create_bioyond_workstation_example():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
by = create_bioyond_workstation_example()
|
||||||
|
by.get_workstation_status()
|
||||||
|
by.get_device_status()
|
||||||
|
by.get_bioyond_status()
|
||||||
|
by.get_station_info()
|
||||||
|
by.get_workstation_status()
|
||||||
|
by.get_bioyond_status()
|
||||||
|
by.get_station_info()
|
||||||
|
by.get_workstation_status()
|
||||||
|
by.get_bioyond_status()
|
||||||
|
by.get_station_info()
|
||||||
|
by.get_workstation_status()
|
||||||
|
by.get_bioyond_status()
|
||||||
|
by.get_station_info()
|
||||||
pass
|
pass
|
||||||
@@ -24,6 +24,13 @@ class ElectrodeSheetState(TypedDict):
|
|||||||
thickness: float # 厚度 (mm)
|
thickness: float # 厚度 (mm)
|
||||||
mass: float # 质量 (g)
|
mass: float # 质量 (g)
|
||||||
material_type: str # 材料类型(正极、负极、隔膜、弹片、垫片、铝箔等)
|
material_type: str # 材料类型(正极、负极、隔膜、弹片、垫片、铝箔等)
|
||||||
|
height: float
|
||||||
|
electrolyte_name: str
|
||||||
|
data_electrolyte_code: str
|
||||||
|
open_circuit_voltage: float
|
||||||
|
assembly_pressure: float
|
||||||
|
electrolyte_volume: float
|
||||||
|
|
||||||
info: Optional[str] # 附加信息
|
info: Optional[str] # 附加信息
|
||||||
|
|
||||||
class ElectrodeSheet(Resource):
|
class ElectrodeSheet(Resource):
|
||||||
@@ -61,6 +68,7 @@ class ElectrodeSheet(Resource):
|
|||||||
info=None
|
info=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: 这个还要不要?给self._unilabos_state赋值的?
|
||||||
def load_state(self, state: Dict[str, Any]) -> None:
|
def load_state(self, state: Dict[str, Any]) -> None:
|
||||||
"""格式不变"""
|
"""格式不变"""
|
||||||
super().load_state(state)
|
super().load_state(state)
|
||||||
@@ -146,10 +154,10 @@ class MaterialHole(Resource):
|
|||||||
):
|
):
|
||||||
"""放置极片"""
|
"""放置极片"""
|
||||||
# TODO: 这里要改,diameter找不到,加入._unilabos_state后应该没问题
|
# TODO: 这里要改,diameter找不到,加入._unilabos_state后应该没问题
|
||||||
if resource._unilabos_state["diameter"] > self._unilabos_state["diameter"]:
|
#if resource._unilabos_state["diameter"] > self._unilabos_state["diameter"]:
|
||||||
raise ValueError(f"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}")
|
# raise ValueError(f"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}")
|
||||||
if len(self.children) >= self._unilabos_state["max_sheets"]:
|
#if len(self.children) >= self._unilabos_state["max_sheets"]:
|
||||||
raise ValueError(f"洞位已满,无法放置更多极片")
|
# raise ValueError(f"洞位已满,无法放置更多极片")
|
||||||
super().assign_child_resource(resource, location, reassign)
|
super().assign_child_resource(resource, location, reassign)
|
||||||
|
|
||||||
# 根据children的编号取物料对象。
|
# 根据children的编号取物料对象。
|
||||||
@@ -164,8 +172,6 @@ class MaterialPlateState(TypedDict):
|
|||||||
hole_diameter: float
|
hole_diameter: float
|
||||||
info: Optional[str] # 附加信息
|
info: Optional[str] # 附加信息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MaterialPlate(ItemizedResource[MaterialHole]):
|
class MaterialPlate(ItemizedResource[MaterialHole]):
|
||||||
"""料板类 - 4x4个洞位,每个洞位放1个极片"""
|
"""料板类 - 4x4个洞位,每个洞位放1个极片"""
|
||||||
|
|
||||||
@@ -323,12 +329,13 @@ class PlateSlot(ResourceStack):
|
|||||||
|
|
||||||
class ClipMagazineHole(Container):
|
class ClipMagazineHole(Container):
|
||||||
"""子弹夹洞位类"""
|
"""子弹夹洞位类"""
|
||||||
children: List[ElectrodeSheet] = []
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
diameter: float,
|
diameter: float,
|
||||||
depth: float,
|
depth: float,
|
||||||
|
max_sheets: int = 100,
|
||||||
category: str = "clip_magazine_hole",
|
category: str = "clip_magazine_hole",
|
||||||
):
|
):
|
||||||
"""初始化子弹夹洞位
|
"""初始化子弹夹洞位
|
||||||
@@ -337,6 +344,7 @@ class ClipMagazineHole(Container):
|
|||||||
name: 洞位名称
|
name: 洞位名称
|
||||||
diameter: 洞直径 (mm)
|
diameter: 洞直径 (mm)
|
||||||
depth: 洞深度 (mm)
|
depth: 洞深度 (mm)
|
||||||
|
max_sheets: 最大极片数量
|
||||||
category: 类别
|
category: 类别
|
||||||
"""
|
"""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -348,143 +356,46 @@ class ClipMagazineHole(Container):
|
|||||||
)
|
)
|
||||||
self.diameter = diameter
|
self.diameter = diameter
|
||||||
self.depth = depth
|
self.depth = depth
|
||||||
|
self.max_sheets = max_sheets
|
||||||
|
self._sheets: List[ElectrodeSheet] = []
|
||||||
|
|
||||||
def can_add_sheet(self, sheet: ElectrodeSheet) -> bool:
|
def can_add_sheet(self, sheet: ElectrodeSheet) -> bool:
|
||||||
"""检查是否可以添加极片
|
"""检查是否可以添加极片"""
|
||||||
|
return (len(self._sheets) < self.max_sheets and
|
||||||
根据洞的深度和极片的厚度来判断是否可以添加极片
|
sheet.diameter <= self.diameter)
|
||||||
"""
|
|
||||||
# 检查极片直径是否适合洞的直径
|
|
||||||
if sheet._unilabos_state["diameter"] > self.diameter:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# 计算当前已添加极片的总厚度
|
|
||||||
current_thickness = sum(s._unilabos_state["thickness"] for s in self.children)
|
|
||||||
|
|
||||||
# 检查添加新极片后总厚度是否超过洞的深度
|
|
||||||
if current_thickness + sheet._unilabos_state["thickness"] > self.depth:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
def add_sheet(self, sheet: ElectrodeSheet) -> None:
|
||||||
|
"""添加极片"""
|
||||||
|
if not self.can_add_sheet(sheet):
|
||||||
|
raise ValueError(f"无法向洞位 {self.name} 添加极片")
|
||||||
|
self._sheets.append(sheet)
|
||||||
|
|
||||||
def assign_child_resource(
|
def take_sheet(self) -> ElectrodeSheet:
|
||||||
self,
|
"""取出极片"""
|
||||||
resource: ElectrodeSheet,
|
if len(self._sheets) == 0:
|
||||||
location: Optional[Coordinate] = None,
|
raise ValueError(f"洞位 {self.name} 没有极片")
|
||||||
reassign: bool = True,
|
return self._sheets.pop()
|
||||||
):
|
|
||||||
"""放置极片到洞位中
|
|
||||||
|
|
||||||
Args:
|
|
||||||
resource: 要放置的极片
|
|
||||||
location: 极片在洞位中的位置(对于洞位,通常为None)
|
|
||||||
reassign: 是否允许重新分配
|
|
||||||
"""
|
|
||||||
# 检查是否可以添加极片
|
|
||||||
if not self.can_add_sheet(resource):
|
|
||||||
raise ValueError(f"无法向洞位 {self.name} 添加极片:直径或厚度不匹配")
|
|
||||||
|
|
||||||
# 调用父类方法实际执行分配
|
|
||||||
super().assign_child_resource(resource, location, reassign)
|
|
||||||
|
|
||||||
def unassign_child_resource(self, resource: ElectrodeSheet):
|
|
||||||
"""从洞位中移除极片
|
|
||||||
|
|
||||||
Args:
|
|
||||||
resource: 要移除的极片
|
|
||||||
"""
|
|
||||||
if resource not in self.children:
|
|
||||||
raise ValueError(f"极片 {resource.name} 不在洞位 {self.name} 中")
|
|
||||||
|
|
||||||
# 调用父类方法实际执行移除
|
|
||||||
super().unassign_child_resource(resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_sheet_count(self) -> int:
|
||||||
|
"""获取极片数量"""
|
||||||
|
return len(self._sheets)
|
||||||
|
|
||||||
def serialize_state(self) -> Dict[str, Any]:
|
def serialize_state(self) -> Dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"sheet_count": len(self.children),
|
"sheet_count": len(self._sheets),
|
||||||
"sheets": [sheet.serialize() for sheet in self.children],
|
"sheets": [sheet.serialize() for sheet in self._sheets],
|
||||||
}
|
}
|
||||||
class ClipMagazine_four(ItemizedResource[ClipMagazineHole]):
|
|
||||||
"""子弹夹类 - 有4个洞位,每个洞位放多个极片"""
|
|
||||||
children: List[ClipMagazineHole]
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: str,
|
|
||||||
size_x: float,
|
|
||||||
size_y: float,
|
|
||||||
size_z: float,
|
|
||||||
hole_diameter: float = 14.0,
|
|
||||||
hole_depth: float = 10.0,
|
|
||||||
hole_spacing: float = 25.0,
|
|
||||||
max_sheets_per_hole: int = 100,
|
|
||||||
category: str = "clip_magazine_four",
|
|
||||||
model: Optional[str] = None,
|
|
||||||
):
|
|
||||||
"""初始化子弹夹
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name: 子弹夹名称
|
|
||||||
size_x: 长度 (mm)
|
|
||||||
size_y: 宽度 (mm)
|
|
||||||
size_z: 高度 (mm)
|
|
||||||
hole_diameter: 洞直径 (mm)
|
|
||||||
hole_depth: 洞深度 (mm)
|
|
||||||
hole_spacing: 洞位间距 (mm)
|
|
||||||
max_sheets_per_hole: 每个洞位最大极片数量
|
|
||||||
category: 类别
|
|
||||||
model: 型号
|
|
||||||
"""
|
|
||||||
# 创建4个洞位,排成2x2布局
|
|
||||||
holes = create_ordered_items_2d(
|
|
||||||
klass=ClipMagazineHole,
|
|
||||||
num_items_x=2,
|
|
||||||
num_items_y=2,
|
|
||||||
dx=(size_x - 2 * hole_spacing) / 2, # 居中
|
|
||||||
dy=(size_y - hole_spacing) / 2, # 居中
|
|
||||||
dz=size_z - 0,
|
|
||||||
item_dx=hole_spacing,
|
|
||||||
item_dy=hole_spacing,
|
|
||||||
diameter=hole_diameter,
|
|
||||||
depth=hole_depth,
|
|
||||||
)
|
|
||||||
|
|
||||||
super().__init__(
|
|
||||||
name=name,
|
|
||||||
size_x=size_x,
|
|
||||||
size_y=size_y,
|
|
||||||
size_z=size_z,
|
|
||||||
ordered_items=holes,
|
|
||||||
category=category,
|
|
||||||
model=model,
|
|
||||||
)
|
|
||||||
|
|
||||||
# 保存洞位的直径和深度
|
|
||||||
self.hole_diameter = hole_diameter
|
|
||||||
self.hole_depth = hole_depth
|
|
||||||
self.max_sheets_per_hole = max_sheets_per_hole
|
|
||||||
|
|
||||||
def serialize(self) -> dict:
|
|
||||||
return {
|
|
||||||
**super().serialize(),
|
|
||||||
"hole_diameter": self.hole_diameter,
|
|
||||||
"hole_depth": self.hole_depth,
|
|
||||||
"max_sheets_per_hole": self.max_sheets_per_hole,
|
|
||||||
}
|
|
||||||
# TODO: 这个要改
|
# TODO: 这个要改
|
||||||
class ClipMagazine(ItemizedResource[ClipMagazineHole]):
|
class ClipMagazine(Resource):
|
||||||
"""子弹夹类 - 有6个洞位,每个洞位放多个极片"""
|
"""子弹夹类 - 有6个洞位,每个洞位放多个极片"""
|
||||||
children: List[ClipMagazineHole]
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
size_x: float,
|
size_x: float,
|
||||||
size_y: float,
|
size_y: float,
|
||||||
size_z: float,
|
size_z: float,
|
||||||
hole_diameter: float = 14.0,
|
|
||||||
hole_depth: float = 10.0,
|
|
||||||
hole_spacing: float = 25.0,
|
hole_spacing: float = 25.0,
|
||||||
max_sheets_per_hole: int = 100,
|
max_sheets_per_hole: int = 100,
|
||||||
category: str = "clip_magazine",
|
category: str = "clip_magazine",
|
||||||
@@ -514,8 +425,8 @@ class ClipMagazine(ItemizedResource[ClipMagazineHole]):
|
|||||||
dz=size_z - 0,
|
dz=size_z - 0,
|
||||||
item_dx=hole_spacing,
|
item_dx=hole_spacing,
|
||||||
item_dy=hole_spacing,
|
item_dy=hole_spacing,
|
||||||
diameter=hole_diameter,
|
diameter=0,
|
||||||
depth=hole_depth,
|
depth=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -528,7 +439,6 @@ class ClipMagazine(ItemizedResource[ClipMagazineHole]):
|
|||||||
model=model,
|
model=model,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 保存洞位的直径和深度
|
|
||||||
self.hole_diameter = hole_diameter
|
self.hole_diameter = hole_diameter
|
||||||
self.hole_depth = hole_depth
|
self.hole_depth = hole_depth
|
||||||
self.max_sheets_per_hole = max_sheets_per_hole
|
self.max_sheets_per_hole = max_sheets_per_hole
|
||||||
@@ -545,9 +455,9 @@ class BatteryState(TypedDict):
|
|||||||
"""电池状态字典"""
|
"""电池状态字典"""
|
||||||
diameter: float
|
diameter: float
|
||||||
height: float
|
height: float
|
||||||
|
assembly_pressure: float
|
||||||
electrolyte_name: str
|
|
||||||
electrolyte_volume: float
|
electrolyte_volume: float
|
||||||
|
electrolyte_name: str
|
||||||
|
|
||||||
class Battery(Resource):
|
class Battery(Resource):
|
||||||
"""电池类 - 可容纳极片"""
|
"""电池类 - 可容纳极片"""
|
||||||
@@ -556,6 +466,9 @@ class Battery(Resource):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
|
size_x=1,
|
||||||
|
size_y=1,
|
||||||
|
size_z=1,
|
||||||
category: str = "battery",
|
category: str = "battery",
|
||||||
):
|
):
|
||||||
"""初始化电池
|
"""初始化电池
|
||||||
@@ -576,7 +489,13 @@ class Battery(Resource):
|
|||||||
size_z=1,
|
size_z=1,
|
||||||
category=category,
|
category=category,
|
||||||
)
|
)
|
||||||
self._unilabos_state: BatteryState = BatteryState()
|
self._unilabos_state: BatteryState = BatteryState(
|
||||||
|
diameter = 1.0,
|
||||||
|
height = 1.0,
|
||||||
|
assembly_pressure = 1.0,
|
||||||
|
electrolyte_volume = 1.0,
|
||||||
|
electrolyte_name = "DP001"
|
||||||
|
)
|
||||||
|
|
||||||
def add_electrolyte_with_bottle(self, bottle: Bottle) -> bool:
|
def add_electrolyte_with_bottle(self, bottle: Bottle) -> bool:
|
||||||
to_add_name = bottle._unilabos_state["electrolyte_name"]
|
to_add_name = bottle._unilabos_state["electrolyte_name"]
|
||||||
@@ -664,6 +583,7 @@ class BatteryPressSlot(Resource):
|
|||||||
reassign: bool = True,
|
reassign: bool = True,
|
||||||
):
|
):
|
||||||
"""放置极片"""
|
"""放置极片"""
|
||||||
|
# TODO: 让高京看下槽位只有一个电池时是否这么写。
|
||||||
if self.has_battery():
|
if self.has_battery():
|
||||||
raise ValueError(f"槽位已含有一个电池,无法再放置其他电池")
|
raise ValueError(f"槽位已含有一个电池,无法再放置其他电池")
|
||||||
super().assign_child_resource(resource, location, reassign)
|
super().assign_child_resource(resource, location, reassign)
|
||||||
@@ -672,6 +592,7 @@ class BatteryPressSlot(Resource):
|
|||||||
def get_battery_info(self, index: int) -> Battery:
|
def get_battery_info(self, index: int) -> Battery:
|
||||||
return self.children[0]
|
return self.children[0]
|
||||||
|
|
||||||
|
# TODO:这个移液枪架子看一下从哪继承
|
||||||
class TipBox64State(TypedDict):
|
class TipBox64State(TypedDict):
|
||||||
"""电池状态字典"""
|
"""电池状态字典"""
|
||||||
tip_diameter: float = 5.0
|
tip_diameter: float = 5.0
|
||||||
@@ -730,15 +651,6 @@ class TipBox64(TipRack):
|
|||||||
make_tip=make_tip,
|
make_tip=make_tip,
|
||||||
)
|
)
|
||||||
self._unilabos_state: WasteTipBoxstate = WasteTipBoxstate()
|
self._unilabos_state: WasteTipBoxstate = WasteTipBoxstate()
|
||||||
# 记录网格参数用于前端渲染
|
|
||||||
self._grid_params = {
|
|
||||||
"num_items_x": 8,
|
|
||||||
"num_items_y": 8,
|
|
||||||
"dx": 8.0,
|
|
||||||
"dy": 8.0,
|
|
||||||
"item_dx": 9.0,
|
|
||||||
"item_dy": 9.0,
|
|
||||||
}
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name=name,
|
name=name,
|
||||||
size_x=size_x,
|
size_x=size_x,
|
||||||
@@ -750,12 +662,6 @@ class TipBox64(TipRack):
|
|||||||
with_tips=True,
|
with_tips=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def serialize(self) -> dict:
|
|
||||||
return {
|
|
||||||
**super().serialize(),
|
|
||||||
**self._grid_params,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WasteTipBoxstate(TypedDict):
|
class WasteTipBoxstate(TypedDict):
|
||||||
@@ -833,34 +739,19 @@ class BottleRackState(TypedDict):
|
|||||||
name_to_index: dict
|
name_to_index: dict
|
||||||
|
|
||||||
|
|
||||||
class BottleRackState(TypedDict):
|
|
||||||
""" bottle_diameter: 瓶子直径 (mm)
|
|
||||||
bottle_height: 瓶子高度 (mm)
|
|
||||||
position_spacing: 位置间距 (mm)"""
|
|
||||||
bottle_diameter: float
|
|
||||||
bottle_height: float
|
|
||||||
position_spacing: float
|
|
||||||
name_to_index: dict
|
|
||||||
|
|
||||||
|
|
||||||
class BottleRack(Resource):
|
class BottleRack(Resource):
|
||||||
"""瓶架类 - 12个待配位置+12个已配位置"""
|
"""瓶架类 - 12个待配位置+12个已配位置"""
|
||||||
children: List[Resource] = []
|
children: List[Bottle] = []
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
size_x: float,
|
size_x: float,
|
||||||
size_y: float,
|
size_y: float,
|
||||||
size_z: float,
|
size_z: float,
|
||||||
category: str = "bottle_rack",
|
category: str = "bottle_rack",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
num_items_x: int = 3,
|
|
||||||
num_items_y: int = 4,
|
|
||||||
position_spacing: float = 35.0,
|
|
||||||
orientation: str = "horizontal",
|
|
||||||
padding_x: float = 20.0,
|
|
||||||
padding_y: float = 20.0,
|
|
||||||
):
|
):
|
||||||
"""初始化瓶架
|
"""初始化瓶架
|
||||||
|
|
||||||
@@ -880,42 +771,13 @@ class BottleRack(Resource):
|
|||||||
category=category,
|
category=category,
|
||||||
model=model,
|
model=model,
|
||||||
)
|
)
|
||||||
# 初始化状态
|
# TODO: 添加瓶位坐标映射
|
||||||
self._unilabos_state: BottleRackState = BottleRackState(
|
self.index_to_pos = {
|
||||||
bottle_diameter=30.0,
|
0: Coordinate.zero(),
|
||||||
bottle_height=100.0,
|
1: Coordinate(x=1, y=2, z=3) # 添加
|
||||||
position_spacing=position_spacing,
|
}
|
||||||
name_to_index={},
|
|
||||||
)
|
|
||||||
# 基于网格生成瓶位坐标映射(居中摆放)
|
|
||||||
# 使用内边距,避免点跑到容器外(前端渲染不按mm等比缩放时更稳妥)
|
|
||||||
origin_x = padding_x
|
|
||||||
origin_y = padding_y
|
|
||||||
self.index_to_pos = {}
|
|
||||||
for j in range(num_items_y):
|
|
||||||
for i in range(num_items_x):
|
|
||||||
idx = j * num_items_x + i
|
|
||||||
if orientation == "vertical":
|
|
||||||
# 纵向:沿 y 方向优先排列
|
|
||||||
self.index_to_pos[idx] = Coordinate(
|
|
||||||
x=origin_x + j * position_spacing,
|
|
||||||
y=origin_y + i * position_spacing,
|
|
||||||
z=0,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# 横向(默认):沿 x 方向优先排列
|
|
||||||
self.index_to_pos[idx] = Coordinate(
|
|
||||||
x=origin_x + i * position_spacing,
|
|
||||||
y=origin_y + j * position_spacing,
|
|
||||||
z=0,
|
|
||||||
)
|
|
||||||
self.name_to_index = {}
|
self.name_to_index = {}
|
||||||
self.name_to_pos = {}
|
self.name_to_pos = {}
|
||||||
self.num_items_x = num_items_x
|
|
||||||
self.num_items_y = num_items_y
|
|
||||||
self.orientation = orientation
|
|
||||||
self.padding_x = padding_x
|
|
||||||
self.padding_y = padding_y
|
|
||||||
|
|
||||||
def load_state(self, state: Dict[str, Any]) -> None:
|
def load_state(self, state: Dict[str, Any]) -> None:
|
||||||
"""格式不变"""
|
"""格式不变"""
|
||||||
@@ -925,23 +787,20 @@ class BottleRack(Resource):
|
|||||||
def serialize_state(self) -> Dict[str, Dict[str, Any]]:
|
def serialize_state(self) -> Dict[str, Dict[str, Any]]:
|
||||||
"""格式不变"""
|
"""格式不变"""
|
||||||
data = super().serialize_state()
|
data = super().serialize_state()
|
||||||
data.update(
|
data.update(self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)
|
||||||
self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# TODO: 这里有些问题要重新写一下
|
# TODO: 这里有些问题要重新写一下
|
||||||
def assign_child_resource_old(self, resource: Resource, location=Coordinate.zero(), reassign=True):
|
def assign_child_resource(self, resource: Bottle, location=Coordinate.zero(), reassign = True):
|
||||||
capacity = self.num_items_x * self.num_items_y
|
assert len(self.children) <= 12, "瓶架已满,无法添加更多瓶子"
|
||||||
assert len(self.children) < capacity, "瓶架已满,无法添加更多瓶子"
|
|
||||||
index = len(self.children)
|
index = len(self.children)
|
||||||
location = self.index_to_pos.get(index, Coordinate.zero())
|
location = Coordinate(x=20 + (index % 4) * 15, y=20 + (index // 4) * 15, z=0)
|
||||||
self.name_to_pos[resource.name] = location
|
self.name_to_pos[resource.name] = location
|
||||||
self.name_to_index[resource.name] = index
|
self.name_to_index[resource.name] = index
|
||||||
return super().assign_child_resource(resource, location, reassign)
|
return super().assign_child_resource(resource, location, reassign)
|
||||||
|
|
||||||
def assign_child_resource(self, resource: Resource, index: int):
|
def assign_child_resource_by_index(self, resource: Bottle, index: int):
|
||||||
capacity = self.num_items_x * self.num_items_y
|
assert 0 <= index < 12, "无效的瓶子索引"
|
||||||
assert 0 <= index < capacity, "无效的瓶子索引"
|
|
||||||
self.name_to_index[resource.name] = index
|
self.name_to_index[resource.name] = index
|
||||||
location = self.index_to_pos[index]
|
location = self.index_to_pos[index]
|
||||||
return super().assign_child_resource(resource, location)
|
return super().assign_child_resource(resource, location)
|
||||||
@@ -950,16 +809,9 @@ class BottleRack(Resource):
|
|||||||
super().unassign_child_resource(resource)
|
super().unassign_child_resource(resource)
|
||||||
self.index_to_pos.pop(self.name_to_index.pop(resource.name, None), None)
|
self.index_to_pos.pop(self.name_to_index.pop(resource.name, None), None)
|
||||||
|
|
||||||
def serialize(self) -> dict:
|
# def serialize(self):
|
||||||
return {
|
# self.children.sort(key=lambda x: self.name_to_index.get(x.name, 0))
|
||||||
**super().serialize(),
|
# return super().serialize()
|
||||||
"num_items_x": self.num_items_x,
|
|
||||||
"num_items_y": self.num_items_y,
|
|
||||||
"position_spacing": self._unilabos_state.get("position_spacing", 35.0),
|
|
||||||
"orientation": self.orientation,
|
|
||||||
"padding_x": self.padding_x,
|
|
||||||
"padding_y": self.padding_y,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class BottleState(TypedDict):
|
class BottleState(TypedDict):
|
||||||
@@ -1095,16 +947,20 @@ class CoincellDeck(Deck):
|
|||||||
# plate.assign_child_resource(hole)
|
# plate.assign_child_resource(hole)
|
||||||
# return plate
|
# return plate
|
||||||
|
|
||||||
def create_a_liaopan():
|
import json
|
||||||
liaopan = MaterialPlate(name="liaopan", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
|
|
||||||
for i in range(16):
|
|
||||||
jipian = ElectrodeSheet(name=f"jipian_{i}", size_x= 12, size_y=12, size_z=0.1)
|
|
||||||
liaopan1.children[i].assign_child_resource(jipian, location=None)
|
|
||||||
return liaopan
|
|
||||||
|
|
||||||
def create_a_coin_cell_deck():
|
if __name__ == "__main__":
|
||||||
deck = Deck(size_x=1200,
|
#electrode1 = BatteryPressSlot()
|
||||||
size_y=800,
|
#print(electrode1.get_size_x())
|
||||||
|
#print(electrode1.get_size_y())
|
||||||
|
#print(electrode1.get_size_z())
|
||||||
|
#jipian = ElectrodeSheet()
|
||||||
|
#jipian._unilabos_state["diameter"] = 18
|
||||||
|
#print(jipian.serialize())
|
||||||
|
#print(jipian.serialize_state())
|
||||||
|
|
||||||
|
deck = CoincellDeck(size_x=1000,
|
||||||
|
size_y=1000,
|
||||||
size_z=900)
|
size_z=900)
|
||||||
|
|
||||||
#liaopan = TipBox64(name="liaopan")
|
#liaopan = TipBox64(name="liaopan")
|
||||||
@@ -1115,172 +971,33 @@ def create_a_coin_cell_deck():
|
|||||||
deck.assign_child_resource(liaopan1, Coordinate(x=0, y=0, z=0))
|
deck.assign_child_resource(liaopan1, Coordinate(x=0, y=0, z=0))
|
||||||
#创建一个极片
|
#创建一个极片
|
||||||
for i in range(16):
|
for i in range(16):
|
||||||
jipian = ElectrodeSheet(name=f"jipian_{i}", size_x= 12, size_y=12, size_z=0.1)
|
jipian = ElectrodeSheet(name=f"jipian1_{i}", size_x= 12, size_y=12, size_z=0.1)
|
||||||
liaopan1.children[i].assign_child_resource(jipian, location=None)
|
liaopan1.children[i].assign_child_resource(jipian, location=None)
|
||||||
|
#
|
||||||
#创建一个4*4的物料板
|
#创建一个4*4的物料板
|
||||||
liaopan2 = MaterialPlate(name="liaopan2", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
|
liaopan2 = MaterialPlate(name="liaopan2", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
|
||||||
#把物料板放到桌子上
|
#把物料板放到桌子上
|
||||||
deck.assign_child_resource(liaopan2, Coordinate(x=500, y=0, z=0))
|
deck.assign_child_resource(liaopan2, Coordinate(x=500, y=0, z=0))
|
||||||
|
|
||||||
#创建一个4*4的物料板
|
#创建一个4*4的物料板
|
||||||
liaopan3 = MaterialPlate(name="liaopan3", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
|
liaopan3 = MaterialPlate(name="电池料盘", size_x=120.8, size_y=160.5, size_z=10.0, fill=True)
|
||||||
#把物料板放到桌子上
|
#把物料板放到桌子上
|
||||||
deck.assign_child_resource(liaopan3, Coordinate(x=1000, y=0, z=0))
|
deck.assign_child_resource(liaopan3, Coordinate(x=100, y=100, z=0))
|
||||||
|
|
||||||
print(deck)
|
|
||||||
|
|
||||||
return deck
|
|
||||||
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
electrode1 = BatteryPressSlot()
|
|
||||||
#print(electrode1.get_size_x())
|
|
||||||
#print(electrode1.get_size_y())
|
|
||||||
#print(electrode1.get_size_z())
|
|
||||||
#jipian = ElectrodeSheet()
|
|
||||||
#jipian._unilabos_state["diameter"] = 18
|
|
||||||
#print(jipian.serialize())
|
|
||||||
#print(jipian.serialize_state())
|
|
||||||
|
|
||||||
deck = CoincellDeck()
|
|
||||||
"""======================================子弹夹============================================"""
|
|
||||||
zip_dan_jia = ClipMagazine_four("zi_dan_jia", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia, Coordinate(x=1400, y=50, z=0))
|
|
||||||
zip_dan_jia2 = ClipMagazine_four("zi_dan_jia2", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia2, Coordinate(x=1600, y=200, z=0))
|
|
||||||
zip_dan_jia3 = ClipMagazine("zi_dan_jia3", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia3, Coordinate(x=1500, y=200, z=0))
|
|
||||||
zip_dan_jia4 = ClipMagazine("zi_dan_jia4", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia4, Coordinate(x=1500, y=300, z=0))
|
|
||||||
zip_dan_jia5 = ClipMagazine("zi_dan_jia5", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia5, Coordinate(x=1600, y=300, z=0))
|
|
||||||
zip_dan_jia6 = ClipMagazine("zi_dan_jia6", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia6, Coordinate(x=1530, y=500, z=0))
|
|
||||||
zip_dan_jia7 = ClipMagazine("zi_dan_jia7", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia7, Coordinate(x=1180, y=400, z=0))
|
|
||||||
zip_dan_jia8 = ClipMagazine("zi_dan_jia8", 80, 80, 10)
|
|
||||||
deck.assign_child_resource(zip_dan_jia8, Coordinate(x=1280, y=400, z=0))
|
|
||||||
for i in range(4):
|
|
||||||
jipian = ElectrodeSheet(name=f"zi_dan_jia_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia2.children[i].assign_child_resource(jipian, location=None)
|
|
||||||
for i in range(4):
|
|
||||||
jipian2 = ElectrodeSheet(name=f"zi_dan_jia2_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia.children[i].assign_child_resource(jipian2, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian3 = ElectrodeSheet(name=f"zi_dan_jia3_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia3.children[i].assign_child_resource(jipian3, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian4 = ElectrodeSheet(name=f"zi_dan_jia4_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia4.children[i].assign_child_resource(jipian4, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian5 = ElectrodeSheet(name=f"zi_dan_jia5_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia5.children[i].assign_child_resource(jipian5, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian6 = ElectrodeSheet(name=f"zi_dan_jia6_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia6.children[i].assign_child_resource(jipian6, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian7 = ElectrodeSheet(name=f"zi_dan_jia7_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia7.children[i].assign_child_resource(jipian7, location=None)
|
|
||||||
for i in range(6):
|
|
||||||
jipian8 = ElectrodeSheet(name=f"zi_dan_jia8_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
zip_dan_jia8.children[i].assign_child_resource(jipian8, location=None)
|
|
||||||
"""======================================子弹夹============================================"""
|
|
||||||
#liaopan = TipBox64(name="liaopan")
|
|
||||||
"""======================================物料板============================================"""
|
|
||||||
#创建一个4*4的物料板
|
|
||||||
liaopan1 = MaterialPlate(name="liaopan1", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan1, Coordinate(x=1010, y=50, z=0))
|
|
||||||
for i in range(16):
|
|
||||||
jipian_1 = ElectrodeSheet(name=f"{liaopan1.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
liaopan1.children[i].assign_child_resource(jipian_1, location=None)
|
|
||||||
|
|
||||||
liaopan2 = MaterialPlate(name="liaopan2", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan2, Coordinate(x=1130, y=50, z=0))
|
|
||||||
|
|
||||||
liaopan3 = MaterialPlate(name="liaopan3", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan3, Coordinate(x=1250, y=50, z=0))
|
|
||||||
|
|
||||||
liaopan4 = MaterialPlate(name="liaopan4", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan4, Coordinate(x=1010, y=150, z=0))
|
|
||||||
for i in range(16):
|
|
||||||
jipian_4 = ElectrodeSheet(name=f"{liaopan4.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
liaopan4.children[i].assign_child_resource(jipian_4, location=None)
|
|
||||||
liaopan5 = MaterialPlate(name="liaopan5", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan5, Coordinate(x=1130, y=150, z=0))
|
|
||||||
liaopan6 = MaterialPlate(name="liaopan6", size_x=120, size_y=100, size_z=10.0, fill=True)
|
|
||||||
deck.assign_child_resource(liaopan6, Coordinate(x=1250, y=150, z=0))
|
|
||||||
#liaopan.children[3].assign_child_resource(jipian, location=None)
|
#liaopan.children[3].assign_child_resource(jipian, location=None)
|
||||||
"""======================================物料板============================================"""
|
|
||||||
"""======================================瓶架,移液枪============================================"""
|
|
||||||
# 在台面上放置 3x4 瓶架、6x2 瓶架 与 64孔移液枪头盒
|
|
||||||
bottle_rack_3x4 = BottleRack(
|
|
||||||
name="bottle_rack_3x4",
|
|
||||||
size_x=210.0,
|
|
||||||
size_y=140.0,
|
|
||||||
size_z=100.0,
|
|
||||||
num_items_x=3,
|
|
||||||
num_items_y=4,
|
|
||||||
position_spacing=35.0,
|
|
||||||
orientation="vertical",
|
|
||||||
)
|
|
||||||
deck.assign_child_resource(bottle_rack_3x4, Coordinate(x=100, y=200, z=0))
|
|
||||||
|
|
||||||
bottle_rack_6x2 = BottleRack(
|
|
||||||
name="bottle_rack_6x2",
|
|
||||||
size_x=120.0,
|
|
||||||
size_y=250.0,
|
|
||||||
size_z=100.0,
|
|
||||||
num_items_x=6,
|
|
||||||
num_items_y=2,
|
|
||||||
position_spacing=35.0,
|
|
||||||
orientation="vertical",
|
|
||||||
)
|
|
||||||
deck.assign_child_resource(bottle_rack_6x2, Coordinate(x=300, y=300, z=0))
|
|
||||||
|
|
||||||
bottle_rack_6x2_2 = BottleRack(
|
|
||||||
name="bottle_rack_6x2_2",
|
|
||||||
size_x=120.0,
|
|
||||||
size_y=250.0,
|
|
||||||
size_z=100.0,
|
|
||||||
num_items_x=6,
|
|
||||||
num_items_y=2,
|
|
||||||
position_spacing=35.0,
|
|
||||||
orientation="vertical",
|
|
||||||
)
|
|
||||||
deck.assign_child_resource(bottle_rack_6x2_2, Coordinate(x=430, y=300, z=0))
|
|
||||||
|
|
||||||
|
|
||||||
# 将 ElectrodeSheet 放满 3x4 与 6x2 的所有孔位
|
|
||||||
for idx in range(bottle_rack_3x4.num_items_x * bottle_rack_3x4.num_items_y):
|
|
||||||
sheet = ElectrodeSheet(name=f"sheet_3x4_{idx}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
bottle_rack_3x4.assign_child_resource(sheet, index=idx)
|
|
||||||
|
|
||||||
for idx in range(bottle_rack_6x2.num_items_x * bottle_rack_6x2.num_items_y):
|
|
||||||
sheet = ElectrodeSheet(name=f"sheet_6x2_{idx}", size_x=12, size_y=12, size_z=0.1)
|
|
||||||
bottle_rack_6x2.assign_child_resource(sheet, index=idx)
|
|
||||||
|
|
||||||
tip_box = TipBox64(name="tip_box_64")
|
|
||||||
deck.assign_child_resource(tip_box, Coordinate(x=300, y=100, z=0))
|
|
||||||
|
|
||||||
waste_tip_box = WasteTipBox(name="waste_tip_box")
|
|
||||||
deck.assign_child_resource(waste_tip_box, Coordinate(x=300, y=200, z=0))
|
|
||||||
"""======================================瓶架,移液枪============================================"""
|
|
||||||
print(deck)
|
print(deck)
|
||||||
|
|
||||||
|
|
||||||
from unilabos.resources.graphio import convert_resources_from_type
|
from unilabos.resources.graphio import convert_resources_from_type
|
||||||
from unilabos.config.config import BasicConfig
|
from unilabos.config.config import BasicConfig
|
||||||
BasicConfig.ak = "56bbed5b-6e30-438c-b06d-f69eaa63bb45"
|
BasicConfig.ak = "4d5ce6ae-7234-4639-834e-93899b9caf94"
|
||||||
BasicConfig.sk = "238222fe-0bf7-4350-a426-e5ced8011dcf"
|
BasicConfig.sk = "505d3b0a-620e-459a-9905-1efcffce382a"
|
||||||
from unilabos.app.web.client import http_client
|
from unilabos.app.web.client import http_client
|
||||||
|
|
||||||
resources = convert_resources_from_type([deck], [Resource])
|
resources = convert_resources_from_type([deck], [Resource])
|
||||||
|
json.dump({"nodes": resources, "links": []}, open("button_battery_station_resources_unilab.json", "w"), indent=2)
|
||||||
# 检查序列化后的资源
|
|
||||||
|
|
||||||
json.dump({"nodes": resources, "links": []}, open("button_battery_decks_unilab.json", "w"), indent=2)
|
|
||||||
|
|
||||||
|
|
||||||
#print(resources)
|
#print(resources)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
114
unilabos/devices/workstation/coin_cell_assembly/cellconfig.py
Normal file
114
unilabos/devices/workstation/coin_cell_assembly/cellconfig.py
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#coding=utf-8
|
||||||
|
|
||||||
|
ENV = 'pro'#'test'
|
||||||
|
class MQConfig:
|
||||||
|
"""MQTT 配置类"""
|
||||||
|
lab_id: str = '9F05593C'
|
||||||
|
instance_id: str = 'mqtt-cn-dsr48m6jy02'
|
||||||
|
|
||||||
|
group_id: str = 'GID_prod'
|
||||||
|
broker_url: str = 'mqtt-cn-dsr48m6jy02.mqtt.aliyuncs.com'
|
||||||
|
port: int = 8883
|
||||||
|
ca_content: str = '''-----BEGIN CERTIFICATE-----
|
||||||
|
MIID3jCCAsagAwIBAgIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||||
|
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA1MDYxNTE0Mjda
|
||||||
|
Fw0zNTA1MDQxNTE0MjdaMEsxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||||
|
A1UEBwwCQkoxEDAOBgNVBAoMB2RwLnRlY2gxEDAOBgNVBAsMB3VuaS1sYWIwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnTBywX+6DJ2n+prNKvylBBJF6
|
||||||
|
NHQrCt2cztZfswHsW4QhAbDddp4PRzNVzKtIfHX5ZrXGbxNT1/TqQYXKiFjKbfPC
|
||||||
|
VHTrS6+95LP3MxNTlBWHP6d2uI45KwrGgQ7D1uPDG1wZsfuJxvOkfAIxZRCDUMJr
|
||||||
|
erYYK/p2/GVMAO5YKE7wENUMN+iLfVQRqQJRgte9z0B35DxUeOUblJDun0Dpl/6L
|
||||||
|
0km/YRrjUKA/5+u/h+Ko9+36L1DAi+9rm3eyp+BQHBy5aiVhAG6uAJeMjbZMxwxz
|
||||||
|
ixg9cWNxP1BW+aQQzixbEQ+YlO9+w/soJkLstiK7jF8uIg2QvmNUKNlqab0pAgMB
|
||||||
|
AAGjgbkwgbYwHQYDVR0OBBYEFAqg0r7f6ngWODyVxVWHWM06b8wDMIGGBgNVHSME
|
||||||
|
fzB9gBQKoNK+3+p4Fjg8lcVVh1jNOm/MA6FPpE0wSzELMAkGA1UEBhMCQ04xCzAJ
|
||||||
|
BgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4GA1UECgwHZHAudGVjaDEQMA4GA1UE
|
||||||
|
CwwHdW5pLWxhYoIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDAYDVR0TBAUwAwEB/zAN
|
||||||
|
BgkqhkiG9w0BAQsFAAOCAQEAMylGHHhRCI8JLTizxqk2HaOFkF/WfnYC3XyNx3bK
|
||||||
|
9KqwVcvaqES+C058lits5nCV1qjjSnKt6xU11S8C6E28Kazh+wMqnSw63fz4UOY5
|
||||||
|
4cekPCPy8XcWlOY6UW2N27GR0c9JDo9ovruOn1Y4KjATpAQI4W2tPAQ2gCVSNpu1
|
||||||
|
bw5uw35yJSRzdQIHlsVbslvj2wcugK3GZHmmxJK+q9ww7G6xXtE2Y0+vl6AZRj+I
|
||||||
|
lcTy5TNNDZiiboIlAt+K3m4hxzSgGPbmFPJX3Lw3i+YMR/0PrWfXqxZgicO/V6/d
|
||||||
|
SgGBqq/tH1caiaEjCFudSZcOiZvHIlb09O4qL7mCtWEiEQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
'''
|
||||||
|
cert_content: str = '''-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDlTCCAn2gAwIBAgIUa/ce6dpJ8K7XNvT0LknVmLgfJMIwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||||
|
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA4MTMwNDQ0MDVa
|
||||||
|
Fw0yNjEyMjYwNDQ0MDVaMHoxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||||
|
A1UEBwwCQkoxDDAKBgNVBAoMA0RQVDENMAsGA1UECwwETVFUVDEhMB8GCSqGSIb3
|
||||||
|
DQEJARYSaHVhaGFpbWluZ0BkcC50ZWNoMREwDwYDVQQDDAg0NzJBMjZBQzCCASIw
|
||||||
|
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPc4NHXcwaFX3jSN6DnDYoY7ON6c
|
||||||
|
AeVIlcQp3CMHnulh4t3I3Fnsyelpc809s7l5vEpAjMIuZ40DJKZQmV9ckmeylMiY
|
||||||
|
bAk851+i8YcRQPeYYY7Ggt0sfkY3TWIIqptZtlIhXtkTCWw6xpHAPkYxqNTiUN/0
|
||||||
|
vwQWwiBS7WqD8NVjNhhHootYLsMjnQYc162L8nUwzG2pjB3UYqOldC3FkHXvBkG2
|
||||||
|
Oeex8VM8Urblv0huCmoFRyuMmNol0QWqp+6nwAgdvf89Z38NJByPI9VHaBB/VV1F
|
||||||
|
HiAZe3H8Ph7wzgUSXBuVHJ4BaeJbg4+ax6BccpaQn26jgpJGUEj+YR+NwdMCAwEA
|
||||||
|
AaNCMEAwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCAvQwIAYDVR0lAQH/BBYw
|
||||||
|
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQAZaF8puP0/
|
||||||
|
OcRM7Gcd4LrF8H/WG0Q7WM0T9BWGvee6A+Fcd4ajBC0S0tIfdsfYat0+g4U57jrr
|
||||||
|
vaQeZGFKc4YKVui8vSuth82fcsFk5fpyhz4JJRggzeoby+0gNx9eYDJwLIvbVy4Y
|
||||||
|
2LKGq+rsO07QF54jtwB4WpDNFnEIadXyjPBsMy/0Ssbetp827WYZygXYyAcUlCfN
|
||||||
|
Wns7K0phfZJwIMQgPs3d4mGwCC+xaRIB3GGjUGFXV1sFItjkTUHCvm+phw/MTpRp
|
||||||
|
pauplyDcWYux7z1dKhbuHElzCEqxZNwyI0nGJlRFP13Oo+jnuDO7gQh2lyz/AFyX
|
||||||
|
KyTA3xFZduHO
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID3jCCAsagAwIBAgIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||||
|
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA1MDYxNTE0Mjda
|
||||||
|
Fw0zNTA1MDQxNTE0MjdaMEsxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||||
|
A1UEBwwCQkoxEDAOBgNVBAoMB2RwLnRlY2gxEDAOBgNVBAsMB3VuaS1sYWIwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnTBywX+6DJ2n+prNKvylBBJF6
|
||||||
|
NHQrCt2cztZfswHsW4QhAbDddp4PRzNVzKtIfHX5ZrXGbxNT1/TqQYXKiFjKbfPC
|
||||||
|
VHTrS6+95LP3MxNTlBWHP6d2uI45KwrGgQ7D1uPDG1wZsfuJxvOkfAIxZRCDUMJr
|
||||||
|
erYYK/p2/GVMAO5YKE7wENUMN+iLfVQRqQJRgte9z0B35DxUeOUblJDun0Dpl/6L
|
||||||
|
0km/YRrjUKA/5+u/h+Ko9+36L1DAi+9rm3eyp+BQHBy5aiVhAG6uAJeMjbZMxwxz
|
||||||
|
ixg9cWNxP1BW+aQQzixbEQ+YlO9+w/soJkLstiK7jF8uIg2QvmNUKNlqab0pAgMB
|
||||||
|
AAGjgbkwgbYwHQYDVR0OBBYEFAqg0r7f6ngWODyVxVWHWM06b8wDMIGGBgNVHSME
|
||||||
|
fzB9gBQKoNK+3+p4Fjg8lcVVh1jNOm/MA6FPpE0wSzELMAkGA1UEBhMCQ04xCzAJ
|
||||||
|
BgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4GA1UECgwHZHAudGVjaDEQMA4GA1UE
|
||||||
|
CwwHdW5pLWxhYoIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDAYDVR0TBAUwAwEB/zAN
|
||||||
|
BgkqhkiG9w0BAQsFAAOCAQEAMylGHHhRCI8JLTizxqk2HaOFkF/WfnYC3XyNx3bK
|
||||||
|
9KqwVcvaqES+C058lits5nCV1qjjSnKt6xU11S8C6E28Kazh+wMqnSw63fz4UOY5
|
||||||
|
4cekPCPy8XcWlOY6UW2N27GR0c9JDo9ovruOn1Y4KjATpAQI4W2tPAQ2gCVSNpu1
|
||||||
|
bw5uw35yJSRzdQIHlsVbslvj2wcugK3GZHmmxJK+q9ww7G6xXtE2Y0+vl6AZRj+I
|
||||||
|
lcTy5TNNDZiiboIlAt+K3m4hxzSgGPbmFPJX3Lw3i+YMR/0PrWfXqxZgicO/V6/d
|
||||||
|
SgGBqq/tH1caiaEjCFudSZcOiZvHIlb09O4qL7mCtWEiEQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
'''
|
||||||
|
key_content: str = '''-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA9zg0ddzBoVfeNI3oOcNihjs43pwB5UiVxCncIwee6WHi3cjc
|
||||||
|
WezJ6WlzzT2zuXm8SkCMwi5njQMkplCZX1ySZ7KUyJhsCTznX6LxhxFA95hhjsaC
|
||||||
|
3Sx+RjdNYgiqm1m2UiFe2RMJbDrGkcA+RjGo1OJQ3/S/BBbCIFLtaoPw1WM2GEei
|
||||||
|
i1guwyOdBhzXrYvydTDMbamMHdRio6V0LcWQde8GQbY557HxUzxStuW/SG4KagVH
|
||||||
|
K4yY2iXRBaqn7qfACB29/z1nfw0kHI8j1UdoEH9VXUUeIBl7cfw+HvDOBRJcG5Uc
|
||||||
|
ngFp4luDj5rHoFxylpCfbqOCkkZQSP5hH43B0wIDAQABAoIBAAPzz0ZUcqmR1Eva
|
||||||
|
5PH98gQzp2wB9snLY86HY3Z/JVAPf5Ht9sbAUWHhT8PVoWpIasSmFbuJxz6DRk3S
|
||||||
|
M8VVVipxxgcTWqo/JOD4HZiCNfcRru6+5dHxZ4p2B/n4EWfoy+KyEZkgd5jQFONj
|
||||||
|
jIX+rDR3qZzFqoBRhQSHLuD+i66eZ7l1LOqsnk51r3nTCnGmdyV8fll56MMB5D6+
|
||||||
|
8LN2rwbmSYX/UIBBqHUthgEt2onFNaetTLgSa3RSNGZ3xEZt4N32vw1SARxItuso
|
||||||
|
npAAY77POMUwWe3666fETI+yr/gJuppvTF4sQUXy7I4iz7I18n2SYivHabdgnk6H
|
||||||
|
7y1TcGECgYEA/NbBLFz1YPOQiT6TsuitIlfWcFWXYI4yHh/Mwwm/heHV683HrUti
|
||||||
|
RSHWbFxggW70BYJbGAQprEe9UIRVdP9YNi3aPeN5WNfnTFHlN2HRiKenlETM1tw9
|
||||||
|
yaSWjNbAyc2ka+l1EblMJy92xoCkErS8riEPW83o+3+LqJwnjsJ8tVECgYEA+k93
|
||||||
|
AyNpXuOZldAoqSHF3wHgzgd2jhfVdQcNlz9sLfT8TAdoR01mdBtdytcYAH+FHplW
|
||||||
|
wlkCfpT1RPf3fEd0Asy727pJnL9v/QfY/BB+vfgWKUQg9CWNIevwItCaTNOSekis
|
||||||
|
lKl5dxNGOyouU7rPbTj9BC26OHA50Z3vLMKmi+MCgYEAy0Sb6N6TJ26pNK1qcNs+
|
||||||
|
1e1oKMem+6lWAYHvTJ35q9jz8q9taJTCXHHnwRZDP8vDwuoZ8iTmm+rQ+HprebQP
|
||||||
|
Zv9WBYtrc1GgUmtErFGn8wVWZI0rYVGPGx2HK5M7SwJYvajixW0DHD28b7ncLm2/
|
||||||
|
gv5xKo1QUWEpFlT0OIGDYQECgYEA8WRlH6+s1Iel++ZM8B7T1ibXh5mG6a1ue3eb
|
||||||
|
0bqmNwPFtASIugqYvWwO3ajlSsWvuTyjgLWaRDye9C42i7HU3UZX/KUAjJvKAjjp
|
||||||
|
Nt0pfUadCJrdNNZp7sa8RLbrtx9qaWdgl9WAgCckWbZqCvFjTK/iwX7f0cHY4J/w
|
||||||
|
ojftqYUCgYARM6YaEJuBJEBmZV1I0rweiguqWssZz2j1awSlsfYxckwnci4VtSMI
|
||||||
|
D/sp0Wp0yn2N4cgqp49BFD0rCQCTsASVICEf9HWdMQXsUhzWsz4SjVEhjWWC1VAk
|
||||||
|
sEL+BOcbsHy3qMbV2uKBHrhuZShDdy5KtCm9TB+7zTWyDVHwE24nig==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
'''
|
||||||
|
|
||||||
|
# HTTP配置
|
||||||
|
class HTTPConfig:
|
||||||
|
remote_addr = "https://uni-lab.test.bohrium.com/api/v1"
|
||||||
1332
unilabos/devices/workstation/coin_cell_assembly/celljson.json
Normal file
1332
unilabos/devices/workstation/coin_cell_assembly/celljson.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@ from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
|
|||||||
class CoinCellAssemblyWorkstation(WorkstationBase):
|
class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
deck: CoincellDeck,
|
station_resource: CoincellDeck,
|
||||||
address: str = "192.168.1.20",
|
address: str = "192.168.1.20",
|
||||||
port: str = "502",
|
port: str = "502",
|
||||||
debug_mode: bool = True,
|
debug_mode: bool = True,
|
||||||
@@ -30,12 +30,12 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
#桌子
|
#桌子
|
||||||
deck=deck,
|
station_resource=station_resource,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
self.debug_mode = debug_mode
|
self.debug_mode = debug_mode
|
||||||
self.deck = deck
|
self.station_resource = station_resource
|
||||||
""" 连接初始化 """
|
""" 连接初始化 """
|
||||||
modbus_client = TCPClient(addr=address, port=port)
|
modbus_client = TCPClient(addr=address, port=port)
|
||||||
print("modbus_client", modbus_client)
|
print("modbus_client", modbus_client)
|
||||||
@@ -60,6 +60,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
self.csv_export_thread = None
|
self.csv_export_thread = None
|
||||||
self.csv_export_running = False
|
self.csv_export_running = False
|
||||||
self.csv_export_file = None
|
self.csv_export_file = None
|
||||||
|
self.coin_num_N = 0 #已组装电池数量
|
||||||
#创建一个物料台面,包含两个极片板
|
#创建一个物料台面,包含两个极片板
|
||||||
#self.deck = create_a_coin_cell_deck()
|
#self.deck = create_a_coin_cell_deck()
|
||||||
|
|
||||||
@@ -74,7 +75,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
self._ros_node = ros_node
|
self._ros_node = ros_node
|
||||||
#self.deck = create_a_coin_cell_deck()
|
#self.deck = create_a_coin_cell_deck()
|
||||||
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
||||||
"resources": [self.deck]
|
"resources": [self.station_resource]
|
||||||
})
|
})
|
||||||
|
|
||||||
# 批量操作在这里写
|
# 批量操作在这里写
|
||||||
@@ -84,7 +85,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
|
|
||||||
|
|
||||||
async def fill_plate(self):
|
async def fill_plate(self):
|
||||||
plate_1: MaterialPlate = self.deck.children[0].children[0]
|
plate_1: MaterialPlate = self.station_resource.children[0].children[0]
|
||||||
#plate_1
|
#plate_1
|
||||||
return await self._ros_node.update_resource(plate_1)
|
return await self._ros_node.update_resource(plate_1)
|
||||||
|
|
||||||
@@ -341,7 +342,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
def modify_deck_name(self, resource_name: str):
|
def modify_deck_name(self, resource_name: str):
|
||||||
# figure_res = self._ros_node.resource_tracker.figure_resource({"name": resource_name})
|
# figure_res = self._ros_node.resource_tracker.figure_resource({"name": resource_name})
|
||||||
# print(f"!!! figure_res: {type(figure_res)}")
|
# print(f"!!! figure_res: {type(figure_res)}")
|
||||||
self.deck.children[1]
|
self.station_resource.children[1]
|
||||||
return
|
return
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -606,7 +607,8 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
print("waiting for start_cmd")
|
print("waiting for start_cmd")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def func_pack_send_bottle_num(self, bottle_num: int):
|
def func_pack_send_bottle_num(self, bottle_num):
|
||||||
|
bottle_num = int(bottle_num)
|
||||||
#发送电解液平台数
|
#发送电解液平台数
|
||||||
print("启动")
|
print("启动")
|
||||||
while (self._unilab_rece_electrolyte_bottle_num()) == False:
|
while (self._unilab_rece_electrolyte_bottle_num()) == False:
|
||||||
@@ -697,6 +699,23 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
print("data_electrolyte_code", data_electrolyte_code)
|
print("data_electrolyte_code", data_electrolyte_code)
|
||||||
print("data_coin_cell_code", data_coin_cell_code)
|
print("data_coin_cell_code", data_coin_cell_code)
|
||||||
#接收完信息后,读取完毕标志位置True
|
#接收完信息后,读取完毕标志位置True
|
||||||
|
liaopan3 = self.station_resource.get_resource("\u7535\u6c60\u6599\u76d8")
|
||||||
|
#把物料解绑后放到另一盘上
|
||||||
|
battery = ElectrodeSheet(name=f"battery_{self.coin_num_N}", size_x=14, size_y=14, size_z=2)
|
||||||
|
battery._unilabos_state = {
|
||||||
|
"electrolyte_name": data_coin_cell_code,
|
||||||
|
"data_electrolyte_code": data_electrolyte_code,
|
||||||
|
"open_circuit_voltage": data_open_circuit_voltage,
|
||||||
|
"assembly_pressure": data_assembly_pressure,
|
||||||
|
"electrolyte_volume": data_electrolyte_volume
|
||||||
|
}
|
||||||
|
liaopan3.children[self.coin_num_N].assign_child_resource(battery, location=None)
|
||||||
|
#print(jipian2.parent)
|
||||||
|
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
||||||
|
"resources": [self.station_resource]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
self._unilab_rec_msg_succ_cmd(True)
|
self._unilab_rec_msg_succ_cmd(True)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
#等待允许读取标志位置False
|
#等待允许读取标志位置False
|
||||||
@@ -757,6 +776,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
|
|
||||||
|
|
||||||
def func_allpack_cmd(self, elec_num, elec_use_num, file_path: str="D:\\coin_cell_data") -> bool:
|
def func_allpack_cmd(self, elec_num, elec_use_num, file_path: str="D:\\coin_cell_data") -> bool:
|
||||||
|
elec_num, elec_use_num = int(elec_num), int(elec_use_num)
|
||||||
summary_csv_file = os.path.join(file_path, "duandian.csv")
|
summary_csv_file = os.path.join(file_path, "duandian.csv")
|
||||||
# 如果断点文件存在,先读取之前的进度
|
# 如果断点文件存在,先读取之前的进度
|
||||||
if os.path.exists(summary_csv_file):
|
if os.path.exists(summary_csv_file):
|
||||||
@@ -784,20 +804,22 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
elec_num_N = 0
|
elec_num_N = 0
|
||||||
elec_use_num_N = 0
|
elec_use_num_N = 0
|
||||||
coin_num_N = 0
|
coin_num_N = 0
|
||||||
|
for i in range(20):
|
||||||
print(f"剩余电解液瓶数: {elec_num}, 已组装电池数: {elec_use_num}")
|
print(f"剩余电解液瓶数: {elec_num}, 已组装电池数: {elec_use_num}")
|
||||||
|
print(f"剩余电解液瓶数: {type(elec_num)}, 已组装电池数: {type(elec_use_num)}")
|
||||||
|
print(f"剩余电解液瓶数: {type(int(elec_num))}, 已组装电池数: {type(int(elec_use_num))}")
|
||||||
|
|
||||||
#如果是第一次运行,则进行初始化、切换自动、启动, 如果是断点重启则跳过。
|
#如果是第一次运行,则进行初始化、切换自动、启动, 如果是断点重启则跳过。
|
||||||
if read_status_flag == False:
|
if read_status_flag == False:
|
||||||
|
pass
|
||||||
#初始化
|
#初始化
|
||||||
self.func_pack_device_init()
|
#self.func_pack_device_init()
|
||||||
#切换自动
|
#切换自动
|
||||||
self.func_pack_device_auto()
|
#self.func_pack_device_auto()
|
||||||
#启动,小车收回
|
#启动,小车收回
|
||||||
self.func_pack_device_start()
|
#self.func_pack_device_start()
|
||||||
#发送电解液瓶数量,启动搬运,多搬运没事
|
#发送电解液瓶数量,启动搬运,多搬运没事
|
||||||
self.func_pack_send_bottle_num(elec_num)
|
#self.func_pack_send_bottle_num(elec_num)
|
||||||
last_i = elec_num_N
|
last_i = elec_num_N
|
||||||
last_j = elec_use_num_N
|
last_j = elec_use_num_N
|
||||||
for i in range(last_i, elec_num):
|
for i in range(last_i, elec_num):
|
||||||
@@ -811,27 +833,9 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
#读取电池组装数据并存入csv
|
#读取电池组装数据并存入csv
|
||||||
self.func_pack_get_msg_cmd(file_path)
|
self.func_pack_get_msg_cmd(file_path)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
#这里定义物料系统
|
|
||||||
# TODO:读完再将电池数加一还是进入循环就将电池数加一需要考虑
|
# TODO:读完再将电池数加一还是进入循环就将电池数加一需要考虑
|
||||||
liaopan1 = self.deck.get_resource("liaopan1")
|
|
||||||
liaopan4 = self.deck.get_resource("liaopan4")
|
|
||||||
jipian1 = liaopan1.children[coin_num_N].children[0]
|
|
||||||
jipian4 = liaopan4.children[coin_num_N].children[0]
|
|
||||||
#print(jipian1)
|
|
||||||
#从料盘上去物料解绑后放到另一盘上
|
|
||||||
jipian1.parent.unassign_child_resource(jipian1)
|
|
||||||
jipian4.parent.unassign_child_resource(jipian4)
|
|
||||||
|
|
||||||
#print(jipian2.parent)
|
|
||||||
battery = Battery(name = f"battery_{coin_num_N}")
|
|
||||||
battery.assign_child_resource(jipian1, location=None)
|
|
||||||
battery.assign_child_resource(jipian4, location=None)
|
|
||||||
|
|
||||||
zidanjia6 = self.deck.get_resource("zi_dan_jia6")
|
|
||||||
|
|
||||||
zidanjia6.children[0].assign_child_resource(battery, location=None)
|
|
||||||
|
|
||||||
|
|
||||||
# 生成断点文件
|
# 生成断点文件
|
||||||
# 生成包含elec_num_N、coin_num_N、timestamp的CSV文件
|
# 生成包含elec_num_N、coin_num_N、timestamp的CSV文件
|
||||||
@@ -842,6 +846,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
writer.writerow([elec_num, elec_use_num, elec_num_N, elec_use_num_N, coin_num_N, timestamp])
|
writer.writerow([elec_num, elec_use_num, elec_num_N, elec_use_num_N, coin_num_N, timestamp])
|
||||||
csvfile.flush()
|
csvfile.flush()
|
||||||
coin_num_N += 1
|
coin_num_N += 1
|
||||||
|
self.coin_num_N = coin_num_N
|
||||||
elec_use_num_N += 1
|
elec_use_num_N += 1
|
||||||
elec_num_N += 1
|
elec_num_N += 1
|
||||||
elec_use_num_N = 0
|
elec_use_num_N = 0
|
||||||
@@ -878,34 +883,22 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
|
|
||||||
def fun_wuliao_test(self) -> bool:
|
def fun_wuliao_test(self) -> bool:
|
||||||
#找到data_init中构建的2个物料盘
|
#找到data_init中构建的2个物料盘
|
||||||
#liaopan1 = self.deck.get_resource("liaopan1")
|
liaopan3 = self.station_resource.get_resource("\u7535\u6c60\u6599\u76d8")
|
||||||
#liaopan4 = self.deck.get_resource("liaopan4")
|
for i in range(16):
|
||||||
#for coin_num_N in range(16):
|
battery = ElectrodeSheet(name=f"battery_{i}", size_x=16, size_y=16, size_z=2)
|
||||||
# liaopan1 = self.deck.get_resource("liaopan1")
|
battery._unilabos_state = {
|
||||||
# liaopan4 = self.deck.get_resource("liaopan4")
|
"diameter": 20.0,
|
||||||
# jipian1 = liaopan1.children[coin_num_N].children[0]
|
"height": 20.0,
|
||||||
# jipian4 = liaopan4.children[coin_num_N].children[0]
|
"assembly_pressure": i,
|
||||||
# #print(jipian1)
|
"electrolyte_volume": 20.0,
|
||||||
# #从料盘上去物料解绑后放到另一盘上
|
"electrolyte_name": f"DP{i}"
|
||||||
# jipian1.parent.unassign_child_resource(jipian1)
|
}
|
||||||
# jipian4.parent.unassign_child_resource(jipian4)
|
liaopan3.children[i].assign_child_resource(battery, location=None)
|
||||||
#
|
|
||||||
# #print(jipian2.parent)
|
|
||||||
# battery = Battery(name = f"battery_{coin_num_N}")
|
|
||||||
# battery.assign_child_resource(jipian1, location=None)
|
|
||||||
# battery.assign_child_resource(jipian4, location=None)
|
|
||||||
#
|
|
||||||
# zidanjia6 = self.deck.get_resource("zi_dan_jia6")
|
|
||||||
# zidanjia6.children[0].assign_child_resource(battery, location=None)
|
|
||||||
# ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
|
||||||
# "resources": [self.deck]
|
|
||||||
# })
|
|
||||||
# time.sleep(2)
|
|
||||||
for i in range(20):
|
|
||||||
print(f"输出{i}")
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
|
|
||||||
|
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
||||||
|
"resources": [self.station_resource]
|
||||||
|
})
|
||||||
|
time.sleep(4)
|
||||||
# 数据读取与输出
|
# 数据读取与输出
|
||||||
def func_read_data_and_output(self, file_path: str="D:\\coin_cell_data"):
|
def func_read_data_and_output(self, file_path: str="D:\\coin_cell_data"):
|
||||||
# 检查CSV导出是否正在运行,已运行则跳出,防止同时启动两个while循环
|
# 检查CSV导出是否正在运行,已运行则跳出,防止同时启动两个while循环
|
||||||
@@ -1012,7 +1005,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
|||||||
# else:
|
# else:
|
||||||
# print("子弹夹洞位0没有极片")
|
# print("子弹夹洞位0没有极片")
|
||||||
#
|
#
|
||||||
# #把电解液从瓶中取到电池夹子中
|
# # TODO:#把电解液从瓶中取到电池夹子中
|
||||||
# battery_site = deck.get_resource("battery_press_1")
|
# battery_site = deck.get_resource("battery_press_1")
|
||||||
# clip_magazine_battery = deck.get_resource("clip_magazine_battery")
|
# clip_magazine_battery = deck.get_resource("clip_magazine_battery")
|
||||||
# if battery_site.has_battery():
|
# if battery_site.has_battery():
|
||||||
@@ -1119,24 +1112,52 @@ if __name__ == "__main__":
|
|||||||
#print("success")
|
#print("success")
|
||||||
#创建一个物料台面
|
#创建一个物料台面
|
||||||
|
|
||||||
#deck = create_a_coin_cell_deck()
|
deck = create_a_coin_cell_deck()
|
||||||
|
#deck = create_a_full_coin_cell_deck()
|
||||||
|
|
||||||
|
|
||||||
##在台面上找到料盘和极片
|
##在台面上找到料盘和极片
|
||||||
#liaopan1 = deck.get_resource("liaopan1")
|
#liaopan1 = deck.get_resource("liaopan1")
|
||||||
#liaopan2 = deck.get_resource("liaopan2")
|
#liaopan2 = deck.get_resource("liaopan2")
|
||||||
#jipian1 = liaopan1.children[1].children[0]
|
#jipian1 = liaopan1.children[1].children[0]
|
||||||
#
|
##
|
||||||
##print(jipian1)
|
#print(jipian1)
|
||||||
##把物料解绑后放到另一盘上
|
##把物料解绑后放到另一盘上
|
||||||
#jipian1.parent.unassign_child_resource(jipian1)
|
#jipian1.parent.unassign_child_resource(jipian1)
|
||||||
#liaopan2.children[1].assign_child_resource(jipian1, location=None)
|
#liaopan2.children[1].assign_child_resource(jipian1, location=None)
|
||||||
##print(jipian2.parent)
|
##print(jipian2.parent)
|
||||||
|
|
||||||
|
liaopan1 = deck.get_resource("liaopan1")
|
||||||
|
liaopan2 = deck.get_resource("liaopan2")
|
||||||
|
for i in range(16):
|
||||||
|
#找到liaopan1上每一个jipian
|
||||||
|
jipian_linshi = liaopan1.children[i].children[0]
|
||||||
|
#把物料解绑后放到另一盘上
|
||||||
|
print("极片:", jipian_linshi)
|
||||||
|
jipian_linshi.parent.unassign_child_resource(jipian_linshi)
|
||||||
|
liaopan2.children[i].assign_child_resource(jipian_linshi, location=None)
|
||||||
|
|
||||||
|
|
||||||
from unilabos.resources.graphio import resource_ulab_to_plr, convert_resources_to_type
|
from unilabos.resources.graphio import resource_ulab_to_plr, convert_resources_to_type
|
||||||
|
#with open("./button_battery_station_resources_unilab.json", "r", encoding="utf-8") as f:
|
||||||
|
# bioyond_resources_unilab = json.load(f)
|
||||||
|
#print(f"成功读取 JSON 文件,包含 {len(bioyond_resources_unilab)} 个资源")
|
||||||
|
#ulab_resources = convert_resources_to_type(bioyond_resources_unilab, List[PLRResource])
|
||||||
|
#print(f"转换结果类型: {type(ulab_resources)}")
|
||||||
|
#print(ulab_resources)
|
||||||
|
|
||||||
with open("./button_battery_decks_unilab.json", "r", encoding="utf-8") as f:
|
|
||||||
bioyond_resources_unilab = json.load(f)
|
|
||||||
print(f"成功读取 JSON 文件,包含 {len(bioyond_resources_unilab)} 个资源")
|
|
||||||
ulab_resources = convert_resources_to_type(bioyond_resources_unilab, List[PLRResource])
|
|
||||||
print(f"转换结果类型: {type(ulab_resources)}")
|
|
||||||
print(ulab_resources)
|
|
||||||
|
|
||||||
|
|
||||||
|
from unilabos.resources.graphio import convert_resources_from_type
|
||||||
|
from unilabos.config.config import BasicConfig
|
||||||
|
BasicConfig.ak = "beb0c15f-2279-46a1-aba5-00eaf89aef55"
|
||||||
|
BasicConfig.sk = "15d4f25e-3512-4f9c-9bfb-43ab85e7b561"
|
||||||
|
from unilabos.app.web.client import http_client
|
||||||
|
|
||||||
|
resources = convert_resources_from_type([deck], [Resource])
|
||||||
|
json.dump({"nodes": resources, "links": []}, open("button_battery_station_resources_unilab.json", "w"), indent=2)
|
||||||
|
|
||||||
|
#print(resources)
|
||||||
|
http_client.remote_addr = "https://uni-lab.test.bohrium.com/api/v1"
|
||||||
|
|
||||||
|
http_client.resource_add(resources)
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address
|
||||||
|
COIL_SYS_START_CMD,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8010
|
||||||
|
COIL_SYS_STOP_CMD,BOOL,,<EFBFBD>豸ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8020
|
||||||
|
COIL_SYS_RESET_CMD,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8030
|
||||||
|
COIL_SYS_HAND_CMD,BOOL,,<EFBFBD>豸<EFBFBD>ֶ<EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8040
|
||||||
|
COIL_SYS_AUTO_CMD,BOOL,,<EFBFBD>豸<EFBFBD>Զ<EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8050
|
||||||
|
COIL_SYS_INIT_CMD,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8060
|
||||||
|
COIL_UNILAB_SEND_MSG_SUCC_CMD,BOOL,,UNILAB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䷽<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8700
|
||||||
|
COIL_UNILAB_REC_MSG_SUCC_CMD,BOOL,,UNILAB<EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8710
|
||||||
|
COIL_SYS_START_STATUS,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8210
|
||||||
|
COIL_SYS_STOP_STATUS,BOOL,,<EFBFBD>豸ֹͣ<EFBFBD><EFBFBD>,,coil,8220
|
||||||
|
COIL_SYS_RESET_STATUS,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>,,coil,8230
|
||||||
|
COIL_SYS_HAND_STATUS,BOOL,,<EFBFBD>豸<EFBFBD>ֶ<EFBFBD>ģʽ,,coil,8240
|
||||||
|
COIL_SYS_AUTO_STATUS,BOOL,,<EFBFBD>豸<EFBFBD>Զ<EFBFBD>ģʽ,,coil,8250
|
||||||
|
COIL_SYS_INIT_STATUS,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8260
|
||||||
|
COIL_REQUEST_REC_MSG_STATUS,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䷽,,coil,8510
|
||||||
|
COIL_REQUEST_SEND_MSG_STATUS,BOOL,,<EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8500
|
||||||
|
REG_MSG_ELECTROLYTE_USE_NUM,INT16,,<EFBFBD><EFBFBD>ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һʹ<EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD>,,hold_register,11000
|
||||||
|
REG_MSG_ELECTROLYTE_NUM,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һʹ<EFBFBD><EFBFBD>ƿ<EFBFBD><EFBFBD>,,hold_register,11002
|
||||||
|
REG_MSG_ELECTROLYTE_VOLUME,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>,,hold_register,11004
|
||||||
|
REG_MSG_ASSEMBLY_TYPE,INT16,,<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD>ʽ,,hold_register,11006
|
||||||
|
REG_MSG_ASSEMBLY_PRESSURE,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,11008
|
||||||
|
REG_DATA_ASSEMBLY_COIN_CELL_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10000
|
||||||
|
REG_DATA_OPEN_CIRCUIT_VOLTAGE,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10002
|
||||||
|
REG_DATA_AXIS_X_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺX<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10004
|
||||||
|
REG_DATA_AXIS_Y_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺZ<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10006
|
||||||
|
REG_DATA_AXIS_Z_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺY<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10008
|
||||||
|
REG_DATA_POLE_WEIGHT,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10010
|
||||||
|
REG_DATA_ASSEMBLY_PER_TIME,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װʱ<EFBFBD><EFBFBD>,,hold_register,10012
|
||||||
|
REG_DATA_ASSEMBLY_PRESSURE,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10014
|
||||||
|
REG_DATA_ELECTROLYTE_VOLUME,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>,,hold_register,10016
|
||||||
|
REG_DATA_COIN_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10018
|
||||||
|
REG_DATA_ELECTROLYTE_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>,,hold_register,10020
|
||||||
|
REG_DATA_COIN_CELL_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>,,hold_register,10030
|
||||||
|
REG_DATA_STACK_VISON_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD>϶ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,12004
|
||||||
|
REG_DATA_GLOVE_BOX_PRESSURE,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>,,hold_register,10050
|
||||||
|
REG_DATA_GLOVE_BOX_WATER_CONTENT,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10052
|
||||||
|
REG_DATA_GLOVE_BOX_O2_CONTENT,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10054
|
||||||
|
UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM,BOOL,,Unilabȷ<EFBFBD><EFBFBD><EFBFBD>ѷ<EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Һƿ<EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8720
|
||||||
|
UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM,BOOL,,Unilab<EFBFBD>ɽ<EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD>Һƿ<EFBFBD><EFBFBD>,,coil,8520
|
||||||
|
REG_MSG_ELECTROLYTE_NUM_USED,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,496
|
||||||
|
REG_DATA_ELECTROLYTE_USE_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>װƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10000
|
||||||
|
UNILAB_SEND_FINISHED_CMD,BOOL,,Unilab<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8730
|
||||||
|
UNILAB_RECE_FINISHED_CMD,BOOL,,<EFBFBD><EFBFBD>֪unilab<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8530
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address,
|
||||||
|
COIL_SYS_START_CMD,BOOL,,,,coil,8010,
|
||||||
|
COIL_SYS_STOP_CMD,BOOL,,,,coil,8020,
|
||||||
|
COIL_SYS_RESET_CMD,BOOL,,,,coil,8030,
|
||||||
|
COIL_SYS_HAND_CMD,BOOL,,,,coil,8040,
|
||||||
|
COIL_SYS_AUTO_CMD,BOOL,,,,coil,8050,
|
||||||
|
COIL_SYS_INIT_CMD,BOOL,,,,coil,8060,
|
||||||
|
COIL_UNILAB_SEND_MSG_SUCC_CMD,BOOL,,,,coil,8700,
|
||||||
|
COIL_UNILAB_REC_MSG_SUCC_CMD,BOOL,,,,coil,8710,unilab_rec_msg_succ_cmd
|
||||||
|
COIL_SYS_START_STATUS,BOOL,,,,coil,8210,
|
||||||
|
COIL_SYS_STOP_STATUS,BOOL,,,,coil,8220,
|
||||||
|
COIL_SYS_RESET_STATUS,BOOL,,,,coil,8230,
|
||||||
|
COIL_SYS_HAND_STATUS,BOOL,,,,coil,8240,
|
||||||
|
COIL_SYS_AUTO_STATUS,BOOL,,,,coil,8250,
|
||||||
|
COIL_SYS_INIT_STATUS,BOOL,,,,coil,8260,
|
||||||
|
COIL_REQUEST_REC_MSG_STATUS,BOOL,,,,coil,8500,
|
||||||
|
COIL_REQUEST_SEND_MSG_STATUS,BOOL,,,,coil,8510,request_send_msg_status
|
||||||
|
REG_MSG_ELECTROLYTE_USE_NUM,INT16,,,,hold_register,11000,
|
||||||
|
REG_MSG_ELECTROLYTE_NUM,INT16,,,,hold_register,11002,unilab_send_msg_electrolyte_num
|
||||||
|
REG_MSG_ELECTROLYTE_VOLUME,INT16,,,,hold_register,11004,unilab_send_msg_electrolyte_vol
|
||||||
|
REG_MSG_ASSEMBLY_TYPE,INT16,,,,hold_register,11006,unilab_send_msg_assembly_type
|
||||||
|
REG_MSG_ASSEMBLY_PRESSURE,INT16,,,,hold_register,11008,unilab_send_msg_assembly_pressure
|
||||||
|
REG_DATA_ASSEMBLY_COIN_CELL_NUM,INT16,,,,hold_register,10000,data_assembly_coin_cell_num
|
||||||
|
REG_DATA_OPEN_CIRCUIT_VOLTAGE,FLOAT32,,,,hold_register,10002,data_open_circuit_voltage
|
||||||
|
REG_DATA_AXIS_X_POS,FLOAT32,,,,hold_register,10004,
|
||||||
|
REG_DATA_AXIS_Y_POS,FLOAT32,,,,hold_register,10006,
|
||||||
|
REG_DATA_AXIS_Z_POS,FLOAT32,,,,hold_register,10008,
|
||||||
|
REG_DATA_POLE_WEIGHT,FLOAT32,,,,hold_register,10010,data_pole_weight
|
||||||
|
REG_DATA_ASSEMBLY_PER_TIME,FLOAT32,,,,hold_register,10012,data_assembly_time
|
||||||
|
REG_DATA_ASSEMBLY_PRESSURE,INT16,,,,hold_register,10014,data_assembly_pressure
|
||||||
|
REG_DATA_ELECTROLYTE_VOLUME,INT16,,,,hold_register,10016,data_electrolyte_volume
|
||||||
|
REG_DATA_COIN_NUM,INT16,,,,hold_register,10018,data_coin_num
|
||||||
|
REG_DATA_ELECTROLYTE_CODE,STRING,,,,hold_register,10020,data_electrolyte_code()
|
||||||
|
REG_DATA_COIN_CELL_CODE,STRING,,,,hold_register,10030,data_coin_cell_code()
|
||||||
|
REG_DATA_STACK_VISON_CODE,STRING,,,,hold_register,12004,data_stack_vision_code()
|
||||||
|
REG_DATA_GLOVE_BOX_PRESSURE,FLOAT32,,,,hold_register,10050,data_glove_box_pressure
|
||||||
|
REG_DATA_GLOVE_BOX_WATER_CONTENT,FLOAT32,,,,hold_register,10052,data_glove_box_water_content
|
||||||
|
REG_DATA_GLOVE_BOX_O2_CONTENT,FLOAT32,,,,hold_register,10054,data_glove_box_o2_content
|
||||||
|
UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM,BOOL,,,,coil,8720,
|
||||||
|
UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM,BOOL,,,,coil,8520,
|
||||||
|
REG_MSG_ELECTROLYTE_NUM_USED,INT16,,,,hold_register,496,
|
||||||
|
REG_DATA_ELECTROLYTE_USE_NUM,INT16,,,,hold_register,10000,
|
||||||
|
UNILAB_SEND_FINISHED_CMD,BOOL,,,,coil,8730,
|
||||||
|
UNILAB_RECE_FINISHED_CMD,BOOL,,,,coil,8530,
|
||||||
|
REG_DATA_ASSEMBLY_TYPE,INT16,,,,hold_register,10018,ASSEMBLY_TYPE7or8
|
||||||
|
COIL_ALUMINUM_FOIL,BOOL,,,,coil,8340,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
|||||||
|
import json
|
||||||
|
import re
|
||||||
|
from pymodbus.client import ModbusTcpClient
|
||||||
|
from unilabos.device_comms.modbus_plc.modbus import WorderOrder, Coil, DiscreteInputs, HoldRegister, InputRegister, DataType
|
||||||
|
from pymodbus.constants import Endian
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Callable
|
||||||
|
from unilabos.device_comms.modbus_plc.client import TCPClient, ModbusNode, PLCWorkflow, ModbusWorkflow, WorkflowAction, BaseClient
|
||||||
|
from unilabos.device_comms.modbus_plc.modbus import DeviceType, Base as ModbusNodeBase, DataType, WorderOrder
|
||||||
|
|
||||||
|
class Coin_Cell_Assembly:
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
coin_cell_assmbly = Coin_Cell_Assembly(address="192.168.1.20", port="502")
|
||||||
|
|
||||||
|
#params = {
|
||||||
|
# "elec_num": 32
|
||||||
|
#}
|
||||||
|
#str_data = json.dumps(params, ensure_ascii=False)
|
||||||
|
#print('param:', coin_cell_assmbly.func_pack_device_write_batch_elec_param(params))
|
||||||
|
#time.sleep(1)
|
||||||
|
|
||||||
|
print(coin_cell_assmbly.func_pack_device_write_per_elec_param(
|
||||||
|
elec_use_num=4,
|
||||||
|
elec_num=5,
|
||||||
|
elec_vol=55,
|
||||||
|
assembly_type=25,
|
||||||
|
assembly_pressure=550))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
print('start:', coin_cell_assmbly.func_pack_device_start())
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print('start:', coin_cell_assmbly.func_pack_device_start())
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print('stop:', coin_cell_assmbly.func_pack_device_stop())
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# cmd coil
|
||||||
|
print('start cmd:', coin_cell_assmbly.sys_start_cmd(True))
|
||||||
|
time.sleep(1)
|
||||||
|
print('stop cmd:', coin_cell_assmbly.sys_stop_cmd(False))
|
||||||
|
time.sleep(1)
|
||||||
|
print('reset cmd:', coin_cell_assmbly.sys_reset_cmd(True))
|
||||||
|
time.sleep(1)
|
||||||
|
print('hand cmd:', coin_cell_assmbly.sys_hand_cmd(False))
|
||||||
|
time.sleep(1)
|
||||||
|
print('auto cmd:', coin_cell_assmbly.sys_auto_cmd(True))
|
||||||
|
time.sleep(1)
|
||||||
|
print('init cmd:', coin_cell_assmbly.sys_init_cmd(False))
|
||||||
|
time.sleep(1)
|
||||||
|
print('send msg succ cmd:', coin_cell_assmbly.unilab_send_msg_succ_cmd(False))
|
||||||
|
time.sleep(1)
|
||||||
|
print('rec msg succ cmd:', coin_cell_assmbly.unilab_rec_msg_succ_cmd(True))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# cmd reg
|
||||||
|
print('elec use num msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_use_num(8))
|
||||||
|
time.sleep(1)
|
||||||
|
print('elec num msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_num(4))
|
||||||
|
time.sleep(1)
|
||||||
|
print('elec vol msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_vol(3.3))
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly type msg:', coin_cell_assmbly.unilab_send_msg_assembly_type(1))
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly pressure msg:', coin_cell_assmbly.unilab_send_msg_assembly_pressure(1))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# status coil
|
||||||
|
print('start status:',coin_cell_assmbly.sys_start_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('stop status:',coin_cell_assmbly.sys_stop_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('reset status:',coin_cell_assmbly.sys_reset_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('hand status:',coin_cell_assmbly.sys_hand_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('auto status:', coin_cell_assmbly.sys_auto_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('init ok:', coin_cell_assmbly.sys_init_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('request rec msg:', coin_cell_assmbly.request_rec_msg_status)
|
||||||
|
time.sleep(1)
|
||||||
|
print('request send msg:', coin_cell_assmbly.request_send_msg_status)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# status reg
|
||||||
|
print('assembly coin cell num:', coin_cell_assmbly.data_assembly_coin_cell_num)
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly coin assembly per time:', coin_cell_assmbly.data_assembly_time)
|
||||||
|
time.sleep(1)
|
||||||
|
print('open circuit vol:', coin_cell_assmbly.data_open_circuit_voltage)
|
||||||
|
time.sleep(1)
|
||||||
|
print('axis x pos:', coin_cell_assmbly.data_axis_x_pos)
|
||||||
|
time.sleep(1)
|
||||||
|
print('axis y pos:', coin_cell_assmbly.data_axis_y_pos)
|
||||||
|
time.sleep(1)
|
||||||
|
print('axis z pos:', coin_cell_assmbly.data_axis_z_pos)
|
||||||
|
time.sleep(1)
|
||||||
|
print('pole weight:', coin_cell_assmbly.data_pole_weight)
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly pressure:', coin_cell_assmbly.data_assembly_coin_cell_num)
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly electrolyte vol:', coin_cell_assmbly.data_electrolyte_volume)
|
||||||
|
time.sleep(1)
|
||||||
|
print('assembly coin num:', coin_cell_assmbly.data_coin_num)
|
||||||
|
time.sleep(1)
|
||||||
|
print('coin cell code:', coin_cell_assmbly.data_coin_cell_code)
|
||||||
|
time.sleep(1)
|
||||||
|
print('elec code:', coin_cell_assmbly.data_electrolyte_code)
|
||||||
|
time.sleep(1)
|
||||||
|
print('glove box pressure:', coin_cell_assmbly.data_glove_box_pressure)
|
||||||
|
time.sleep(1)
|
||||||
|
print('glove box o2:', coin_cell_assmbly.data_glove_box_o2_content)
|
||||||
|
time.sleep(1)
|
||||||
|
print('glove box water:', coin_cell_assmbly.data_glove_box_water_content)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
'''
|
||||||
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig.json
Normal file
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig.json
Normal file
File diff suppressed because it is too large
Load Diff
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig2.json
Normal file
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig2.json
Normal file
File diff suppressed because it is too large
Load Diff
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig3.json
Normal file
1925
unilabos/devices/workstation/coin_cell_assembly/new_cellconfig3.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,691 @@
|
|||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "BatteryStation",
|
||||||
|
"name": "扣电工作站",
|
||||||
|
"children": [
|
||||||
|
"coin_cell_deck"
|
||||||
|
],
|
||||||
|
"parent": null,
|
||||||
|
"type": "device",
|
||||||
|
"class": "bettery_station_registry",
|
||||||
|
"position": {
|
||||||
|
"x": 600,
|
||||||
|
"y": 400,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"debug_mode": false,
|
||||||
|
"_comment": "protocol_type接外部工站固定写法字段,一般为空,station_resource写法也固定",
|
||||||
|
"protocol_type": [],
|
||||||
|
"station_resource": {
|
||||||
|
"data": {
|
||||||
|
"_resource_child_name": "coin_cell_deck",
|
||||||
|
"_resource_type": "unilabos.devices.workstation.coin_cell_assembly.button_battery_station:CoincellDeck"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"address": "192.168.1.20",
|
||||||
|
"port": 502
|
||||||
|
},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "coin_cell_deck",
|
||||||
|
"name": "coin_cell_deck",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [
|
||||||
|
"\u7535\u6c60\u6599\u76d8"
|
||||||
|
],
|
||||||
|
"parent": null,
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "CoincellDeck",
|
||||||
|
"size_x": 1000,
|
||||||
|
"size_y": 1000,
|
||||||
|
"size_z": 900,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "coin_cell_deck",
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_0_0",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_0_1",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_0_2",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_0_3",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_1_0",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_1_1",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_1_2",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_1_3",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_2_0",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_2_1",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_2_2",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_2_3",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_3_0",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_3_1",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_3_2",
|
||||||
|
"\u7535\u6c60\u6599\u76d8_materialhole_3_3"
|
||||||
|
],
|
||||||
|
"parent": "coin_cell_deck",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 100,
|
||||||
|
"y": 100,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialPlate",
|
||||||
|
"size_x": 120.8,
|
||||||
|
"size_y": 160.5,
|
||||||
|
"size_z": 10.0,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_plate",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null,
|
||||||
|
"ordering": {
|
||||||
|
"A1": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
|
||||||
|
"B1": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
|
||||||
|
"C1": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
|
||||||
|
"D1": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
|
||||||
|
"A2": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
|
||||||
|
"B2": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
|
||||||
|
"C2": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
|
||||||
|
"D2": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
|
||||||
|
"A3": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
|
||||||
|
"B3": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
|
||||||
|
"C3": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
|
||||||
|
"D3": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
|
||||||
|
"A4": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
|
||||||
|
"B4": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
|
||||||
|
"C4": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
|
||||||
|
"D4": "\u7535\u6c60\u6599\u76d8_materialhole_3_3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 12.4,
|
||||||
|
"y": 104.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 12.4,
|
||||||
|
"y": 80.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 12.4,
|
||||||
|
"y": 56.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 12.4,
|
||||||
|
"y": 32.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 36.4,
|
||||||
|
"y": 104.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 36.4,
|
||||||
|
"y": 80.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 36.4,
|
||||||
|
"y": 56.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 36.4,
|
||||||
|
"y": 32.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 60.4,
|
||||||
|
"y": 104.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 60.4,
|
||||||
|
"y": 80.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 60.4,
|
||||||
|
"y": 56.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 60.4,
|
||||||
|
"y": 32.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 84.4,
|
||||||
|
"y": 104.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 84.4,
|
||||||
|
"y": 80.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 84.4,
|
||||||
|
"y": 56.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_3",
|
||||||
|
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_3",
|
||||||
|
"sample_id": null,
|
||||||
|
"children": [],
|
||||||
|
"parent": "\u7535\u6c60\u6599\u76d8",
|
||||||
|
"type": "container",
|
||||||
|
"class": "",
|
||||||
|
"position": {
|
||||||
|
"x": 84.4,
|
||||||
|
"y": 32.25,
|
||||||
|
"z": 10.0
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"type": "MaterialHole",
|
||||||
|
"size_x": 16,
|
||||||
|
"size_y": 16,
|
||||||
|
"size_z": 16,
|
||||||
|
"rotation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"type": "Rotation"
|
||||||
|
},
|
||||||
|
"category": "material_hole",
|
||||||
|
"model": null,
|
||||||
|
"barcode": null
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"diameter": 20,
|
||||||
|
"depth": 10,
|
||||||
|
"max_sheets": 1,
|
||||||
|
"info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": []
|
||||||
|
}
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"debug_mode": false,
|
"debug_mode": false,
|
||||||
"_comment": "protocol_type接外部工站固定写法字段,一般为空,deck写法也固定",
|
"_comment": "protocol_type接外部工站固定写法字段,一般为空,station_resource写法也固定",
|
||||||
"protocol_type": [],
|
"protocol_type": [],
|
||||||
"deck": {
|
"station_resource": {
|
||||||
"data": {
|
"data": {
|
||||||
"_resource_child_name": "coin_cell_deck",
|
"_resource_child_name": "coin_cell_deck",
|
||||||
"_resource_type": "unilabos.devices.workstation.coin_cell_assembly.button_battery_station:CoincellDeck"
|
"_resource_type": "unilabos.devices.workstation.coin_cell_assembly.button_battery_station:CoincellDeck"
|
||||||
|
|||||||
750
unilabos/devices/workstation/coin_cell_assembly/test.ipynb
Normal file
750
unilabos/devices/workstation/coin_cell_assembly/test.ipynb
Normal file
@@ -0,0 +1,750 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 22,
|
||||||
|
"id": "80bc9500",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from __future__ import annotations\n",
|
||||||
|
"\n",
|
||||||
|
"from collections import OrderedDict\n",
|
||||||
|
"from typing import Any, Dict, List, Optional, TypedDict, Union, cast\n",
|
||||||
|
"\n",
|
||||||
|
"from pylabrobot.resources.coordinate import Coordinate\n",
|
||||||
|
"from pylabrobot.resources.container import Container\n",
|
||||||
|
"from pylabrobot.resources.deck import Deck\n",
|
||||||
|
"from pylabrobot.resources.itemized_resource import ItemizedResource\n",
|
||||||
|
"from pylabrobot.resources.resource import Resource\n",
|
||||||
|
"from pylabrobot.resources.resource_stack import ResourceStack\n",
|
||||||
|
"from pylabrobot.resources.tip_rack import TipRack, TipSpot\n",
|
||||||
|
"from pylabrobot.resources.trash import Trash\n",
|
||||||
|
"from pylabrobot.resources.utils import create_ordered_items_2d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "498a9159",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"物料类型构建"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 23,
|
||||||
|
"id": "f4a27241",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"class ElectrodeSheetState(TypedDict):\n",
|
||||||
|
" diameter: float # 直径 (mm)\n",
|
||||||
|
" thickness: float # 厚度 (mm)\n",
|
||||||
|
" mass: float # 质量 (g)\n",
|
||||||
|
" material_type: str # 材料类型(正极、负极、隔膜、弹片、垫片、铝箔等)\n",
|
||||||
|
" info: Optional[str] # 附加信息\n",
|
||||||
|
"\n",
|
||||||
|
"class ElectrodeSheet(Resource):\n",
|
||||||
|
" \"\"\"极片类 - 包含正负极片、隔膜、弹片、垫片、铝箔等所有片状材料\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" name: str = \"极片\",\n",
|
||||||
|
" size_x=10,\n",
|
||||||
|
" size_y=10,\n",
|
||||||
|
" size_z=10,\n",
|
||||||
|
" category: str = \"electrode_sheet\",\n",
|
||||||
|
" model: Optional[str] = None,\n",
|
||||||
|
" ):\n",
|
||||||
|
" \"\"\"初始化极片\n",
|
||||||
|
"\n",
|
||||||
|
" Args:\n",
|
||||||
|
" name: 极片名称\n",
|
||||||
|
" category: 类别\n",
|
||||||
|
" model: 型号\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" super().__init__(\n",
|
||||||
|
" name=name,\n",
|
||||||
|
" size_x=size_x,\n",
|
||||||
|
" size_y=size_y,\n",
|
||||||
|
" size_z=size_z,\n",
|
||||||
|
" category=category,\n",
|
||||||
|
" model=model,\n",
|
||||||
|
" )\n",
|
||||||
|
" self._unilabos_state: ElectrodeSheetState = ElectrodeSheetState(\n",
|
||||||
|
" diameter=14,\n",
|
||||||
|
" thickness=0.1,\n",
|
||||||
|
" mass=0.5,\n",
|
||||||
|
" material_type=\"copper\",\n",
|
||||||
|
" info=None\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # TODO: 这个还要不要?给self._unilabos_state赋值的?\n",
|
||||||
|
" def load_state(self, state: Dict[str, Any]) -> None:\n",
|
||||||
|
" \"\"\"格式不变\"\"\"\n",
|
||||||
|
" super().load_state(state)\n",
|
||||||
|
" self._unilabos_state = state\n",
|
||||||
|
" #序列化\n",
|
||||||
|
" def serialize_state(self) -> Dict[str, Dict[str, Any]]:\n",
|
||||||
|
" \"\"\"格式不变\"\"\"\n",
|
||||||
|
" data = super().serialize_state()\n",
|
||||||
|
" data.update(self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)\n",
|
||||||
|
" return data\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 24,
|
||||||
|
"id": "830f052e",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# TODO: 这个应该只能放一个极片\n",
|
||||||
|
"class MaterialHoleState(TypedDict):\n",
|
||||||
|
" diameter: int\n",
|
||||||
|
" depth: int\n",
|
||||||
|
" max_sheets: int\n",
|
||||||
|
" info: Optional[str] # 附加信息\n",
|
||||||
|
"\n",
|
||||||
|
"class MaterialHole(Resource):\n",
|
||||||
|
" \"\"\"料板洞位类\"\"\"\n",
|
||||||
|
" children: List[ElectrodeSheet] = []\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" name: str,\n",
|
||||||
|
" size_x: float,\n",
|
||||||
|
" size_y: float,\n",
|
||||||
|
" size_z: float,\n",
|
||||||
|
" category: str = \"material_hole\",\n",
|
||||||
|
" **kwargs\n",
|
||||||
|
" ):\n",
|
||||||
|
" super().__init__(\n",
|
||||||
|
" name=name,\n",
|
||||||
|
" size_x=size_x,\n",
|
||||||
|
" size_y=size_y,\n",
|
||||||
|
" size_z=size_z,\n",
|
||||||
|
" category=category,\n",
|
||||||
|
" )\n",
|
||||||
|
" self._unilabos_state: MaterialHoleState = MaterialHoleState(\n",
|
||||||
|
" diameter=20,\n",
|
||||||
|
" depth=10,\n",
|
||||||
|
" max_sheets=1,\n",
|
||||||
|
" info=None\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def get_all_sheet_info(self):\n",
|
||||||
|
" info_list = []\n",
|
||||||
|
" for sheet in self.children:\n",
|
||||||
|
" info_list.append(sheet._unilabos_state[\"info\"])\n",
|
||||||
|
" return info_list\n",
|
||||||
|
" \n",
|
||||||
|
" #这个函数函数好像没用,一般不会集中赋值质量\n",
|
||||||
|
" def set_all_sheet_mass(self):\n",
|
||||||
|
" for sheet in self.children:\n",
|
||||||
|
" sheet._unilabos_state[\"mass\"] = 0.5 # 示例:设置质量为0.5g\n",
|
||||||
|
"\n",
|
||||||
|
" def load_state(self, state: Dict[str, Any]) -> None:\n",
|
||||||
|
" \"\"\"格式不变\"\"\"\n",
|
||||||
|
" super().load_state(state)\n",
|
||||||
|
" self._unilabos_state = state\n",
|
||||||
|
"\n",
|
||||||
|
" def serialize_state(self) -> Dict[str, Dict[str, Any]]:\n",
|
||||||
|
" \"\"\"格式不变\"\"\"\n",
|
||||||
|
" data = super().serialize_state()\n",
|
||||||
|
" data.update(self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)\n",
|
||||||
|
" return data\n",
|
||||||
|
" #移动极片前先取出对象\n",
|
||||||
|
" def get_sheet_with_name(self, name: str) -> Optional[ElectrodeSheet]:\n",
|
||||||
|
" for sheet in self.children:\n",
|
||||||
|
" if sheet.name == name:\n",
|
||||||
|
" return sheet\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" def has_electrode_sheet(self) -> bool:\n",
|
||||||
|
" \"\"\"检查洞位是否有极片\"\"\"\n",
|
||||||
|
" return len(self.children) > 0\n",
|
||||||
|
"\n",
|
||||||
|
" def assign_child_resource(\n",
|
||||||
|
" self,\n",
|
||||||
|
" resource: ElectrodeSheet,\n",
|
||||||
|
" location: Optional[Coordinate],\n",
|
||||||
|
" reassign: bool = True,\n",
|
||||||
|
" ):\n",
|
||||||
|
" \"\"\"放置极片\"\"\"\n",
|
||||||
|
" # TODO: 这里要改,diameter找不到,加入._unilabos_state后应该没问题\n",
|
||||||
|
" if resource._unilabos_state[\"diameter\"] > self._unilabos_state[\"diameter\"]:\n",
|
||||||
|
" raise ValueError(f\"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}\")\n",
|
||||||
|
" if len(self.children) >= self._unilabos_state[\"max_sheets\"]:\n",
|
||||||
|
" raise ValueError(f\"洞位已满,无法放置更多极片\")\n",
|
||||||
|
" super().assign_child_resource(resource, location, reassign)\n",
|
||||||
|
"\n",
|
||||||
|
" # 根据children的编号取物料对象。\n",
|
||||||
|
" def get_electrode_sheet_info(self, index: int) -> ElectrodeSheet:\n",
|
||||||
|
" return self.children[index]\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"#料板\n",
|
||||||
|
"class MaterialPlateState(TypedDict):\n",
|
||||||
|
" hole_spacing_x: float\n",
|
||||||
|
" hole_spacing_y: float\n",
|
||||||
|
" hole_diameter: float\n",
|
||||||
|
" info: Optional[str] # 附加信息\n",
|
||||||
|
"\n",
|
||||||
|
"class MaterialPlate(ItemizedResource[MaterialHole]):\n",
|
||||||
|
" \"\"\"料板类 - 4x4个洞位,每个洞位放1个极片\"\"\"\n",
|
||||||
|
" \n",
|
||||||
|
" children: List[MaterialHole]\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" name: str,\n",
|
||||||
|
" size_x: float,\n",
|
||||||
|
" size_y: float,\n",
|
||||||
|
" size_z: float,\n",
|
||||||
|
" ordered_items: Optional[Dict[str, MaterialHole]] = None,\n",
|
||||||
|
" ordering: Optional[OrderedDict[str, str]] = None,\n",
|
||||||
|
" category: str = \"material_plate\",\n",
|
||||||
|
" model: Optional[str] = None,\n",
|
||||||
|
" fill: bool = False\n",
|
||||||
|
" ):\n",
|
||||||
|
" \"\"\"初始化料板\n",
|
||||||
|
"\n",
|
||||||
|
" Args:\n",
|
||||||
|
" name: 料板名称\n",
|
||||||
|
" size_x: 长度 (mm)\n",
|
||||||
|
" size_y: 宽度 (mm)\n",
|
||||||
|
" size_z: 高度 (mm)\n",
|
||||||
|
" hole_diameter: 洞直径 (mm)\n",
|
||||||
|
" hole_depth: 洞深度 (mm)\n",
|
||||||
|
" hole_spacing_x: X方向洞位间距 (mm)\n",
|
||||||
|
" hole_spacing_y: Y方向洞位间距 (mm)\n",
|
||||||
|
" number: 编号\n",
|
||||||
|
" category: 类别\n",
|
||||||
|
" model: 型号\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" self._unilabos_state: MaterialPlateState = MaterialPlateState(\n",
|
||||||
|
" hole_spacing_x=24.0,\n",
|
||||||
|
" hole_spacing_y=24.0,\n",
|
||||||
|
" hole_diameter=20.0,\n",
|
||||||
|
" info=\"\",\n",
|
||||||
|
" )\n",
|
||||||
|
" # 创建4x4的洞位\n",
|
||||||
|
" # TODO: 这里要改,对应不同形状\n",
|
||||||
|
" holes = create_ordered_items_2d(\n",
|
||||||
|
" klass=MaterialHole,\n",
|
||||||
|
" num_items_x=4,\n",
|
||||||
|
" num_items_y=4,\n",
|
||||||
|
" dx=(size_x - 4 * self._unilabos_state[\"hole_spacing_x\"]) / 2, # 居中\n",
|
||||||
|
" dy=(size_y - 4 * self._unilabos_state[\"hole_spacing_y\"]) / 2, # 居中\n",
|
||||||
|
" dz=size_z,\n",
|
||||||
|
" item_dx=self._unilabos_state[\"hole_spacing_x\"],\n",
|
||||||
|
" item_dy=self._unilabos_state[\"hole_spacing_y\"],\n",
|
||||||
|
" size_x = 16,\n",
|
||||||
|
" size_y = 16,\n",
|
||||||
|
" size_z = 16,\n",
|
||||||
|
" )\n",
|
||||||
|
" if fill:\n",
|
||||||
|
" super().__init__(\n",
|
||||||
|
" name=name,\n",
|
||||||
|
" size_x=size_x,\n",
|
||||||
|
" size_y=size_y,\n",
|
||||||
|
" size_z=size_z,\n",
|
||||||
|
" ordered_items=holes,\n",
|
||||||
|
" category=category,\n",
|
||||||
|
" model=model,\n",
|
||||||
|
" )\n",
|
||||||
|
" else:\n",
|
||||||
|
" super().__init__(\n",
|
||||||
|
" name=name,\n",
|
||||||
|
" size_x=size_x,\n",
|
||||||
|
" size_y=size_y,\n",
|
||||||
|
" size_z=size_z,\n",
|
||||||
|
" ordered_items=ordered_items,\n",
|
||||||
|
" ordering=ordering,\n",
|
||||||
|
" category=category,\n",
|
||||||
|
" model=model,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def update_locations(self):\n",
|
||||||
|
" # TODO:调多次相加\n",
|
||||||
|
" holes = create_ordered_items_2d(\n",
|
||||||
|
" klass=MaterialHole,\n",
|
||||||
|
" num_items_x=4,\n",
|
||||||
|
" num_items_y=4,\n",
|
||||||
|
" dx=(self._size_x - 3 * self._unilabos_state[\"hole_spacing_x\"]) / 2, # 居中\n",
|
||||||
|
" dy=(self._size_y - 3 * self._unilabos_state[\"hole_spacing_y\"]) / 2, # 居中\n",
|
||||||
|
" dz=self._size_z,\n",
|
||||||
|
" item_dx=self._unilabos_state[\"hole_spacing_x\"],\n",
|
||||||
|
" item_dy=self._unilabos_state[\"hole_spacing_y\"],\n",
|
||||||
|
" size_x = 1,\n",
|
||||||
|
" size_y = 1,\n",
|
||||||
|
" size_z = 1,\n",
|
||||||
|
" )\n",
|
||||||
|
" for item, original_item in zip(holes.items(), self.children):\n",
|
||||||
|
" original_item.location = item[1].location"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 25,
|
||||||
|
"id": "8318ccca",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class CoincellDeck(Deck):\n",
|
||||||
|
" \"\"\"纽扣电池组装工作站台面类\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" name: str = \"coin_cell_deck\",\n",
|
||||||
|
" size_x: float = 1620.0, # 3.66m\n",
|
||||||
|
" size_y: float = 1270.0, # 1.23m\n",
|
||||||
|
" size_z: float = 500.0,\n",
|
||||||
|
" origin: Coordinate = Coordinate(0, 0, 0),\n",
|
||||||
|
" category: str = \"coin_cell_deck\",\n",
|
||||||
|
" ):\n",
|
||||||
|
" \"\"\"初始化纽扣电池组装工作站台面\n",
|
||||||
|
"\n",
|
||||||
|
" Args:\n",
|
||||||
|
" name: 台面名称\n",
|
||||||
|
" size_x: 长度 (mm) - 3.66m\n",
|
||||||
|
" size_y: 宽度 (mm) - 1.23m\n",
|
||||||
|
" size_z: 高度 (mm)\n",
|
||||||
|
" origin: 原点坐标\n",
|
||||||
|
" category: 类别\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" super().__init__(\n",
|
||||||
|
" name=name,\n",
|
||||||
|
" size_x=size_x,\n",
|
||||||
|
" size_y=size_y,\n",
|
||||||
|
" size_z=size_z,\n",
|
||||||
|
" origin=origin,\n",
|
||||||
|
" category=category,\n",
|
||||||
|
" )"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"id": "c73bae21",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 17,
|
||||||
|
"id": "3369a1dd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def upload_resources_to_unilab(wuliao: List[Resource]):\n",
|
||||||
|
" from unilabos.resources.graphio import convert_resources_from_type\n",
|
||||||
|
" from unilabos.config.config import BasicConfig \n",
|
||||||
|
" BasicConfig.ak = \"beb0c15f-2279-46a1-aba5-00eaf89aef55\"\n",
|
||||||
|
" BasicConfig.sk = \"15d4f25e-3512-4f9c-9bfb-43ab85e7b561\"\n",
|
||||||
|
" from unilabos.app.web.client import http_client\n",
|
||||||
|
" resources = convert_resources_from_type(wuliao, [Resource])\n",
|
||||||
|
" json.dump({\"nodes\": resources, \"links\": []}, open(\"button_battery_station_resources_unilab.json\", \"w\"), indent=2)\n",
|
||||||
|
" \n",
|
||||||
|
" #print(resources)\n",
|
||||||
|
" http_client.remote_addr = \"https://uni-lab.test.bohrium.com/api/v1\"\n",
|
||||||
|
" \n",
|
||||||
|
" http_client.resource_add(resources)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 29,
|
||||||
|
"id": "1543ddab",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"liaopan1 = MaterialPlate(name=\"liaopan1\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 30,
|
||||||
|
"id": "b732754a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"MaterialPlate(name=liaopan1, size_x=120.8, size_y=120.5, size_z=10.0, location=None)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(liaopan1)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 31,
|
||||||
|
"id": "7e6e7252",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"[MaterialHole(name=liaopan1_materialhole_0_0, location=Coordinate(012.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_1, location=Coordinate(012.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_2, location=Coordinate(012.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_3, location=Coordinate(012.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_0, location=Coordinate(036.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_1, location=Coordinate(036.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_2, location=Coordinate(036.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_3, location=Coordinate(036.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_0, location=Coordinate(060.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_1, location=Coordinate(060.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_2, location=Coordinate(060.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_3, location=Coordinate(060.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_0, location=Coordinate(084.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_1, location=Coordinate(084.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_2, location=Coordinate(084.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_3, location=Coordinate(084.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole)]\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(liaopan1.children)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 26,
|
||||||
|
"id": "836ff68d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [15:15:08,950]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"CoincellDeck(name=coin_cell_deck, location=Coordinate(000.000, 000.000, 000.000), size_x=1620.0, size_y=1270.0, size_z=500.0, category=coin_cell_deck)\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [15:15:09,218]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"deck = CoincellDeck()\n",
|
||||||
|
"#创建一个4*4的物料板\n",
|
||||||
|
"liaopan1 = MaterialPlate(name=\"liaopan1\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)\n",
|
||||||
|
"#把物料板放到桌子上\n",
|
||||||
|
"deck.assign_child_resource(liaopan1, Coordinate(x=0, y=0, z=0))\n",
|
||||||
|
"#创建一个极片\n",
|
||||||
|
"for i in range(16):\n",
|
||||||
|
" jipian = ElectrodeSheet(name=f\"jipian_{i}\", size_x= 12, size_y=12, size_z=0.1)\n",
|
||||||
|
" liaopan1.children[i].assign_child_resource(jipian, location=None)\n",
|
||||||
|
"#创建一个4*4的物料板\n",
|
||||||
|
"liaopan2 = MaterialPlate(name=\"liaopan2\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)\n",
|
||||||
|
"#把物料板放到桌子上\n",
|
||||||
|
"deck.assign_child_resource(liaopan2, Coordinate(x=500, y=0, z=0))\n",
|
||||||
|
"#liaopan.children[3].assign_child_resource(jipian, location=None)\n",
|
||||||
|
"print(deck)\n",
|
||||||
|
"\n",
|
||||||
|
"upload_resources_to_unilab([deck])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 20,
|
||||||
|
"id": "00aab9cf",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"MaterialPlate(name=liaopan1, size_x=120.8, size_y=120.5, size_z=10.0, location=Coordinate(000.000, 000.000, 000.000))\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"liaopan1 = deck.get_resource(\"liaopan1\")\n",
|
||||||
|
"print(liaopan1)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "7409969c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"liaopan1 = deck.get_resource(\"liaopan1\")\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "096dde04",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 27,
|
||||||
|
"id": "5528df96",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [15:17:44,322]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"ElectrodeSheet(name=jipian_1, location=None, size_x=12, size_y=12, size_z=0.1, category=electrode_sheet)\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [15:17:44,599]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"#在台面上找到料盘和极片\n",
|
||||||
|
"liaopan1 = deck.get_resource(\"liaopan1\")\n",
|
||||||
|
"liaopan2 = deck.get_resource(\"liaopan2\")\n",
|
||||||
|
"jipian1 = liaopan1.children[1].children[0]\n",
|
||||||
|
"#\n",
|
||||||
|
"print(jipian1)\n",
|
||||||
|
"#把物料解绑后放到另一盘上\n",
|
||||||
|
"jipian1.parent.unassign_child_resource(jipian1)\n",
|
||||||
|
"liaopan2.children[1].assign_child_resource(jipian1, location=None)\n",
|
||||||
|
"#print(jipian2.parent)\n",
|
||||||
|
"upload_resources_to_unilab([deck])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "43736700",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [14:31:50,027]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||||
|
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\u001b[37m25-09-22 [14:31:50,358]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"<Response [200]>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 16,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "unilab",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.11.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
6674
unilabos/devices/workstation/coin_cell_assembly/work_station.yaml
Normal file
6674
unilabos/devices/workstation/coin_cell_assembly/work_station.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -668,7 +668,7 @@ __all__ = [
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 简单测试HTTP服务
|
# 简单测试HTTP服务
|
||||||
class BioyondWorkstation:
|
class DummyWorkstation:
|
||||||
device_id = "WS-001"
|
device_id = "WS-001"
|
||||||
|
|
||||||
def process_step_finish_report(self, report_request):
|
def process_step_finish_report(self, report_request):
|
||||||
|
|||||||
@@ -242,8 +242,11 @@ workstation.bioyond_dispensing_station:
|
|||||||
properties:
|
properties:
|
||||||
config:
|
config:
|
||||||
type: string
|
type: string
|
||||||
|
deck:
|
||||||
|
type: string
|
||||||
required:
|
required:
|
||||||
- config
|
- config
|
||||||
|
- deck
|
||||||
type: object
|
type: object
|
||||||
data:
|
data:
|
||||||
properties: {}
|
properties: {}
|
||||||
|
|||||||
834
unilabos/registry/devices/bioyond_cell.yaml
Normal file
834
unilabos/registry/devices/bioyond_cell.yaml
Normal file
@@ -0,0 +1,834 @@
|
|||||||
|
bioyond_cell:
|
||||||
|
category:
|
||||||
|
- bioyond_cell
|
||||||
|
class:
|
||||||
|
action_value_mappings:
|
||||||
|
auto-auto_batch_outbound_from_xlsx:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
xlsx_path: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
xlsx_path:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- xlsx_path
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: auto_batch_outbound_from_xlsx参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-auto_feeding4to3:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
WH3_x1_y1_z3_1_materialId: ''
|
||||||
|
WH3_x1_y1_z3_1_materialType: ''
|
||||||
|
WH3_x1_y1_z3_1_quantity: 0
|
||||||
|
WH3_x1_y2_z3_4_materialId: ''
|
||||||
|
WH3_x1_y2_z3_4_materialType: ''
|
||||||
|
WH3_x1_y2_z3_4_quantity: 0
|
||||||
|
WH3_x1_y3_z3_7_materialId: ''
|
||||||
|
WH3_x1_y3_z3_7_materialType: ''
|
||||||
|
WH3_x1_y3_z3_7_quantity: 0
|
||||||
|
WH3_x1_y4_z3_10_materialId: ''
|
||||||
|
WH3_x1_y4_z3_10_materialType: ''
|
||||||
|
WH3_x1_y4_z3_10_quantity: 0
|
||||||
|
WH3_x1_y5_z3_13_materialId: ''
|
||||||
|
WH3_x1_y5_z3_13_materialType: ''
|
||||||
|
WH3_x1_y5_z3_13_quantity: 0
|
||||||
|
WH3_x2_y1_z3_2_materialId: ''
|
||||||
|
WH3_x2_y1_z3_2_materialType: ''
|
||||||
|
WH3_x2_y1_z3_2_quantity: 0
|
||||||
|
WH3_x2_y2_z3_5_materialId: ''
|
||||||
|
WH3_x2_y2_z3_5_materialType: ''
|
||||||
|
WH3_x2_y2_z3_5_quantity: 0
|
||||||
|
WH3_x2_y3_z3_8_materialId: ''
|
||||||
|
WH3_x2_y3_z3_8_materialType: ''
|
||||||
|
WH3_x2_y3_z3_8_quantity: 0
|
||||||
|
WH3_x2_y4_z3_11_materialId: ''
|
||||||
|
WH3_x2_y4_z3_11_materialType: ''
|
||||||
|
WH3_x2_y4_z3_11_quantity: 0
|
||||||
|
WH3_x2_y5_z3_14_materialId: ''
|
||||||
|
WH3_x2_y5_z3_14_materialType: ''
|
||||||
|
WH3_x2_y5_z3_14_quantity: 0
|
||||||
|
WH3_x3_y1_z3_3_materialId: ''
|
||||||
|
WH3_x3_y1_z3_3_materialType: ''
|
||||||
|
WH3_x3_y1_z3_3_quantity: 0
|
||||||
|
WH3_x3_y2_z3_6_materialId: ''
|
||||||
|
WH3_x3_y2_z3_6_materialType: ''
|
||||||
|
WH3_x3_y2_z3_6_quantity: 0
|
||||||
|
WH3_x3_y3_z3_9_materialId: ''
|
||||||
|
WH3_x3_y3_z3_9_materialType: ''
|
||||||
|
WH3_x3_y3_z3_9_quantity: 0
|
||||||
|
WH3_x3_y4_z3_12_materialId: ''
|
||||||
|
WH3_x3_y4_z3_12_materialType: ''
|
||||||
|
WH3_x3_y4_z3_12_quantity: 0
|
||||||
|
WH3_x3_y5_z3_15_materialId: ''
|
||||||
|
WH3_x3_y5_z3_15_materialType: ''
|
||||||
|
WH3_x3_y5_z3_15_quantity: 0
|
||||||
|
WH4_x1_y1_z1_1_materialName: ''
|
||||||
|
WH4_x1_y1_z1_1_quantity: 0.0
|
||||||
|
WH4_x1_y1_z2_1_materialName: ''
|
||||||
|
WH4_x1_y1_z2_1_materialType: ''
|
||||||
|
WH4_x1_y1_z2_1_quantity: 0.0
|
||||||
|
WH4_x1_y1_z2_1_targetWH: ''
|
||||||
|
WH4_x1_y2_z1_6_materialName: ''
|
||||||
|
WH4_x1_y2_z1_6_quantity: 0.0
|
||||||
|
WH4_x1_y2_z2_4_materialName: ''
|
||||||
|
WH4_x1_y2_z2_4_materialType: ''
|
||||||
|
WH4_x1_y2_z2_4_quantity: 0.0
|
||||||
|
WH4_x1_y2_z2_4_targetWH: ''
|
||||||
|
WH4_x1_y3_z1_11_materialName: ''
|
||||||
|
WH4_x1_y3_z1_11_quantity: 0.0
|
||||||
|
WH4_x1_y3_z2_7_materialName: ''
|
||||||
|
WH4_x1_y3_z2_7_materialType: ''
|
||||||
|
WH4_x1_y3_z2_7_quantity: 0.0
|
||||||
|
WH4_x1_y3_z2_7_targetWH: ''
|
||||||
|
WH4_x2_y1_z1_2_materialName: ''
|
||||||
|
WH4_x2_y1_z1_2_quantity: 0.0
|
||||||
|
WH4_x2_y1_z2_2_materialName: ''
|
||||||
|
WH4_x2_y1_z2_2_materialType: ''
|
||||||
|
WH4_x2_y1_z2_2_quantity: 0.0
|
||||||
|
WH4_x2_y1_z2_2_targetWH: ''
|
||||||
|
WH4_x2_y2_z1_7_materialName: ''
|
||||||
|
WH4_x2_y2_z1_7_quantity: 0.0
|
||||||
|
WH4_x2_y2_z2_5_materialName: ''
|
||||||
|
WH4_x2_y2_z2_5_materialType: ''
|
||||||
|
WH4_x2_y2_z2_5_quantity: 0.0
|
||||||
|
WH4_x2_y2_z2_5_targetWH: ''
|
||||||
|
WH4_x2_y3_z1_12_materialName: ''
|
||||||
|
WH4_x2_y3_z1_12_quantity: 0.0
|
||||||
|
WH4_x2_y3_z2_8_materialName: ''
|
||||||
|
WH4_x2_y3_z2_8_materialType: ''
|
||||||
|
WH4_x2_y3_z2_8_quantity: 0.0
|
||||||
|
WH4_x2_y3_z2_8_targetWH: ''
|
||||||
|
WH4_x3_y1_z1_3_materialName: ''
|
||||||
|
WH4_x3_y1_z1_3_quantity: 0.0
|
||||||
|
WH4_x3_y1_z2_3_materialName: ''
|
||||||
|
WH4_x3_y1_z2_3_materialType: ''
|
||||||
|
WH4_x3_y1_z2_3_quantity: 0.0
|
||||||
|
WH4_x3_y1_z2_3_targetWH: ''
|
||||||
|
WH4_x3_y2_z1_8_materialName: ''
|
||||||
|
WH4_x3_y2_z1_8_quantity: 0.0
|
||||||
|
WH4_x3_y2_z2_6_materialName: ''
|
||||||
|
WH4_x3_y2_z2_6_materialType: ''
|
||||||
|
WH4_x3_y2_z2_6_quantity: 0.0
|
||||||
|
WH4_x3_y2_z2_6_targetWH: ''
|
||||||
|
WH4_x3_y3_z2_9_materialName: ''
|
||||||
|
WH4_x3_y3_z2_9_materialType: ''
|
||||||
|
WH4_x3_y3_z2_9_quantity: 0.0
|
||||||
|
WH4_x3_y3_z2_9_targetWH: ''
|
||||||
|
WH4_x4_y1_z1_4_materialName: ''
|
||||||
|
WH4_x4_y1_z1_4_quantity: 0.0
|
||||||
|
WH4_x4_y2_z1_9_materialName: ''
|
||||||
|
WH4_x4_y2_z1_9_quantity: 0.0
|
||||||
|
WH4_x5_y1_z1_5_materialName: ''
|
||||||
|
WH4_x5_y1_z1_5_quantity: 0.0
|
||||||
|
WH4_x5_y2_z1_10_materialName: ''
|
||||||
|
WH4_x5_y2_z1_10_quantity: 0.0
|
||||||
|
xlsx_path: unilabos/devices/workstation/bioyond_cell/样品导入模板.xlsx
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
WH3_x1_y1_z3_1_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y1_z3_1_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y1_z3_1_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x1_y2_z3_4_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y2_z3_4_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y2_z3_4_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x1_y3_z3_7_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y3_z3_7_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y3_z3_7_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x1_y4_z3_10_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y4_z3_10_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y4_z3_10_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x1_y5_z3_13_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y5_z3_13_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x1_y5_z3_13_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x2_y1_z3_2_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y1_z3_2_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y1_z3_2_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x2_y2_z3_5_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y2_z3_5_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y2_z3_5_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x2_y3_z3_8_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y3_z3_8_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y3_z3_8_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x2_y4_z3_11_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y4_z3_11_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y4_z3_11_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x2_y5_z3_14_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y5_z3_14_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x2_y5_z3_14_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x3_y1_z3_3_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y1_z3_3_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y1_z3_3_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x3_y2_z3_6_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y2_z3_6_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y2_z3_6_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x3_y3_z3_9_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y3_z3_9_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y3_z3_9_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x3_y4_z3_12_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y4_z3_12_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y4_z3_12_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH3_x3_y5_z3_15_materialId:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y5_z3_15_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH3_x3_y5_z3_15_quantity:
|
||||||
|
default: 0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y1_z1_1_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y1_z1_1_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y1_z2_1_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y1_z2_1_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y1_z2_1_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y1_z2_1_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y2_z1_6_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y2_z1_6_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y2_z2_4_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y2_z2_4_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y2_z2_4_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y2_z2_4_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y3_z1_11_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y3_z1_11_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y3_z2_7_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y3_z2_7_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x1_y3_z2_7_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x1_y3_z2_7_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y1_z1_2_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y1_z1_2_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y1_z2_2_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y1_z2_2_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y1_z2_2_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y1_z2_2_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y2_z1_7_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y2_z1_7_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y2_z2_5_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y2_z2_5_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y2_z2_5_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y2_z2_5_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y3_z1_12_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y3_z1_12_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y3_z2_8_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y3_z2_8_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x2_y3_z2_8_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x2_y3_z2_8_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y1_z1_3_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y1_z1_3_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x3_y1_z2_3_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y1_z2_3_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y1_z2_3_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x3_y1_z2_3_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y2_z1_8_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y2_z1_8_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x3_y2_z2_6_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y2_z2_6_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y2_z2_6_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x3_y2_z2_6_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y3_z2_9_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y3_z2_9_materialType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x3_y3_z2_9_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x3_y3_z2_9_targetWH:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x4_y1_z1_4_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x4_y1_z1_4_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x4_y2_z1_9_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x4_y2_z1_9_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x5_y1_z1_5_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x5_y1_z1_5_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
WH4_x5_y2_z1_10_materialName:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
WH4_x5_y2_z1_10_quantity:
|
||||||
|
default: 0.0
|
||||||
|
type: number
|
||||||
|
xlsx_path:
|
||||||
|
default: unilabos/devices/workstation/bioyond_cell/样品导入模板.xlsx
|
||||||
|
type: string
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: auto_feeding4to3参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-auto_feeding4to3_from_xlsx:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
xlsx_path: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
xlsx_path:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- xlsx_path
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: auto_feeding4to3_from_xlsx参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-create_orders:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
xlsx_path: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
xlsx_path:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- xlsx_path
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: create_orders参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-order_list_v2:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
beginTime: ''
|
||||||
|
endTime: ''
|
||||||
|
filter: ''
|
||||||
|
pageCount: 1
|
||||||
|
skipCount: 0
|
||||||
|
sorting: ''
|
||||||
|
status: ''
|
||||||
|
timeType: ''
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
beginTime:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
endTime:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
filter:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
pageCount:
|
||||||
|
default: 1
|
||||||
|
type: integer
|
||||||
|
skipCount:
|
||||||
|
default: 0
|
||||||
|
type: integer
|
||||||
|
sorting:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
timeType:
|
||||||
|
default: ''
|
||||||
|
type: string
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: order_list_v2参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-report_material_change:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
material_obj: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
material_obj:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- material_obj
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: report_material_change参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-scheduler_continue:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: scheduler_continue参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-scheduler_start:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: scheduler_start参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-scheduler_stop:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: scheduler_stop参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-storage_batch_inbound:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
items: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- items
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: storage_batch_inbound参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-storage_inbound:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
location_id: null
|
||||||
|
material_id: null
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
location_id:
|
||||||
|
type: string
|
||||||
|
material_id:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- material_id
|
||||||
|
- location_id
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: storage_inbound参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-transfer_1_to_2:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default: {}
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: transfer_1_to_2参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-transfer_3_to_2_to_1:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
source_wh_id: 3a19debc-84b4-0359-e2d4-b3beea49348b
|
||||||
|
source_x: 1
|
||||||
|
source_y: 1
|
||||||
|
source_z: 1
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
source_wh_id:
|
||||||
|
default: 3a19debc-84b4-0359-e2d4-b3beea49348b
|
||||||
|
type: string
|
||||||
|
source_x:
|
||||||
|
default: 1
|
||||||
|
type: integer
|
||||||
|
source_y:
|
||||||
|
default: 1
|
||||||
|
type: integer
|
||||||
|
source_z:
|
||||||
|
default: 1
|
||||||
|
type: integer
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: transfer_3_to_2_to_1参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
auto-wait_for_transfer_task:
|
||||||
|
feedback: {}
|
||||||
|
goal: {}
|
||||||
|
goal_default:
|
||||||
|
filter_text: null
|
||||||
|
interval: 5
|
||||||
|
timeout: 3000
|
||||||
|
handles: {}
|
||||||
|
placeholder_keys: {}
|
||||||
|
result: {}
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
properties:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
filter_text:
|
||||||
|
type: string
|
||||||
|
interval:
|
||||||
|
default: 5
|
||||||
|
type: integer
|
||||||
|
timeout:
|
||||||
|
default: 3000
|
||||||
|
type: integer
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
result: {}
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: wait_for_transfer_task参数
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
module: unilabos.devices.workstation.bioyond_studio.bioyond_cell.bioyond_cell_workstation:BioyondCellWorkstation
|
||||||
|
status_types: {}
|
||||||
|
type: python
|
||||||
|
config_info: []
|
||||||
|
description: ''
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema:
|
||||||
|
config:
|
||||||
|
properties:
|
||||||
|
bioyond_config:
|
||||||
|
type: string
|
||||||
|
station_resource:
|
||||||
|
type: string
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
data:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
type: object
|
||||||
|
registry_type: device
|
||||||
|
version: 1.0.0
|
||||||
@@ -1,231 +1,3 @@
|
|||||||
hplc.agilent:
|
|
||||||
category:
|
|
||||||
- characterization_chromatic
|
|
||||||
class:
|
|
||||||
action_value_mappings:
|
|
||||||
auto-check_status:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default: {}
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 检查安捷伦HPLC设备状态的函数。用于监控设备的运行状态、连接状态、错误信息等关键指标。该函数定期查询设备状态,确保系统稳定运行,及时发现和报告设备异常。适用于自动化流程中的设备监控、故障诊断、系统维护等场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties: {}
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: check_status参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-extract_data_from_txt:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
file_path: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 从文本文件中提取分析数据的函数。用于解析安捷伦HPLC生成的结果文件,提取峰面积、保留时间、浓度等关键分析数据。支持多种文件格式的自动识别和数据结构化处理,为后续数据分析和报告生成提供标准化的数据格式。适用于批量数据处理、结果验证、质量控制等分析工作流程。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
file_path:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- file_path
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: extract_data_from_txt参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-start_sequence:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
params: null
|
|
||||||
resource: null
|
|
||||||
wf_name: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 启动安捷伦HPLC分析序列的函数。用于执行预定义的分析方法序列,包括样品进样、色谱分离、检测等完整的分析流程。支持参数配置、资源分配、工作流程管理等功能,实现全自动的样品分析。适用于批量样品处理、标准化分析、质量检测等需要连续自动分析的应用场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
params:
|
|
||||||
type: string
|
|
||||||
resource:
|
|
||||||
type: object
|
|
||||||
wf_name:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- wf_name
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: start_sequence参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-try_close_sub_device:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
device_name: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 尝试关闭HPLC子设备的函数。用于安全地关闭泵、检测器、进样器等各个子模块,确保设备正常断开连接并保护硬件安全。该函数提供错误处理和状态确认机制,避免强制关闭可能造成的设备损坏。适用于设备维护、系统重启、紧急停机等需要安全关闭设备的场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
device_name:
|
|
||||||
type: string
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: try_close_sub_device参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-try_open_sub_device:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
device_name: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 尝试打开HPLC子设备的函数。用于初始化和连接泵、检测器、进样器等各个子模块,建立设备通信并进行自检。该函数提供连接验证和错误恢复机制,确保子设备正常启动并准备就绪。适用于设备初始化、系统启动、设备重连等需要建立设备连接的场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
device_name:
|
|
||||||
type: string
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: try_open_sub_device参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
execute_command_from_outer:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
command: command
|
|
||||||
goal_default:
|
|
||||||
command: ''
|
|
||||||
handles: {}
|
|
||||||
result:
|
|
||||||
success: success
|
|
||||||
schema:
|
|
||||||
description: ''
|
|
||||||
properties:
|
|
||||||
feedback:
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- status
|
|
||||||
title: SendCmd_Feedback
|
|
||||||
type: object
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
command:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- command
|
|
||||||
title: SendCmd_Goal
|
|
||||||
type: object
|
|
||||||
result:
|
|
||||||
properties:
|
|
||||||
return_info:
|
|
||||||
type: string
|
|
||||||
success:
|
|
||||||
type: boolean
|
|
||||||
required:
|
|
||||||
- return_info
|
|
||||||
- success
|
|
||||||
title: SendCmd_Result
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: SendCmd
|
|
||||||
type: object
|
|
||||||
type: SendCmd
|
|
||||||
module: unilabos.devices.hplc.AgilentHPLC:HPLCDriver
|
|
||||||
status_types:
|
|
||||||
could_run: bool
|
|
||||||
data_file: String
|
|
||||||
device_status: str
|
|
||||||
driver_init_ok: bool
|
|
||||||
finish_status: str
|
|
||||||
is_running: bool
|
|
||||||
status_text: str
|
|
||||||
success: bool
|
|
||||||
type: python
|
|
||||||
config_info: []
|
|
||||||
description: 安捷伦高效液相色谱(HPLC)分析设备,用于复杂化合物的分离、检测和定量分析。该设备通过UI自动化技术控制安捷伦ChemStation软件,实现全自动的样品分析流程。具备序列启动、设备状态监控、数据文件提取、结果处理等功能。支持多样品批量处理和实时状态反馈,适用于药物分析、环境检测、食品安全、化学研究等需要高精度色谱分析的实验室应用。
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema:
|
|
||||||
config:
|
|
||||||
properties:
|
|
||||||
driver_debug:
|
|
||||||
default: false
|
|
||||||
type: string
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
data:
|
|
||||||
properties:
|
|
||||||
could_run:
|
|
||||||
type: boolean
|
|
||||||
data_file:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
device_status:
|
|
||||||
type: string
|
|
||||||
driver_init_ok:
|
|
||||||
type: boolean
|
|
||||||
finish_status:
|
|
||||||
type: string
|
|
||||||
is_running:
|
|
||||||
type: boolean
|
|
||||||
status_text:
|
|
||||||
type: string
|
|
||||||
success:
|
|
||||||
type: boolean
|
|
||||||
required:
|
|
||||||
- status_text
|
|
||||||
- device_status
|
|
||||||
- could_run
|
|
||||||
- driver_init_ok
|
|
||||||
- is_running
|
|
||||||
- success
|
|
||||||
- finish_status
|
|
||||||
- data_file
|
|
||||||
type: object
|
|
||||||
version: 1.0.0
|
|
||||||
hplc.agilent-zhida:
|
hplc.agilent-zhida:
|
||||||
category:
|
category:
|
||||||
- characterization_chromatic
|
- characterization_chromatic
|
||||||
|
|||||||
@@ -1,194 +1 @@
|
|||||||
raman.home_made:
|
{}
|
||||||
category:
|
|
||||||
- characterization_optic
|
|
||||||
class:
|
|
||||||
action_value_mappings:
|
|
||||||
auto-ccd_time:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
int_time: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 设置CCD检测器积分时间的函数。用于配置拉曼光谱仪的信号采集时间,控制光谱数据的质量和信噪比。较长的积分时间可获得更高的信号强度和更好的光谱质量,但会增加测量时间。该函数允许根据样品特性和测量要求动态调整检测参数,优化测量效果。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
int_time:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- int_time
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: ccd_time参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-laser_on_power:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
output_voltage_laser: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 设置激光器输出功率的函数。用于控制拉曼光谱仪激光器的功率输出,调节激光强度以适应不同样品的测量需求。适当的激光功率能够获得良好的拉曼信号同时避免样品损伤。该函数支持精确的功率控制,确保测量结果的稳定性和重现性。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
output_voltage_laser:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- output_voltage_laser
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: laser_on_power参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-raman_without_background:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
int_time: null
|
|
||||||
laser_power: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 执行无背景扣除的拉曼光谱测量函数。用于直接采集样品的拉曼光谱信号,不进行背景校正处理。该函数配置积分时间和激光功率参数,获取原始光谱数据用于后续的数据处理分析。适用于对光谱数据质量要求较高或需要自定义背景处理流程的测量场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
int_time:
|
|
||||||
type: string
|
|
||||||
laser_power:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- int_time
|
|
||||||
- laser_power
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: raman_without_background参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-raman_without_background_average:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
average: null
|
|
||||||
int_time: null
|
|
||||||
laser_power: null
|
|
||||||
sample_name: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 执行多次平均的无背景拉曼光谱测量函数。通过多次测量取平均值来提高光谱数据的信噪比和测量精度,减少随机噪声影响。该函数支持自定义平均次数、积分时间、激光功率等参数,并可为样品指定名称便于数据管理。适用于对测量精度要求较高的定量分析和研究应用。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
average:
|
|
||||||
type: string
|
|
||||||
int_time:
|
|
||||||
type: string
|
|
||||||
laser_power:
|
|
||||||
type: string
|
|
||||||
sample_name:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- sample_name
|
|
||||||
- int_time
|
|
||||||
- laser_power
|
|
||||||
- average
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: raman_without_background_average参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
raman_cmd:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
command: command
|
|
||||||
goal_default:
|
|
||||||
command: ''
|
|
||||||
handles: {}
|
|
||||||
result:
|
|
||||||
success: success
|
|
||||||
schema:
|
|
||||||
description: ''
|
|
||||||
properties:
|
|
||||||
feedback:
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- status
|
|
||||||
title: SendCmd_Feedback
|
|
||||||
type: object
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
command:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- command
|
|
||||||
title: SendCmd_Goal
|
|
||||||
type: object
|
|
||||||
result:
|
|
||||||
properties:
|
|
||||||
return_info:
|
|
||||||
type: string
|
|
||||||
success:
|
|
||||||
type: boolean
|
|
||||||
required:
|
|
||||||
- return_info
|
|
||||||
- success
|
|
||||||
title: SendCmd_Result
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: SendCmd
|
|
||||||
type: object
|
|
||||||
type: SendCmd
|
|
||||||
module: unilabos.devices.raman_uv.home_made_raman:RamanObj
|
|
||||||
status_types: {}
|
|
||||||
type: python
|
|
||||||
config_info: []
|
|
||||||
description: 拉曼光谱分析设备,用于物质的分子结构和化学成分表征。该设备集成激光器和CCD检测器,通过串口通信控制激光功率和光谱采集。具备背景扣除、多次平均、自动数据处理等功能,支持高精度的拉曼光谱测量。适用于材料表征、化学分析、质量控制、研究开发等需要分子指纹识别和结构分析的实验应用。
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema:
|
|
||||||
config:
|
|
||||||
properties:
|
|
||||||
baudrate_ccd:
|
|
||||||
default: 921600
|
|
||||||
type: string
|
|
||||||
baudrate_laser:
|
|
||||||
default: 9600
|
|
||||||
type: string
|
|
||||||
port_ccd:
|
|
||||||
type: string
|
|
||||||
port_laser:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- port_laser
|
|
||||||
- port_ccd
|
|
||||||
type: object
|
|
||||||
data:
|
|
||||||
properties: {}
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
version: 1.0.0
|
|
||||||
|
|||||||
@@ -75,31 +75,6 @@ reaction_station.bioyond:
|
|||||||
title: load_bioyond_data_from_file参数
|
title: load_bioyond_data_from_file参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
auto-merge_workflow_with_parameters:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
json_str: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: ''
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
json_str:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- json_str
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: merge_workflow_with_parameters参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-post_init:
|
auto-post_init:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -729,6 +704,7 @@ reaction_station.bioyond:
|
|||||||
status_types:
|
status_types:
|
||||||
all_workflows: dict
|
all_workflows: dict
|
||||||
bioyond_status: dict
|
bioyond_status: dict
|
||||||
|
station_info: dict
|
||||||
workstation_status: dict
|
workstation_status: dict
|
||||||
type: python
|
type: python
|
||||||
config_info: []
|
config_info: []
|
||||||
@@ -742,8 +718,6 @@ reaction_station.bioyond:
|
|||||||
type: string
|
type: string
|
||||||
deck:
|
deck:
|
||||||
type: string
|
type: string
|
||||||
station_config:
|
|
||||||
type: string
|
|
||||||
required: []
|
required: []
|
||||||
type: object
|
type: object
|
||||||
data:
|
data:
|
||||||
@@ -752,11 +726,14 @@ reaction_station.bioyond:
|
|||||||
type: object
|
type: object
|
||||||
bioyond_status:
|
bioyond_status:
|
||||||
type: object
|
type: object
|
||||||
|
station_info:
|
||||||
|
type: object
|
||||||
workstation_status:
|
workstation_status:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- bioyond_status
|
- bioyond_status
|
||||||
- all_workflows
|
- all_workflows
|
||||||
|
- station_info
|
||||||
- workstation_status
|
- workstation_status
|
||||||
type: object
|
type: object
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|||||||
@@ -834,174 +834,3 @@ linear_motion.toyo_xyz.sim:
|
|||||||
mesh: toyo_xyz
|
mesh: toyo_xyz
|
||||||
type: device
|
type: device
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
motor.iCL42:
|
|
||||||
category:
|
|
||||||
- robot_linear_motion
|
|
||||||
class:
|
|
||||||
action_value_mappings:
|
|
||||||
auto-execute_run_motor:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
mode: null
|
|
||||||
position: null
|
|
||||||
velocity: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 步进电机执行运动函数。直接执行电机运动命令,包括位置设定、速度控制和路径规划。该函数处理底层的电机控制协议,消除警告信息,设置运动参数并启动电机运行。适用于需要直接控制电机运动的应用场景。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
position:
|
|
||||||
type: number
|
|
||||||
velocity:
|
|
||||||
type: integer
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- position
|
|
||||||
- velocity
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: execute_run_motor参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-init_device:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default: {}
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: iCL42电机设备初始化函数。建立与iCL42步进电机驱动器的串口通信连接,配置通信参数包括波特率、数据位、校验位等。该函数是电机使用前的必要步骤,确保驱动器处于可控状态并准备接收运动指令。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties: {}
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: init_device参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-run_motor:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
mode: null
|
|
||||||
position: null
|
|
||||||
velocity: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: 步进电机运动控制函数。根据指定的运动模式、目标位置和速度参数控制电机运动。支持多种运动模式和精确的位置控制,自动处理运动轨迹规划和执行。该函数提供异步执行和状态反馈,确保运动的准确性和可靠性。
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
position:
|
|
||||||
type: number
|
|
||||||
velocity:
|
|
||||||
type: integer
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- position
|
|
||||||
- velocity
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: run_motor参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
execute_command_from_outer:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
command: command
|
|
||||||
goal_default:
|
|
||||||
command: ''
|
|
||||||
handles: {}
|
|
||||||
result:
|
|
||||||
success: success
|
|
||||||
schema:
|
|
||||||
description: ''
|
|
||||||
properties:
|
|
||||||
feedback:
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- status
|
|
||||||
title: SendCmd_Feedback
|
|
||||||
type: object
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
command:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- command
|
|
||||||
title: SendCmd_Goal
|
|
||||||
type: object
|
|
||||||
result:
|
|
||||||
properties:
|
|
||||||
return_info:
|
|
||||||
type: string
|
|
||||||
success:
|
|
||||||
type: boolean
|
|
||||||
required:
|
|
||||||
- return_info
|
|
||||||
- success
|
|
||||||
title: SendCmd_Result
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: SendCmd
|
|
||||||
type: object
|
|
||||||
type: SendCmd
|
|
||||||
module: unilabos.devices.motor.iCL42:iCL42Driver
|
|
||||||
status_types:
|
|
||||||
is_executing_run: bool
|
|
||||||
motor_position: int
|
|
||||||
success: bool
|
|
||||||
type: python
|
|
||||||
config_info: []
|
|
||||||
description: iCL42步进电机驱动器,用于实验室设备的精密线性运动控制。该设备通过串口通信控制iCL42型步进电机驱动器,支持多种运动模式和精确的位置、速度控制。具备位置反馈、运行状态监控和故障检测功能。适用于自动进样器、样品传送、精密定位平台等需要准确线性运动控制的实验室自动化设备。
|
|
||||||
handles: []
|
|
||||||
icon: ''
|
|
||||||
init_param_schema:
|
|
||||||
config:
|
|
||||||
properties:
|
|
||||||
device_address:
|
|
||||||
default: 1
|
|
||||||
type: integer
|
|
||||||
device_com:
|
|
||||||
default: COM9
|
|
||||||
type: string
|
|
||||||
required: []
|
|
||||||
type: object
|
|
||||||
data:
|
|
||||||
properties:
|
|
||||||
is_executing_run:
|
|
||||||
type: boolean
|
|
||||||
motor_position:
|
|
||||||
type: integer
|
|
||||||
success:
|
|
||||||
type: boolean
|
|
||||||
required:
|
|
||||||
- motor_position
|
|
||||||
- is_executing_run
|
|
||||||
- success
|
|
||||||
type: object
|
|
||||||
version: 1.0.0
|
|
||||||
|
|||||||
@@ -6120,31 +6120,6 @@ workstation.bioyond:
|
|||||||
title: load_bioyond_data_from_file参数
|
title: load_bioyond_data_from_file参数
|
||||||
type: object
|
type: object
|
||||||
type: UniLabJsonCommand
|
type: UniLabJsonCommand
|
||||||
auto-merge_workflow_with_parameters:
|
|
||||||
feedback: {}
|
|
||||||
goal: {}
|
|
||||||
goal_default:
|
|
||||||
json_str: null
|
|
||||||
handles: {}
|
|
||||||
placeholder_keys: {}
|
|
||||||
result: {}
|
|
||||||
schema:
|
|
||||||
description: ''
|
|
||||||
properties:
|
|
||||||
feedback: {}
|
|
||||||
goal:
|
|
||||||
properties:
|
|
||||||
json_str:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- json_str
|
|
||||||
type: object
|
|
||||||
result: {}
|
|
||||||
required:
|
|
||||||
- goal
|
|
||||||
title: merge_workflow_with_parameters参数
|
|
||||||
type: object
|
|
||||||
type: UniLabJsonCommand
|
|
||||||
auto-post_init:
|
auto-post_init:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
@@ -6460,6 +6435,7 @@ workstation.bioyond:
|
|||||||
status_types:
|
status_types:
|
||||||
all_workflows: dict
|
all_workflows: dict
|
||||||
bioyond_status: dict
|
bioyond_status: dict
|
||||||
|
station_info: dict
|
||||||
workstation_status: dict
|
workstation_status: dict
|
||||||
type: python
|
type: python
|
||||||
config_info: []
|
config_info: []
|
||||||
@@ -6473,8 +6449,6 @@ workstation.bioyond:
|
|||||||
type: string
|
type: string
|
||||||
deck:
|
deck:
|
||||||
type: string
|
type: string
|
||||||
station_config:
|
|
||||||
type: string
|
|
||||||
required: []
|
required: []
|
||||||
type: object
|
type: object
|
||||||
data:
|
data:
|
||||||
@@ -6483,11 +6457,14 @@ workstation.bioyond:
|
|||||||
type: object
|
type: object
|
||||||
bioyond_status:
|
bioyond_status:
|
||||||
type: object
|
type: object
|
||||||
|
station_info:
|
||||||
|
type: object
|
||||||
workstation_status:
|
workstation_status:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- bioyond_status
|
- bioyond_status
|
||||||
- all_workflows
|
- all_workflows
|
||||||
|
- station_info
|
||||||
- workstation_status
|
- workstation_status
|
||||||
type: object
|
type: object
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|||||||
@@ -1,46 +1,130 @@
|
|||||||
BIOYOND_PolymerStation_1BottleCarrier:
|
1BottleCarrier:
|
||||||
category:
|
category:
|
||||||
- bottle_carriers
|
- bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_1BottleCarrier
|
module: unilabos.resources.bioyond.bottle_carriers:YB_1BottleCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: BIOYOND_PolymerStation_1BottleCarrier
|
description: 1BottleCarrier
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_1FlaskCarrier:
|
1FlaskCarrier:
|
||||||
category:
|
category:
|
||||||
- bottle_carriers
|
- bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_1FlaskCarrier
|
module: unilabos.resources.bioyond.bottle_carriers:YB_1FlaskCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: BIOYOND_PolymerStation_1FlaskCarrier
|
description: 1FlaskCarrier
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_6StockCarrier:
|
6StockCarrier:
|
||||||
category:
|
category:
|
||||||
- bottle_carriers
|
- bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6StockCarrier
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6StockCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: BIOYOND_PolymerStation_6StockCarrier
|
description: 6StockCarrier
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_6VialCarrier:
|
6VialCarrier:
|
||||||
category:
|
category:
|
||||||
- bottle_carriers
|
- bottle_carriers
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottle_carriers:BIOYOND_PolymerStation_6VialCarrier
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6VialCarrier
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
description: BIOYOND_PolymerStation_6VialCarrier
|
description: 6VialCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
6x5ml_DispensingVialCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6x5ml_DispensingVialCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: 6x5ml_DispensingVialCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
6x20ml_DispensingVialCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6x20ml_DispensingVialCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: 6x20ml_DispensingVialCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
6x_SmallSolutionBottleCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6x_SmallSolutionBottleCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: 6x_SmallSolutionBottleCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
4x_LargeSolutionBottleCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_4x_LargeSolutionBottleCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: 4x_LargeSolutionBottleCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
6x_LargeDispenseHeadCarrier:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_6x_LargeDispenseHeadCarrier
|
||||||
|
type: pylabrobot
|
||||||
|
description: 6x_LargeDispenseHeadCarrier
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
AdapterBlock:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_AdapterBlock
|
||||||
|
type: pylabrobot
|
||||||
|
description: AdapterBlock
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
TipBox:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottle_carriers:YB_TipBox
|
||||||
|
type: pylabrobot
|
||||||
|
description: TipBox
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
|
|||||||
@@ -1,50 +1,281 @@
|
|||||||
BIOYOND_PolymerStation_Liquid_Vial:
|
Liquid_Vial:
|
||||||
category:
|
category:
|
||||||
- bottles
|
- bottles
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Liquid_Vial
|
module: unilabos.resources.bioyond.bottles:YB_Liquid_Vial
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_Reagent_Bottle:
|
Reagent_Bottle:
|
||||||
category:
|
category:
|
||||||
- bottles
|
- bottles
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Reagent_Bottle
|
module: unilabos.resources.bioyond.bottles:YB_Reagent_Bottle
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_Solid_Stock:
|
Solid_Stock:
|
||||||
category:
|
category:
|
||||||
- bottles
|
- bottles
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solid_Stock
|
module: unilabos.resources.bioyond.bottles:YB_Solid_Stock
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_Solid_Vial:
|
Solid_Vial:
|
||||||
category:
|
category:
|
||||||
- bottles
|
- bottles
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solid_Vial
|
module: unilabos.resources.bioyond.bottles:YB_Solid_Vial
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
BIOYOND_PolymerStation_Solution_Beaker:
|
Solution_Beaker:
|
||||||
category:
|
category:
|
||||||
- bottles
|
- bottles
|
||||||
class:
|
class:
|
||||||
module: unilabos.resources.bioyond.bottles:BIOYOND_PolymerStation_Solution_Beaker
|
module: unilabos.resources.bioyond.bottles:YB_Solution_Beaker
|
||||||
type: pylabrobot
|
type: pylabrobot
|
||||||
handles: []
|
handles: []
|
||||||
icon: ''
|
icon: ''
|
||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
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
|
||||||
|
Liquid_Bottle:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.bottles:YB_Liquid_Bottle
|
||||||
|
type: pylabrobot
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
version: 1.0.0
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
Pipette_Tip:
|
||||||
|
category:
|
||||||
|
- yb3
|
||||||
|
class:
|
||||||
|
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,3 +22,15 @@ BIOYOND_PolymerReactionStation_Deck:
|
|||||||
init_param_schema: {}
|
init_param_schema: {}
|
||||||
registry_type: resource
|
registry_type: resource
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
YB_Deck16:
|
||||||
|
category:
|
||||||
|
- deck
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.bioyond.decks:YB_Deck
|
||||||
|
type: pylabrobot
|
||||||
|
description: BIOYOND PolymerReactionStation Deck
|
||||||
|
handles: []
|
||||||
|
icon: 配液站.webp
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|||||||
@@ -2,11 +2,17 @@ from pylabrobot.resources import create_homogeneous_resources, Coordinate, Resou
|
|||||||
|
|
||||||
from unilabos.resources.itemized_carrier import Bottle, BottleCarrier
|
from unilabos.resources.itemized_carrier import Bottle, BottleCarrier
|
||||||
from unilabos.resources.bioyond.bottles import (
|
from unilabos.resources.bioyond.bottles import (
|
||||||
BIOYOND_PolymerStation_Solid_Stock,
|
YB_Solid_Stock,
|
||||||
BIOYOND_PolymerStation_Solid_Vial,
|
YB_Solid_Vial,
|
||||||
BIOYOND_PolymerStation_Liquid_Vial,
|
YB_Liquid_Vial,
|
||||||
BIOYOND_PolymerStation_Solution_Beaker,
|
YB_Solution_Beaker,
|
||||||
BIOYOND_PolymerStation_Reagent_Bottle
|
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
|
# 命名约定:试剂瓶-Bottle,烧杯-Beaker,烧瓶-Flask,小瓶-Vial
|
||||||
|
|
||||||
@@ -51,13 +57,13 @@ def BIOYOND_Electrolyte_6VialCarrier(name: str) -> BottleCarrier:
|
|||||||
size_y=carrier_size_y,
|
size_y=carrier_size_y,
|
||||||
size_z=carrier_size_z,
|
size_z=carrier_size_z,
|
||||||
sites=sites,
|
sites=sites,
|
||||||
model="BIOYOND_Electrolyte_6VialCarrier",
|
model="Electrolyte_6VialCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 3
|
carrier.num_items_x = 3
|
||||||
carrier.num_items_y = 2
|
carrier.num_items_y = 2
|
||||||
carrier.num_items_z = 1
|
carrier.num_items_z = 1
|
||||||
for i in range(6):
|
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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
@@ -89,16 +95,16 @@ def BIOYOND_Electrolyte_1BottleCarrier(name: str) -> BottleCarrier:
|
|||||||
resource_size_y=beaker_diameter,
|
resource_size_y=beaker_diameter,
|
||||||
name_prefix=name,
|
name_prefix=name,
|
||||||
),
|
),
|
||||||
model="BIOYOND_Electrolyte_1BottleCarrier",
|
model="Electrolyte_1BottleCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 1
|
carrier.num_items_x = 1
|
||||||
carrier.num_items_y = 1
|
carrier.num_items_y = 1
|
||||||
carrier.num_items_z = 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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_6StockCarrier(name: str) -> BottleCarrier:
|
def YB_6StockCarrier(name: str) -> BottleCarrier:
|
||||||
"""6瓶载架 - 2x3布局"""
|
"""6瓶载架 - 2x3布局"""
|
||||||
|
|
||||||
# 载架尺寸 (mm)
|
# 载架尺寸 (mm)
|
||||||
@@ -138,18 +144,18 @@ def BIOYOND_PolymerStation_6StockCarrier(name: str) -> BottleCarrier:
|
|||||||
size_y=carrier_size_y,
|
size_y=carrier_size_y,
|
||||||
size_z=carrier_size_z,
|
size_z=carrier_size_z,
|
||||||
sites=sites,
|
sites=sites,
|
||||||
model="BIOYOND_PolymerStation_6VialCarrier",
|
model="6StockCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 3
|
carrier.num_items_x = 3
|
||||||
carrier.num_items_y = 2
|
carrier.num_items_y = 2
|
||||||
carrier.num_items_z = 1
|
carrier.num_items_z = 1
|
||||||
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
||||||
for i in range(6):
|
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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_6VialCarrier(name: str) -> BottleCarrier:
|
def YB_6VialCarrier(name: str) -> BottleCarrier:
|
||||||
"""6瓶载架 - 2x3布局"""
|
"""6瓶载架 - 2x3布局"""
|
||||||
|
|
||||||
# 载架尺寸 (mm)
|
# 载架尺寸 (mm)
|
||||||
@@ -189,20 +195,20 @@ def BIOYOND_PolymerStation_6VialCarrier(name: str) -> BottleCarrier:
|
|||||||
size_y=carrier_size_y,
|
size_y=carrier_size_y,
|
||||||
size_z=carrier_size_z,
|
size_z=carrier_size_z,
|
||||||
sites=sites,
|
sites=sites,
|
||||||
model="BIOYOND_PolymerStation_6VialCarrier",
|
model="6VialCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 3
|
carrier.num_items_x = 3
|
||||||
carrier.num_items_y = 2
|
carrier.num_items_y = 2
|
||||||
carrier.num_items_z = 1
|
carrier.num_items_z = 1
|
||||||
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
ordering = ["A1", "A2", "A3", "B1", "B2", "B3"] # 自定义顺序
|
||||||
for i in range(3):
|
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):
|
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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_1BottleCarrier(name: str) -> BottleCarrier:
|
def YB_1BottleCarrier(name: str) -> BottleCarrier:
|
||||||
"""1瓶载架 - 单个中央位置"""
|
"""1瓶载架 - 单个中央位置"""
|
||||||
|
|
||||||
# 载架尺寸 (mm)
|
# 载架尺寸 (mm)
|
||||||
@@ -230,16 +236,16 @@ def BIOYOND_PolymerStation_1BottleCarrier(name: str) -> BottleCarrier:
|
|||||||
resource_size_y=beaker_diameter,
|
resource_size_y=beaker_diameter,
|
||||||
name_prefix=name,
|
name_prefix=name,
|
||||||
),
|
),
|
||||||
model="BIOYOND_PolymerStation_1BottleCarrier",
|
model="1BottleCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 1
|
carrier.num_items_x = 1
|
||||||
carrier.num_items_y = 1
|
carrier.num_items_y = 1
|
||||||
carrier.num_items_z = 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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_1FlaskCarrier(name: str) -> BottleCarrier:
|
def YB_1FlaskCarrier(name: str) -> BottleCarrier:
|
||||||
"""1瓶载架 - 单个中央位置"""
|
"""1瓶载架 - 单个中央位置"""
|
||||||
|
|
||||||
# 载架尺寸 (mm)
|
# 载架尺寸 (mm)
|
||||||
@@ -267,10 +273,348 @@ def BIOYOND_PolymerStation_1FlaskCarrier(name: str) -> BottleCarrier:
|
|||||||
resource_size_y=beaker_diameter,
|
resource_size_y=beaker_diameter,
|
||||||
name_prefix=name,
|
name_prefix=name,
|
||||||
),
|
),
|
||||||
model="BIOYOND_PolymerStation_1FlaskCarrier",
|
model="1FlaskCarrier",
|
||||||
)
|
)
|
||||||
carrier.num_items_x = 1
|
carrier.num_items_x = 1
|
||||||
carrier.num_items_y = 1
|
carrier.num_items_y = 1
|
||||||
carrier.num_items_z = 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
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_6x5ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""5ml分液瓶板 - 4x2布局,8个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (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 - (4 - 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=4,
|
||||||
|
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="6x5ml_DispensingVialCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 4
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||||
|
for i in range(8):
|
||||||
|
carrier[i] = YB_5ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_6x20ml_DispensingVialCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""20ml分液瓶板 - 4x2布局,8个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (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 - (4 - 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=4,
|
||||||
|
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="6x20ml_DispensingVialCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 4
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||||
|
for i in range(8):
|
||||||
|
carrier[i] = YB_20ml_Dispensing_Vial(f"{name}_vial_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_6x_SmallSolutionBottleCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""配液瓶(小)板 - 4x2布局,8个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (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 - (4 - 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=4,
|
||||||
|
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="6x_SmallSolutionBottleCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 4
|
||||||
|
carrier.num_items_y = 2
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
ordering = ["A1", "A2", "A3", "A4", "B1", "B2", "B3", "B4"]
|
||||||
|
for i in range(8):
|
||||||
|
carrier[i] = YB_Small_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="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] = YB_Large_Solution_Bottle(f"{name}_bottle_{ordering[i]}")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_6x_LargeDispenseHeadCarrier(name: str) -> BottleCarrier:
|
||||||
|
"""加样头(大)板 - 1x1布局,1个位置"""
|
||||||
|
|
||||||
|
# 载架尺寸 (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 - (1 - 1) * bottle_spacing_x - bottle_diameter) / 2
|
||||||
|
start_y = (carrier_size_y - (1 - 1) * bottle_spacing_y - bottle_diameter) / 2
|
||||||
|
|
||||||
|
sites = create_ordered_items_2d(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
num_items_x=1,
|
||||||
|
num_items_y=1,
|
||||||
|
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="6x_LargeDispenseHeadCarrier",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 1
|
||||||
|
carrier.num_items_y = 1
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
carrier[0] = YB_Large_Dispense_Head(f"{name}_head_1")
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="AdapterBlock",
|
||||||
|
)
|
||||||
|
carrier.num_items_x = 1
|
||||||
|
carrier.num_items_y = 1
|
||||||
|
carrier.num_items_z = 1
|
||||||
|
# 适配器块本身不包含瓶子,只是一个支撑结构
|
||||||
|
return carrier
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="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] = 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,
|
name: str,
|
||||||
diameter: float = 20.0,
|
diameter: float = 20.0,
|
||||||
height: float = 100.0,
|
height: float = 100.0,
|
||||||
@@ -12,15 +12,15 @@ def BIOYOND_PolymerStation_Solid_Stock(
|
|||||||
"""创建粉末瓶"""
|
"""创建粉末瓶"""
|
||||||
return Bottle(
|
return Bottle(
|
||||||
name=name,
|
name=name,
|
||||||
diameter=diameter,
|
diameter=diameter,# 未知
|
||||||
height=height,
|
height=height,
|
||||||
max_volume=max_volume,
|
max_volume=max_volume,
|
||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Solid_Stock",
|
model="Solid_Stock",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_Solid_Vial(
|
def YB_Solid_Vial(
|
||||||
name: str,
|
name: str,
|
||||||
diameter: float = 25.0,
|
diameter: float = 25.0,
|
||||||
height: float = 60.0,
|
height: float = 60.0,
|
||||||
@@ -34,11 +34,11 @@ def BIOYOND_PolymerStation_Solid_Vial(
|
|||||||
height=height,
|
height=height,
|
||||||
max_volume=max_volume,
|
max_volume=max_volume,
|
||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Solid_Vial",
|
model="Solid_Vial",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_Liquid_Vial(
|
def YB_Liquid_Vial(
|
||||||
name: str,
|
name: str,
|
||||||
diameter: float = 25.0,
|
diameter: float = 25.0,
|
||||||
height: float = 60.0,
|
height: float = 60.0,
|
||||||
@@ -52,11 +52,11 @@ def BIOYOND_PolymerStation_Liquid_Vial(
|
|||||||
height=height,
|
height=height,
|
||||||
max_volume=max_volume,
|
max_volume=max_volume,
|
||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Liquid_Vial",
|
model="Liquid_Vial",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_Solution_Beaker(
|
def YB_Solution_Beaker(
|
||||||
name: str,
|
name: str,
|
||||||
diameter: float = 60.0,
|
diameter: float = 60.0,
|
||||||
height: float = 70.0,
|
height: float = 70.0,
|
||||||
@@ -70,11 +70,11 @@ def BIOYOND_PolymerStation_Solution_Beaker(
|
|||||||
height=height,
|
height=height,
|
||||||
max_volume=max_volume,
|
max_volume=max_volume,
|
||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Solution_Beaker",
|
model="Solution_Beaker",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def BIOYOND_PolymerStation_Reagent_Bottle(
|
def YB_Reagent_Bottle(
|
||||||
name: str,
|
name: str,
|
||||||
diameter: float = 70.0,
|
diameter: float = 70.0,
|
||||||
height: float = 120.0,
|
height: float = 120.0,
|
||||||
@@ -88,5 +88,168 @@ def BIOYOND_PolymerStation_Reagent_Bottle(
|
|||||||
height=height,
|
height=height,
|
||||||
max_volume=max_volume,
|
max_volume=max_volume,
|
||||||
barcode=barcode,
|
barcode=barcode,
|
||||||
model="BIOYOND_PolymerStation_Reagent_Bottle",
|
model="Reagent_Bottle",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="100ml_Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="High_Viscosity_Liquid_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="Large_Dispense_Head",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="5ml_Dispensing_Vial",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="20ml_Dispensing_Vial",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="Small_Solution_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="Large_Solution_Bottle",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def YB_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="Pipette_Tip",
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
from os import name
|
||||||
from pylabrobot.resources import Deck, Coordinate, Rotation
|
from pylabrobot.resources import Deck, Coordinate, Rotation
|
||||||
|
|
||||||
from unilabos.resources.bioyond.warehouses import bioyond_warehouse_1x4x4, bioyond_warehouse_1x4x2, bioyond_warehouse_liquid_and_lid_handling
|
from unilabos.resources.bioyond.warehouses import bioyond_warehouse_1x4x4, bioyond_warehouse_1x4x2, bioyond_warehouse_liquid_and_lid_handling, bioyond_warehouse_1x2x2, bioyond_warehouse_1x3x3, bioyond_warehouse_10x1x1, bioyond_warehouse_3x3x1, bioyond_warehouse_3x3x1_2, bioyond_warehouse_5x1x1
|
||||||
|
|
||||||
|
|
||||||
class BIOYOND_PolymerReactionStation_Deck(Deck):
|
class BIOYOND_PolymerReactionStation_Deck(Deck):
|
||||||
@@ -66,3 +67,60 @@ class BIOYOND_PolymerPreparationStation_Deck(Deck):
|
|||||||
|
|
||||||
for warehouse_name, warehouse in self.warehouses.items():
|
for warehouse_name, warehouse in self.warehouses.items():
|
||||||
self.assign_child_resource(warehouse, location=self.warehouse_locations[warehouse_name])
|
self.assign_child_resource(warehouse, location=self.warehouse_locations[warehouse_name])
|
||||||
|
|
||||||
|
class BIOYOND_YB_Deck(Deck):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str = "YB_Deck",
|
||||||
|
size_x: float = 4150,
|
||||||
|
size_y: float = 1400.0,
|
||||||
|
size_z: float = 2670.0,
|
||||||
|
category: str = "deck",
|
||||||
|
setup: bool = False
|
||||||
|
) -> None:
|
||||||
|
super().__init__(name=name, size_x=4150.0, size_y=1400.0, size_z=2670.0)
|
||||||
|
if setup:
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def setup(self) -> None:
|
||||||
|
# 添加仓库
|
||||||
|
self.warehouses = {
|
||||||
|
"321窗口": bioyond_warehouse_1x2x2("321窗口"),
|
||||||
|
"43窗口": bioyond_warehouse_1x2x2("43窗口"),
|
||||||
|
"手动传递窗左": bioyond_warehouse_1x3x3("手动传递窗左"),
|
||||||
|
"手动传递窗右": bioyond_warehouse_1x3x3("手动传递窗右"),
|
||||||
|
"加样头堆栈左": bioyond_warehouse_10x1x1("加样头堆栈左"),
|
||||||
|
"加样头堆栈右": bioyond_warehouse_10x1x1("加样头堆栈右"),
|
||||||
|
|
||||||
|
"15ml配液堆栈左": bioyond_warehouse_3x3x1("15ml配液堆栈左"),
|
||||||
|
"母液加样右": bioyond_warehouse_3x3x1_2("母液加样右"),
|
||||||
|
"大瓶母液堆栈左": bioyond_warehouse_5x1x1("大瓶母液堆栈左"),
|
||||||
|
"大瓶母液堆栈右": bioyond_warehouse_5x1x1("大瓶母液堆栈右"),
|
||||||
|
}
|
||||||
|
# warehouse 的位置
|
||||||
|
self.warehouse_locations = {
|
||||||
|
"321窗口": Coordinate(-150.0, 158.0, 0.0),
|
||||||
|
"43窗口": Coordinate(4160.0, 158.0, 0.0),
|
||||||
|
"手动传递窗左": Coordinate(-150.0, 877.0, 0.0),
|
||||||
|
"手动传递窗右": Coordinate(4160.0, 877.0, 0.0),
|
||||||
|
"加样头堆栈左": Coordinate(385.0, 1300.0, 0.0),
|
||||||
|
"加样头堆栈右": Coordinate(2187.0, 1300.0, 0.0),
|
||||||
|
|
||||||
|
"15ml配液堆栈左": Coordinate(749.0, 355.0, 0.0),
|
||||||
|
"母液加样右": Coordinate(2152.0, 333.0, 0.0),
|
||||||
|
"大瓶母液堆栈左": Coordinate(1164.0, 676.0, 0.0),
|
||||||
|
"大瓶母液堆栈右": Coordinate(2717.0, 676.0, 0.0),
|
||||||
|
}
|
||||||
|
|
||||||
|
for warehouse_name, warehouse in self.warehouses.items():
|
||||||
|
self.assign_child_resource(warehouse, location=self.warehouse_locations[warehouse_name])
|
||||||
|
|
||||||
|
def YB_Deck(name: str) -> Deck:
|
||||||
|
by=BIOYOND_YB_Deck(name=name)
|
||||||
|
by.setup()
|
||||||
|
return by
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ def bioyond_warehouse_1x4x4(name: str) -> WareHouse:
|
|||||||
"""创建BioYond 4x1x4仓库"""
|
"""创建BioYond 4x1x4仓库"""
|
||||||
return warehouse_factory(
|
return warehouse_factory(
|
||||||
name=name,
|
name=name,
|
||||||
num_items_x=4,
|
num_items_x=1,
|
||||||
num_items_y=4,
|
num_items_y=4,
|
||||||
num_items_z=1,
|
num_items_z=4,
|
||||||
dx=10.0,
|
dx=10.0,
|
||||||
dy=10.0,
|
dy=10.0,
|
||||||
dz=10.0,
|
dz=10.0,
|
||||||
item_dx=147.0,
|
item_dx=137.0,
|
||||||
item_dy=106.0,
|
item_dy=96.0,
|
||||||
item_dz=130.0,
|
item_dz=120.0,
|
||||||
category="warehouse",
|
category="warehouse",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +34,113 @@ def bioyond_warehouse_1x4x2(name: str) -> WareHouse:
|
|||||||
category="warehouse",
|
category="warehouse",
|
||||||
removed_positions=None
|
removed_positions=None
|
||||||
)
|
)
|
||||||
|
# 定义benyond的堆栈
|
||||||
|
def bioyond_warehouse_1x2x2(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=2,
|
||||||
|
num_items_y=2,
|
||||||
|
num_items_z=1,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="YB_warehouse",
|
||||||
|
)
|
||||||
|
def bioyond_warehouse_10x1x1(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=10,
|
||||||
|
num_items_y=1,
|
||||||
|
num_items_z=1,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
def bioyond_warehouse_1x3x3(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=1,
|
||||||
|
num_items_y=3,
|
||||||
|
num_items_z=3,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
def bioyond_warehouse_2x1x3(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=2,
|
||||||
|
num_items_y=1,
|
||||||
|
num_items_z=3,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
|
||||||
|
def bioyond_warehouse_3x3x1(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=3,
|
||||||
|
num_items_z=1,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
def bioyond_warehouse_5x1x1(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=5,
|
||||||
|
num_items_y=1,
|
||||||
|
num_items_z=1,
|
||||||
|
dx=10.0,
|
||||||
|
dy=10.0,
|
||||||
|
dz=10.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
def bioyond_warehouse_3x3x1_2(name: str) -> WareHouse:
|
||||||
|
"""创建BioYond 4x1x4仓库"""
|
||||||
|
return warehouse_factory(
|
||||||
|
name=name,
|
||||||
|
num_items_x=3,
|
||||||
|
num_items_y=3,
|
||||||
|
num_items_z=1,
|
||||||
|
dx=12.0,
|
||||||
|
dy=12.0,
|
||||||
|
dz=12.0,
|
||||||
|
item_dx=137.0,
|
||||||
|
item_dy=96.0,
|
||||||
|
item_dz=120.0,
|
||||||
|
category="warehouse",
|
||||||
|
)
|
||||||
|
|
||||||
def bioyond_warehouse_liquid_and_lid_handling(name: str) -> WareHouse:
|
def bioyond_warehouse_liquid_and_lid_handling(name: str) -> WareHouse:
|
||||||
"""创建BioYond开关盖加液模块台面"""
|
"""创建BioYond开关盖加液模块台面"""
|
||||||
|
|||||||
@@ -624,6 +624,8 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[st
|
|||||||
Returns:
|
Returns:
|
||||||
pylabrobot 格式的物料列表
|
pylabrobot 格式的物料列表
|
||||||
"""
|
"""
|
||||||
|
print("1:bioyond_materials:",bioyond_materials)
|
||||||
|
# print("2:type_mapping:",type_mapping)
|
||||||
plr_materials = []
|
plr_materials = []
|
||||||
|
|
||||||
for material in bioyond_materials:
|
for material in bioyond_materials:
|
||||||
|
|||||||
Reference in New Issue
Block a user