Compare commits

...

10 Commits

Author SHA1 Message Date
Calvin Cao
385a495e21 Merge pull request #138 from lixinyu1011/workstation_dev_YB3
新建入库物料系统
2025-10-31 19:04:28 +08:00
lixinyu1011
91513a5f4c Delete button_battery_station.py 2025-10-31 19:02:06 +08:00
lixinyu1011
a62896eda2 1031_byxinyu 2025-10-31 18:57:38 +08:00
lixinyu1011
a82d1b7bdb Merge remote-tracking branch 'upstream/workstation_dev_YB3' into workstation_dev_YB3 2025-10-31 15:30:28 +08:00
lixinyu1011
6d7c39da9e 1031 2025-10-31 15:29:59 +08:00
Calvin Cao
d8e9ad4413 Merge pull request #136 from sun7151887/fix/yb3-material-names-and-model
fix: 更新物料类型配置映射
2025-10-31 15:13:48 +08:00
dijkstra402
eb93b83415 fix: 更新物料类型配置映射 2025-10-31 15:05:47 +08:00
lixinyu1011
6df93a5db7 Merge remote-tracking branch 'upstream/workstation_dev_YB3' into workstation_dev_YB3 2025-10-31 14:02:45 +08:00
lixinyu1011
2eb9986edb 123 2025-10-31 13:54:58 +08:00
calvincao
fe4e49e56d feat(workstation): 更新 Bioyond 和 Coin Cell 组装工作站配置
- 修改 Bioyond Studio 配置文件中的 API 主机地址
- 更新 bioyond_cell_workstation.py 中的默认模板路径
- 新增物料模板文件 material_template.xlsx
- 扩展 func_pack_send_msg_cmd 函数以支持 assembly_pressure 参数
- 更新 coin_cell_workstation.yaml 文件以包含 assembly_pressure 的默认值和类型定义
2025-10-31 13:53:58 +08:00
10 changed files with 429 additions and 46 deletions

View File

@@ -0,0 +1,99 @@
{
"typeId": "3a190c8b-3284-af78-d29f-9a69463ad047",
"code": "",
"barCode": "",
"name": "test",
"unit": "",
"parameters": "{}",
"quantity": "",
"details": [
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)11",
"quantity": "1",
"x": 1,
"y": 1,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)21",
"quantity": "1",
"x": 2,
"y": 1,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)12",
"quantity": "1",
"x": 1,
"y": 2,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)22",
"quantity": "1",
"x": 2,
"y": 2,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)13",
"quantity": "1",
"x": 1,
"y": 3,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)23",
"quantity": "1",
"x": 2,
"y": 3,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)14",
"quantity": "1",
"x": 1,
"y": 4,
"z": 1,
"unit": "",
"parameters": "{}"
},
{
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb",
"code": "",
"name": "配液瓶(小)24",
"quantity": "1",
"x": 2,
"y": 4,
"z": 1,
"unit": "",
"parameters": "{}"
}
]
}

114
test/resources/test.json Normal file
View File

@@ -0,0 +1,114 @@
[
{
"id": "3a1d4b7e-4bdc-16bf-7169-f60350d03c7e",
"typeName": "配液瓶(小)板",
"code": "0001-00088",
"barCode": "",
"name": "test1",
"quantity": 1.0,
"lockQuantity": 0.0,
"unit": "块",
"status": 1,
"isUse": false,
"locations": [
{
"id": "3a19deae-2c7a-2426-6d71-e9de3cb158b1",
"whid": "3a19deae-2c79-05a3-9c76-8e6760424841",
"whName": "手动堆栈",
"code": "4",
"x": 2,
"y": 1,
"z": 1,
"quantity": 0
}
],
"detail": [
{
"id": "3a1d4b7e-4bdc-12e8-4d26-dddc77b03f63",
"detailMaterialId": "3a1d4b7e-4bdc-4e9e-8a3c-e9ba4a26457e",
"code": null,
"name": "test1",
"quantity": "1",
"lockQuantity": "0",
"unit": "块",
"x": 1,
"y": 2,
"z": 1,
"associateId": null,
"typeName": "配液瓶(小)",
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"
},
{
"id": "3a1d4b7e-4bdc-35b6-22d4-e6f3235e1c27",
"detailMaterialId": "3a1d4b7e-4bdc-ce0f-1fbb-b88de76fce98",
"code": null,
"name": "test1",
"quantity": "1",
"lockQuantity": "0",
"unit": "块",
"x": 1,
"y": 1,
"z": 1,
"associateId": null,
"typeName": "配液瓶(小)",
"typeId": "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"
}
]
},
{
"id": "3a1d4b7e-ee61-ae87-9cd0-31c7e6621b18",
"typeName": "5ml分液瓶板",
"code": "0010-00089",
"barCode": "",
"name": "test2",
"quantity": 1.0,
"lockQuantity": 0.0,
"unit": "块",
"status": 1,
"isUse": false,
"locations": [
{
"id": "3a19deae-2c7a-79b0-5e44-efaafd1e4cf3",
"whid": "3a19deae-2c79-05a3-9c76-8e6760424841",
"whName": "手动堆栈",
"code": "5",
"x": 2,
"y": 2,
"z": 1,
"quantity": 0
}
],
"detail": [
{
"id": "3a1d4b7e-ee61-8fb3-9a39-2c2841c3c8d0",
"detailMaterialId": "3a1d4b7e-ee61-305c-fe30-2620017ca1bd",
"code": null,
"name": "test2",
"quantity": "1",
"lockQuantity": "0",
"unit": "块",
"x": 1,
"y": 1,
"z": 1,
"associateId": null,
"typeName": "5ml分液瓶",
"typeId": "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"
},
{
"id": "3a1d4b7e-ee61-ef5f-a7d1-f9399a4d3145",
"detailMaterialId": "3a1d4b7e-ee61-2f1d-6969-202ad3cbe226",
"code": null,
"name": "test2",
"quantity": "1",
"lockQuantity": "0",
"unit": "块",
"x": 1,
"y": 2,
"z": 1,
"associateId": null,
"typeName": "5ml分液瓶",
"typeId": "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"
}
]
}
]

View File

@@ -253,7 +253,7 @@ class BioyondCellWorkstation(BioyondWorkstation):
def auto_feeding4to3(
self,
# ★ 修改点:默认模板路径
xlsx_path: Optional[str] = "unilabos\\devices\\workstation\\bioyond_studio\\bioyond_cell\\样品导入模板.xlsx",
xlsx_path: Optional[str] = "unilabos\\devices\\workstation\\bioyond_studio\\bioyond_cell\\material_template.xlsx",
# ---------------- WH4 - 加样头面 (Z=1, 12个点位) ----------------
WH4_x1_y1_z1_1_materialName: str = "", WH4_x1_y1_z1_1_quantity: float = 0.0,
WH4_x2_y1_z1_2_materialName: str = "", WH4_x2_y1_z1_2_quantity: float = 0.0,
@@ -630,7 +630,12 @@ class BioyondCellWorkstation(BioyondWorkstation):
response = self._post_lims("/api/lims/order/orders", orders)
print(response)
# 等待任务报送成功
order_code = response.get("data", {}).get("orderCode")
data_list = response.get("data", [])
if data_list:
order_code = data_list[0].get("orderCode")
else:
order_code = None
if not order_code:
logger.error("上料任务未返回有效 orderCode")
return response
@@ -963,13 +968,179 @@ class BioyondCellWorkstation(BioyondWorkstation):
logger.error(f"✗ 执行失败: {e}")
return {"success": False, "error": str(e)}
def create_material(
self,
material_name: str,
type_id: str,
warehouse_name: str,
location_name_or_id: Optional[str] = None
) -> Dict[str, Any]:
"""创建单个物料并可选入库。
Args:
material_name: 物料名称(会优先匹配配置模板)。
type_id: 物料类型 ID若为空则尝试从配置推断
warehouse_name: 需要入库的仓库名称;若为空则仅创建不入库。
location_name_or_id: 具体库位名称(如 A01或库位 UUID由用户指定。
Returns:
包含创建结果、物料ID以及入库结果的字典。
"""
material_name = (material_name or "").strip()
resolved_type_id = (type_id or "").strip()
# 优先从 SOLID_LIQUID_MAPPINGS 中获取模板数据
template = SOLID_LIQUID_MAPPINGS.get(material_name)
if not template:
raise ValueError(f"在配置中未找到物料 {material_name} 的模板,请检查 SOLID_LIQUID_MAPPINGS。")
material_data: Dict[str, Any]
material_data = deepcopy(template)
# 最终确保 typeId 为调用方传入的值
if resolved_type_id:
material_data["typeId"] = resolved_type_id
material_data["name"] = material_name
# 生成唯一编码
def _generate_code(prefix: str) -> str:
normalized = re.sub(r"\W+", "_", prefix)
normalized = normalized.strip("_") or "material"
return f"{normalized}_{datetime.now().strftime('%Y%m%d%H%M%S')}"
if not material_data.get("code"):
material_data["code"] = _generate_code(material_name)
if not material_data.get("barCode"):
material_data["barCode"] = ""
# 处理数量字段类型
def _to_number(value: Any, default: float = 0.0) -> float:
try:
if value is None:
return default
if isinstance(value, (int, float)):
return float(value)
if isinstance(value, str) and value.strip() == "":
return default
return float(value)
except (TypeError, ValueError):
return default
material_data["quantity"] = _to_number(material_data.get("quantity"), 1.0)
material_data["warningQuantity"] = _to_number(material_data.get("warningQuantity"), 0.0)
unit = material_data.get("unit") or ""
material_data["unit"] = unit
if not material_data.get("parameters"):
material_data["parameters"] = json.dumps({"unit": unit}, ensure_ascii=False)
# 补充子物料信息
details = material_data.get("details") or []
if not isinstance(details, list):
logger.warning("details 字段不是列表,已忽略。")
details = []
else:
for idx, detail in enumerate(details, start=1):
if not isinstance(detail, dict):
continue
if not detail.get("code"):
detail["code"] = f"{material_data['code']}_{idx:02d}"
if not detail.get("name"):
detail["name"] = f"{material_name}_detail_{idx:02d}"
if not detail.get("unit"):
detail["unit"] = unit
if not detail.get("parameters"):
detail["parameters"] = json.dumps({"unit": detail.get("unit", unit)}, ensure_ascii=False)
if "quantity" in detail:
detail["quantity"] = _to_number(detail.get("quantity"), 1.0)
material_data["details"] = details
create_result = self._post_lims("/api/lims/storage/material", material_data)
# 解析创建结果中的物料 ID
material_id: Optional[str] = None
if isinstance(create_result, dict):
data_field = create_result.get("data")
if isinstance(data_field, str):
material_id = data_field
elif isinstance(data_field, dict):
material_id = data_field.get("id") or data_field.get("materialId")
inbound_result: Optional[Dict[str, Any]] = None
location_id: Optional[str] = None
# 按用户指定位置入库
if warehouse_name and material_id and location_name_or_id:
try:
location_ids, position_names = self._load_warehouse_locations(warehouse_name)
position_to_id = {name: loc_id for name, loc_id in zip(position_names, location_ids)}
target_location_id = position_to_id.get(location_name_or_id, location_name_or_id)
if target_location_id:
location_id = target_location_id
inbound_result = self.storage_inbound(material_id, target_location_id)
else:
inbound_result = {"error": f"未找到匹配的库位: {location_name_or_id}"}
except Exception as exc:
logger.error(f"获取仓库 {warehouse_name} 位置失败: {exc}")
inbound_result = {"error": str(exc)}
return {
"success": bool(isinstance(create_result, dict) and create_result.get("code") == 1 and material_id),
"material_name": material_name,
"material_id": material_id,
"warehouse": warehouse_name,
"location_id": location_id,
"location_name_or_id": location_name_or_id,
"create_result": create_result,
"inbound_result": inbound_result,
}
def create_sample(
self,
name: str,
board_type: str,
bottle_type: str,
location_code: str
) -> Dict[str, Any]:
"""创建配液板物料并自动入库。
Args:
material_name: 物料名称,支持 "5ml分液瓶板"/"5ml分液瓶""配液瓶(小)板"/"配液瓶(小)"
quantity: 主物料与明细的数量,默认 1。
location_code: 库位编号,例如 "A01",将自动映射为 "手动堆栈" 下的 UUID。
"""
carrier_type_id = MATERIAL_TYPE_MAPPINGS[board_type][1]
bottle_type_id = MATERIAL_TYPE_MAPPINGS[bottle_type][1]
location_id = WAREHOUSE_MAPPING["手动堆栈"]["site_uuids"][location_code]
# 新建小瓶
details = []
for y in range(1, 5):
for x in range(1, 3):
details.append({
"typeId": bottle_type_id,
"code": "",
"name": str(bottle_type) + str(x) + str(y),
"quantity": "1",
"x": x,
"y": y,
"z": 1,
"unit": "",
"parameters": json.dumps({"unit": ""}, ensure_ascii=False),
})
data = {
"typeId": carrier_type_id,
"code": "",
"barCode": "",
"name": name,
"unit": "",
"parameters": json.dumps({"unit": ""}, ensure_ascii=False),
"quantity": "1",
"details": details,
}
# print("xxx:",data)
create_result = self._post_lims("/api/lims/storage/material", data)
sample_uuid = create_result.get("data")
final_result = self._post_lims("/api/lims/storage/inbound", {
"materialId": sample_uuid,
"locationId": location_id,
})
return final_result
# --------------------------------
if __name__ == "__main__":
lab_registry.setup()
ws = BioyondCellWorkstation()
ws.create_sample(name="test", board_type="配液瓶(小)板", bottle_type="配液瓶(小)", location_code="B01")
# logger.info(ws.scheduler_stop())
# logger.info(ws.scheduler_start())
@@ -981,7 +1152,7 @@ if __name__ == "__main__":
# 继续后续流程
# logger.info(ws.auto_feeding4to3()) #搬运物料到3号箱
# # 使用正斜杠或 Path 对象来指定文件路径
# # # 使用正斜杠或 Path 对象来指定文件路径
# excel_path = Path("unilabos\\devices\\workstation\\bioyond_studio\\bioyond_cell\\2025092701.xlsx")
# logger.info(ws.create_orders(excel_path))
# logger.info(ws.transfer_3_to_2_to_1())

View File

@@ -8,7 +8,7 @@ import os
# BioyondCellWorkstation 默认配置(包含所有必需参数)
API_CONFIG = {
# API 连接配置
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.21.32.103:44388"),
"api_host": os.getenv("BIOYOND_API_HOST", "http://172.16.10.169:44388"),
"api_key": os.getenv("BIOYOND_API_KEY", "8A819E5C"),
"timeout": int(os.getenv("BIOYOND_TIMEOUT", "30")),
@@ -16,7 +16,7 @@ API_CONFIG = {
"report_token": os.getenv("BIOYOND_REPORT_TOKEN", "CHANGE_ME_TOKEN"),
# HTTP 服务配置
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "172.21.32.210"), # HTTP服务监听地址监听计算机飞连ip地址
"HTTP_host": os.getenv("BIOYOND_HTTP_HOST", "172.21.33.174"), # HTTP服务监听地址监听计算机飞连ip地址
"HTTP_port": int(os.getenv("BIOYOND_HTTP_PORT", "8080")),
"debug_mode": False,# 调试模式
}
@@ -154,19 +154,19 @@ MATERIAL_TYPE_MAPPINGS = {
"100ml液体": ("YB_1Bottle100mlCarrier", "d37166b3-ecaa-481e-bd84-3032b795ba07"),
"": ("YB_1BottleCarrier", "3a190ca1-2add-2b23-f8e1-bbd348b7f790"),
"高粘液": ("YB_1GaoNianYeBottleCarrier", "abe8df30-563d-43d2-85e0-cabec59ddc16"),
"加样头(大)": ("YB_jia_yang_tou_da_1X1_carrier", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
"加样头(大)": ("YB_jia_yang_tou_da", "3a190ca0-b2f6-9aeb-8067-547e72c11469"),
"加样头(大)板": ("YB_jia_yang_tou_da_1X1_carrier", "a8e714ae-2a4e-4eb9-9614-e4c140ec3f16"),
"5ml分液瓶板": ("YB_6x5ml_DispensingVialCarrier", "3a192fa4-007d-ec7b-456e-2a8be7a13f23"),
"5ml分液瓶": ("YB_6x5ml_DispensingVialCarrier", "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"),
"5ml分液瓶": ("YB_fen_ye_5ml_Bottle", "3a192c2a-ebb7-58a1-480d-8b3863bf74f4"),
"20ml分液瓶板": ("YB_6x20ml_DispensingVialCarrier", "3a192fa4-47db-3449-162a-eaf8aba57e27"),
"20ml分液瓶": ("YB_6x20ml_DispensingVialCarrier", "3a192c2b-19e8-f0a3-035e-041ca8ca1035"),
"20ml分液瓶": ("YB_fen_ye_20ml_Bottler", "3a192c2b-19e8-f0a3-035e-041ca8ca1035"),
"配液瓶(小)板": ("YB_6x_SmallSolutionBottleCarrier", "3a190c8b-3284-af78-d29f-9a69463ad047"),
"配液瓶(小)": ("YB_6x_SmallSolutionBottleCarrier", "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"),
"配液瓶(小)": ("YB_pei_ye_xiao_Bottler", "3a190c8c-fe8f-bf48-0dc3-97afc7f508eb"),
"配液瓶(大)板": ("YB_4x_LargeSolutionBottleCarrier", "53e50377-32dc-4781-b3c0-5ce45bc7dc27"),
"配液瓶(大)": ("YB_4x_LargeSolutionBottleCarrier", "19c52ad1-51c5-494f-8854-576f4ca9c6ca"),
"配液瓶(大)": ("YB_pei_ye_da_Bottle", "19c52ad1-51c5-494f-8854-576f4ca9c6ca"),
"适配器块": ("YB_AdapterBlock", "efc3bb32-d504-4890-91c0-b64ed3ac80cf"),
"枪头盒": ("YB_TipBox", "3a192c2e-20f3-a44a-0334-c8301839d0b3"),
"枪头": ("YB_TipBox", "b6196971-1050-46da-9927-333e8dea062d"),
"枪头": ("YB_Pipette_Tip", "b6196971-1050-46da-9927-333e8dea062d"),
}
SOLID_LIQUID_MAPPINGS = {

Binary file not shown.

View File

@@ -766,7 +766,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
# self.success = True
# return self.success
def func_pack_send_msg_cmd(self, elec_use_num, elec_vol, assembly_type) -> bool:
def func_pack_send_msg_cmd(self, elec_use_num, elec_vol, assembly_type, assembly_pressure) -> bool:
"""UNILAB写参数"""
while (self.request_rec_msg_status) == False:
print("wait for request_rec_msg_status to True")
@@ -782,6 +782,9 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
#发送电解液组装类型
self._unilab_send_msg_assembly_type(assembly_type)
time.sleep(1)
#发送电池压制力
self._unilab_send_msg_assembly_pressure(assembly_pressure)
time.sleep(1)
self._unilab_send_msg_succ_cmd(True)
time.sleep(1)
while (self.request_rec_msg_status) == True:
@@ -895,16 +898,16 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
self.client.use_node('REG_MSG_NE_PLATE_MATRIX').write(fujipian_juzhendianwei)
self.client.use_node('REG_MSG_SEPARATOR_PLATE_NUM').write(gemopanshu)
self.client.use_node('REG_MSG_SEPARATOR_PLATE_MATRIX').write(gemo_juzhendianwei)
self.client.use_node('COIL_ALUMINUM_FOIL').write(lvbodian)
self.client.use_node('REG_MSG_PRESS_MODE').write(battery_pressure_mode)
self.client.use_node('COIL_ALUMINUM_FOIL').write(not lvbodian)
self.client.use_node('REG_MSG_PRESS_MODE').write(not battery_pressure_mode)
# self.client.use_node('REG_MSG_ASSEMBLY_PRESSURE').write(battery_pressure)
self.client.use_node('REG_MSG_BATTERY_CLEAN_IGNORE').write(battery_clean_ignore)
self.success = True
return self.success
def func_allpack_cmd(self, elec_num, elec_use_num, elec_vol:int=50, assembly_type:int=7, file_path: str="D:\\coin_cell_data") -> bool:
elec_num, elec_use_num, elec_vol, assembly_type = int(elec_num), int(elec_use_num), int(elec_vol), int(assembly_type)
def func_allpack_cmd(self, elec_num, elec_use_num, elec_vol:int=50, assembly_type:int=7, assembly_pressure:int=4200, file_path: str="D:\\coin_cell_data") -> bool:
elec_num, elec_use_num, elec_vol, assembly_type, assembly_pressure = int(elec_num), int(elec_use_num), int(elec_vol), int(assembly_type), int(assembly_pressure)
summary_csv_file = os.path.join(file_path, "duandian.csv")
# 如果断点文件存在,先读取之前的进度
if os.path.exists(summary_csv_file):
@@ -954,7 +957,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
print(f"开始第{last_i+i+1}瓶电解液的组装")
#第一个循环从上次断点继续后续循环从0开始
j_start = last_j if i == last_i else 0
self.func_pack_send_msg_cmd(elec_use_num-j_start, elec_vol, assembly_type)
self.func_pack_send_msg_cmd(elec_use_num-j_start, elec_vol, assembly_type, assembly_pressure)
for j in range(j_start, elec_use_num):
print(f"开始第{last_i+i+1}瓶电解液的第{j+j_start+1}个电池组装")

View File

@@ -74,6 +74,7 @@ coincellassemblyworkstation_device:
feedback: {}
goal: {}
goal_default:
assembly_pressure: 4200
assembly_type: 7
elec_num: null
elec_use_num: null
@@ -88,6 +89,9 @@ coincellassemblyworkstation_device:
feedback: {}
goal:
properties:
assembly_pressure:
default: 4200
type: integer
assembly_type:
default: 7
type: integer
@@ -291,6 +295,7 @@ coincellassemblyworkstation_device:
feedback: {}
goal: {}
goal_default:
assembly_pressure: null
assembly_type: null
elec_use_num: null
elec_vol: null
@@ -303,6 +308,8 @@ coincellassemblyworkstation_device:
feedback: {}
goal:
properties:
assembly_pressure:
type: string
assembly_type:
type: string
elec_use_num:
@@ -313,6 +320,7 @@ coincellassemblyworkstation_device:
- elec_use_num
- elec_vol
- assembly_type
- assembly_pressure
type: object
result: {}
required:

View File

@@ -1361,8 +1361,7 @@ laiyu_liquid:
mix_liquid_height: 0.0
mix_rate: 0
mix_stage: ''
mix_times:
- 0
mix_times: 0
mix_vol: 0
none_keys:
- ''
@@ -1492,11 +1491,9 @@ laiyu_liquid:
mix_stage:
type: string
mix_times:
items:
maximum: 2147483647
minimum: -2147483648
type: integer
type: array
maximum: 2147483647
minimum: -2147483648
type: integer
mix_vol:
maximum: 2147483647
minimum: -2147483648

View File

@@ -3994,8 +3994,7 @@ liquid_handler:
mix_liquid_height: 0.0
mix_rate: 0
mix_stage: ''
mix_times:
- 0
mix_times: 0
mix_vol: 0
none_keys:
- ''
@@ -4151,11 +4150,9 @@ liquid_handler:
mix_stage:
type: string
mix_times:
items:
maximum: 2147483647
minimum: -2147483648
type: integer
type: array
maximum: 2147483647
minimum: -2147483648
type: integer
mix_vol:
maximum: 2147483647
minimum: -2147483648
@@ -5015,8 +5012,7 @@ liquid_handler.biomek:
mix_liquid_height: 0.0
mix_rate: 0
mix_stage: ''
mix_times:
- 0
mix_times: 0
mix_vol: 0
none_keys:
- ''
@@ -5159,11 +5155,9 @@ liquid_handler.biomek:
mix_stage:
type: string
mix_times:
items:
maximum: 2147483647
minimum: -2147483648
type: integer
type: array
maximum: 2147483647
minimum: -2147483648
type: integer
mix_vol:
maximum: 2147483647
minimum: -2147483648
@@ -7807,8 +7801,7 @@ liquid_handler.prcxi:
mix_liquid_height: 0.0
mix_rate: 0
mix_stage: ''
mix_times:
- 0
mix_times: 0
mix_vol: 0
none_keys:
- ''
@@ -7937,11 +7930,9 @@ liquid_handler.prcxi:
mix_stage:
type: string
mix_times:
items:
maximum: 2147483647
minimum: -2147483648
type: integer
type: array
maximum: 2147483647
minimum: -2147483648
type: integer
mix_vol:
maximum: 2147483647
minimum: -2147483648