mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
Add batch creation methods for vial and solution tasks
添加批量创建90%10%小瓶投料任务和二胺溶液配置任务的功能,更新相关参数和默认值
This commit is contained in:
@@ -409,6 +409,265 @@ class BioyondDispensingStation(BioyondWorkstation):
|
|||||||
self.hardware_interface._logger.error(error_msg)
|
self.hardware_interface._logger.error(error_msg)
|
||||||
raise BioyondException(error_msg)
|
raise BioyondException(error_msg)
|
||||||
|
|
||||||
|
# 批量创建二胺溶液配置任务
|
||||||
|
def batch_create_diamine_solution_tasks(self,
|
||||||
|
solutions,
|
||||||
|
liquid_material_name: str = "NMP",
|
||||||
|
speed: str = None,
|
||||||
|
temperature: str = None,
|
||||||
|
delay_time: str = None) -> str:
|
||||||
|
"""
|
||||||
|
批量创建二胺溶液配置任务
|
||||||
|
|
||||||
|
参数说明:
|
||||||
|
- solutions: 溶液列表(数组)或JSON字符串,格式如下:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "MDA",
|
||||||
|
"order": 0,
|
||||||
|
"solid_mass": 5.0,
|
||||||
|
"solvent_volume": 20,
|
||||||
|
...
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
- liquid_material_name: 液体物料名称,默认为"NMP"
|
||||||
|
- speed: 搅拌速度,如果为None则使用默认值400
|
||||||
|
- temperature: 温度,如果为None则使用默认值20
|
||||||
|
- delay_time: 延迟时间,如果为None则使用默认值600
|
||||||
|
|
||||||
|
返回: JSON字符串格式的任务创建结果
|
||||||
|
|
||||||
|
异常:
|
||||||
|
- BioyondException: 各种错误情况下的统一异常
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 参数类型转换:如果是字符串则解析为列表
|
||||||
|
if isinstance(solutions, str):
|
||||||
|
try:
|
||||||
|
solutions = json.loads(solutions)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise BioyondException(f"solutions JSON解析失败: {str(e)}")
|
||||||
|
|
||||||
|
# 参数验证
|
||||||
|
if not isinstance(solutions, list):
|
||||||
|
raise BioyondException("solutions 必须是列表类型或有效的JSON数组字符串")
|
||||||
|
|
||||||
|
if not solutions:
|
||||||
|
raise BioyondException("solutions 列表不能为空")
|
||||||
|
|
||||||
|
# 批量创建任务
|
||||||
|
results = []
|
||||||
|
success_count = 0
|
||||||
|
failed_count = 0
|
||||||
|
|
||||||
|
for idx, solution in enumerate(solutions):
|
||||||
|
try:
|
||||||
|
# 提取参数
|
||||||
|
name = solution.get("name")
|
||||||
|
solid_mass = solution.get("solid_mass")
|
||||||
|
solvent_volume = solution.get("solvent_volume")
|
||||||
|
order = solution.get("order")
|
||||||
|
|
||||||
|
if not all([name, solid_mass is not None, solvent_volume is not None]):
|
||||||
|
self.hardware_interface._logger.warning(
|
||||||
|
f"跳过第 {idx + 1} 个溶液:缺少必要参数"
|
||||||
|
)
|
||||||
|
results.append({
|
||||||
|
"index": idx + 1,
|
||||||
|
"name": name,
|
||||||
|
"success": False,
|
||||||
|
"error": "缺少必要参数"
|
||||||
|
})
|
||||||
|
failed_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 生成库位名称(直接使用物料名称)
|
||||||
|
# 如果需要其他命名规则,可以在这里调整
|
||||||
|
hold_m_name = name
|
||||||
|
|
||||||
|
# 调用单个任务创建方法
|
||||||
|
result = self.create_diamine_solution_task(
|
||||||
|
order_name=f"二胺溶液配置-{name}",
|
||||||
|
material_name=name,
|
||||||
|
target_weigh=str(solid_mass),
|
||||||
|
volume=str(solvent_volume),
|
||||||
|
liquid_material_name=liquid_material_name,
|
||||||
|
speed=speed,
|
||||||
|
temperature=temperature,
|
||||||
|
delay_time=delay_time,
|
||||||
|
hold_m_name=hold_m_name
|
||||||
|
)
|
||||||
|
|
||||||
|
results.append({
|
||||||
|
"index": idx + 1,
|
||||||
|
"name": name,
|
||||||
|
"success": True,
|
||||||
|
"hold_m_name": hold_m_name
|
||||||
|
})
|
||||||
|
success_count += 1
|
||||||
|
self.hardware_interface._logger.info(
|
||||||
|
f"成功创建二胺溶液配置任务: {name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
except BioyondException as e:
|
||||||
|
results.append({
|
||||||
|
"index": idx + 1,
|
||||||
|
"name": solution.get("name", "unknown"),
|
||||||
|
"success": False,
|
||||||
|
"error": str(e)
|
||||||
|
})
|
||||||
|
failed_count += 1
|
||||||
|
self.hardware_interface._logger.error(
|
||||||
|
f"创建第 {idx + 1} 个任务失败: {str(e)}"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
results.append({
|
||||||
|
"index": idx + 1,
|
||||||
|
"name": solution.get("name", "unknown"),
|
||||||
|
"success": False,
|
||||||
|
"error": f"未知错误: {str(e)}"
|
||||||
|
})
|
||||||
|
failed_count += 1
|
||||||
|
self.hardware_interface._logger.error(
|
||||||
|
f"创建第 {idx + 1} 个任务时发生未知错误: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 返回汇总结果
|
||||||
|
summary = {
|
||||||
|
"total": len(solutions),
|
||||||
|
"success": success_count,
|
||||||
|
"failed": failed_count,
|
||||||
|
"details": results
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hardware_interface._logger.info(
|
||||||
|
f"批量创建二胺溶液配置任务完成: 总数={len(solutions)}, "
|
||||||
|
f"成功={success_count}, 失败={failed_count}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 返回JSON字符串格式
|
||||||
|
return json.dumps(summary, ensure_ascii=False)
|
||||||
|
|
||||||
|
except BioyondException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = f"批量创建二胺溶液配置任务时发生未预期的错误: {str(e)}"
|
||||||
|
self.hardware_interface._logger.error(error_msg)
|
||||||
|
raise BioyondException(error_msg)
|
||||||
|
|
||||||
|
# 批量创建90%10%小瓶投料任务
|
||||||
|
def batch_create_90_10_vial_feeding_tasks(self,
|
||||||
|
titration,
|
||||||
|
hold_m_name: str = None,
|
||||||
|
speed: str = None,
|
||||||
|
temperature: str = None,
|
||||||
|
delay_time: str = None,
|
||||||
|
liquid_material_name: str = "NMP") -> str:
|
||||||
|
"""
|
||||||
|
批量创建90%10%小瓶投料任务(仅创建1个任务,但包含所有90%和10%物料)
|
||||||
|
|
||||||
|
参数说明:
|
||||||
|
- titration: 滴定信息的字典或JSON字符串,格式如下:
|
||||||
|
{
|
||||||
|
"name": "BTDA",
|
||||||
|
"main_portion": 1.9152351915461294, # 主称固体质量(g) -> 90%物料
|
||||||
|
"titration_portion": 0.05923407808905555, # 滴定固体质量(g) -> 10%物料固体
|
||||||
|
"titration_solvent": 3.050555021586361 # 滴定溶液体积(mL) -> 10%物料液体
|
||||||
|
}
|
||||||
|
- hold_m_name: 库位名称,如"C01"。必填参数
|
||||||
|
- speed: 搅拌速度,如果为None则使用默认值400
|
||||||
|
- temperature: 温度,如果为None则使用默认值40
|
||||||
|
- delay_time: 延迟时间,如果为None则使用默认值600
|
||||||
|
- liquid_material_name: 10%物料的液体物料名称,默认为"NMP"
|
||||||
|
|
||||||
|
返回: JSON字符串格式的任务创建结果
|
||||||
|
|
||||||
|
异常:
|
||||||
|
- BioyondException: 各种错误情况下的统一异常
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 参数类型转换:如果是字符串则解析为字典
|
||||||
|
if isinstance(titration, str):
|
||||||
|
try:
|
||||||
|
titration = json.loads(titration)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise BioyondException(f"titration参数JSON解析失败: {str(e)}")
|
||||||
|
|
||||||
|
# 参数验证
|
||||||
|
if not isinstance(titration, dict):
|
||||||
|
raise BioyondException("titration 必须是字典类型或有效的JSON字符串")
|
||||||
|
|
||||||
|
if not hold_m_name:
|
||||||
|
raise BioyondException("hold_m_name 是必填参数")
|
||||||
|
|
||||||
|
if not titration:
|
||||||
|
raise BioyondException("titration 参数不能为空")
|
||||||
|
|
||||||
|
# 提取滴定数据
|
||||||
|
name = titration.get("name")
|
||||||
|
main_portion = titration.get("main_portion") # 主称固体质量
|
||||||
|
titration_portion = titration.get("titration_portion") # 滴定固体质量
|
||||||
|
titration_solvent = titration.get("titration_solvent") # 滴定溶液体积
|
||||||
|
|
||||||
|
if not all([name, main_portion is not None, titration_portion is not None, titration_solvent is not None]):
|
||||||
|
raise BioyondException("titration 数据缺少必要参数")
|
||||||
|
|
||||||
|
# 将main_portion平均分成3份作为90%物料(3个小瓶)
|
||||||
|
portion_90 = main_portion / 3
|
||||||
|
|
||||||
|
# 调用单个任务创建方法
|
||||||
|
result = self.create_90_10_vial_feeding_task(
|
||||||
|
order_name=f"90%10%小瓶投料-{name}",
|
||||||
|
speed=speed,
|
||||||
|
temperature=temperature,
|
||||||
|
delay_time=delay_time,
|
||||||
|
# 90%物料 - 主称固体平均分成3份
|
||||||
|
percent_90_1_assign_material_name=name,
|
||||||
|
percent_90_1_target_weigh=str(round(portion_90, 6)),
|
||||||
|
percent_90_2_assign_material_name=name,
|
||||||
|
percent_90_2_target_weigh=str(round(portion_90, 6)),
|
||||||
|
percent_90_3_assign_material_name=name,
|
||||||
|
percent_90_3_target_weigh=str(round(portion_90, 6)),
|
||||||
|
# 10%物料 - 滴定固体 + 滴定溶剂(只使用第1个10%小瓶)
|
||||||
|
percent_10_1_assign_material_name=name,
|
||||||
|
percent_10_1_target_weigh=str(round(titration_portion, 6)),
|
||||||
|
percent_10_1_volume=str(round(titration_solvent, 6)),
|
||||||
|
percent_10_1_liquid_material_name=liquid_material_name,
|
||||||
|
hold_m_name=hold_m_name
|
||||||
|
)
|
||||||
|
|
||||||
|
summary = {
|
||||||
|
"success": True,
|
||||||
|
"hold_m_name": hold_m_name,
|
||||||
|
"material_name": name,
|
||||||
|
"90_vials": {
|
||||||
|
"count": 3,
|
||||||
|
"weight_per_vial": round(portion_90, 6),
|
||||||
|
"total_weight": round(main_portion, 6)
|
||||||
|
},
|
||||||
|
"10_vials": {
|
||||||
|
"count": 1,
|
||||||
|
"solid_weight": round(titration_portion, 6),
|
||||||
|
"liquid_volume": round(titration_solvent, 6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hardware_interface._logger.info(
|
||||||
|
f"成功创建90%10%小瓶投料任务: {hold_m_name}, "
|
||||||
|
f"90%物料={portion_90:.6f}g×3, 10%物料={titration_portion:.6f}g+{titration_solvent:.6f}mL"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 返回JSON字符串格式
|
||||||
|
return json.dumps(summary, ensure_ascii=False)
|
||||||
|
|
||||||
|
except BioyondException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = f"批量创建90%10%小瓶投料任务时发生未预期的错误: {str(e)}"
|
||||||
|
self.hardware_interface._logger.error(error_msg)
|
||||||
|
raise BioyondException(error_msg)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bioyond = BioyondDispensingStation(config={
|
bioyond = BioyondDispensingStation(config={
|
||||||
@@ -416,6 +675,8 @@ if __name__ == "__main__":
|
|||||||
"api_host": "http://192.168.1.200:44388"
|
"api_host": "http://192.168.1.200:44388"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# ============ 原有示例代码 ============
|
||||||
|
|
||||||
# 示例1:使用material_id_query查询工作流对应的holdMID
|
# 示例1:使用material_id_query查询工作流对应的holdMID
|
||||||
workflow_id_1 = "3a15d4a1-3bbe-76f9-a458-292896a338f5" # 二胺溶液配置工作流ID
|
workflow_id_1 = "3a15d4a1-3bbe-76f9-a458-292896a338f5" # 二胺溶液配置工作流ID
|
||||||
workflow_id_2 = "3a19310d-16b9-9d81-b109-0748e953694b" # 90%10%小瓶投料工作流ID
|
workflow_id_2 = "3a19310d-16b9-9d81-b109-0748e953694b" # 90%10%小瓶投料工作流ID
|
||||||
|
|||||||
@@ -5,6 +5,157 @@ bioyond_dispensing_station:
|
|||||||
- bioyond_dispensing_station
|
- bioyond_dispensing_station
|
||||||
class:
|
class:
|
||||||
action_value_mappings:
|
action_value_mappings:
|
||||||
|
batch_create_90_10_vial_feeding_tasks:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
delay_time: delay_time
|
||||||
|
hold_m_name: hold_m_name
|
||||||
|
liquid_material_name: liquid_material_name
|
||||||
|
speed: speed
|
||||||
|
temperature: temperature
|
||||||
|
titration: titration
|
||||||
|
goal_default:
|
||||||
|
delay_time: '600'
|
||||||
|
hold_m_name: ''
|
||||||
|
liquid_material_name: NMP
|
||||||
|
speed: '400'
|
||||||
|
temperature: '40'
|
||||||
|
titration: ''
|
||||||
|
handles:
|
||||||
|
input:
|
||||||
|
- data_key: titration
|
||||||
|
data_source: handle
|
||||||
|
data_type: object
|
||||||
|
handler_key: titration
|
||||||
|
io_type: source
|
||||||
|
label: Titration Data From Calculation Node
|
||||||
|
result:
|
||||||
|
return_info: return_info
|
||||||
|
schema:
|
||||||
|
description: 批量创建90%10%小瓶投料任务。从计算节点接收titration数据,包含物料名称、主称固体质量、滴定固体质量和滴定溶剂体积。
|
||||||
|
properties:
|
||||||
|
feedback:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
title: BatchCreate9010VialFeedingTasks_Feedback
|
||||||
|
type: object
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
delay_time:
|
||||||
|
default: '600'
|
||||||
|
description: 延迟时间(秒),默认600
|
||||||
|
type: string
|
||||||
|
hold_m_name:
|
||||||
|
description: 库位名称,如"C01",必填参数
|
||||||
|
type: string
|
||||||
|
liquid_material_name:
|
||||||
|
default: NMP
|
||||||
|
description: 10%物料的液体物料名称,默认为"NMP"
|
||||||
|
type: string
|
||||||
|
speed:
|
||||||
|
default: '400'
|
||||||
|
description: 搅拌速度,默认400
|
||||||
|
type: string
|
||||||
|
temperature:
|
||||||
|
default: '40'
|
||||||
|
description: 温度(℃),默认40
|
||||||
|
type: string
|
||||||
|
titration:
|
||||||
|
description: '滴定信息对象,包含: name(物料名称), main_portion(主称固体质量g), titration_portion(滴定固体质量g),
|
||||||
|
titration_solvent(滴定溶液体积mL)'
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- titration
|
||||||
|
- hold_m_name
|
||||||
|
title: BatchCreate9010VialFeedingTasks_Goal
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
return_info:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- return_info
|
||||||
|
title: BatchCreate9010VialFeedingTasks_Result
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: BatchCreate9010VialFeedingTasks
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
|
batch_create_diamine_solution_tasks:
|
||||||
|
feedback: {}
|
||||||
|
goal:
|
||||||
|
delay_time: delay_time
|
||||||
|
liquid_material_name: liquid_material_name
|
||||||
|
solutions: solutions
|
||||||
|
speed: speed
|
||||||
|
temperature: temperature
|
||||||
|
goal_default:
|
||||||
|
delay_time: '600'
|
||||||
|
liquid_material_name: NMP
|
||||||
|
solutions: ''
|
||||||
|
speed: '400'
|
||||||
|
temperature: '20'
|
||||||
|
handles:
|
||||||
|
input:
|
||||||
|
- data_key: solutions
|
||||||
|
data_source: handle
|
||||||
|
data_type: array
|
||||||
|
handler_key: solutions
|
||||||
|
io_type: source
|
||||||
|
label: Solution Data From Python
|
||||||
|
result:
|
||||||
|
return_info: return_info
|
||||||
|
schema:
|
||||||
|
description: 批量创建二胺溶液配置任务。自动为多个二胺样品创建溶液配置任务,每个任务包含固体物料称量、溶剂添加、搅拌混合等步骤。
|
||||||
|
properties:
|
||||||
|
feedback:
|
||||||
|
properties: {}
|
||||||
|
required: []
|
||||||
|
title: BatchCreateDiamineSolutionTasks_Feedback
|
||||||
|
type: object
|
||||||
|
goal:
|
||||||
|
properties:
|
||||||
|
delay_time:
|
||||||
|
default: '600'
|
||||||
|
description: 溶液配置完成后的延迟时间(秒),用于充分混合和溶解,默认600秒
|
||||||
|
type: string
|
||||||
|
liquid_material_name:
|
||||||
|
default: NMP
|
||||||
|
description: 液体溶剂名称,用于溶解固体物料,默认为NMP(N-甲基吡咯烷酮)
|
||||||
|
type: string
|
||||||
|
solutions:
|
||||||
|
description: '溶液列表,JSON数组格式,每个元素包含: name(物料名称), order(序号), solid_mass(固体质量g),
|
||||||
|
solvent_volume(溶剂体积mL)。示例: [{"name": "MDA", "order": 0, "solid_mass":
|
||||||
|
5.0, "solvent_volume": 20}, {"name": "MPDA", "order": 1, "solid_mass":
|
||||||
|
4.5, "solvent_volume": 18}]'
|
||||||
|
type: string
|
||||||
|
speed:
|
||||||
|
default: '400'
|
||||||
|
description: 搅拌速度(rpm),用于混合溶液,默认400转/分钟
|
||||||
|
type: string
|
||||||
|
temperature:
|
||||||
|
default: '20'
|
||||||
|
description: 配置温度(℃),溶液配置过程的目标温度,默认20℃(室温)
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- solutions
|
||||||
|
title: BatchCreateDiamineSolutionTasks_Goal
|
||||||
|
type: object
|
||||||
|
result:
|
||||||
|
properties:
|
||||||
|
return_info:
|
||||||
|
description: 批量任务创建结果汇总,JSON格式包含总数、成功数、失败数及每个任务的详细信息
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- return_info
|
||||||
|
title: BatchCreateDiamineSolutionTasks_Result
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- goal
|
||||||
|
title: BatchCreateDiamineSolutionTasks
|
||||||
|
type: object
|
||||||
|
type: UniLabJsonCommand
|
||||||
create_90_10_vial_feeding_task:
|
create_90_10_vial_feeding_task:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal:
|
goal:
|
||||||
|
|||||||
Reference in New Issue
Block a user