C00225155-02/C00225155/MegaRobo.C00225155/MegaRobo.C00225155.AppServer/ExecuteWorks/StationService_MaterialDosi...

462 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Common.Models;
using CommunityToolkit.Mvvm.Messaging;
using MegaRobo.C00225155.Entities;
using MegaRobo.C00225155.Entities.Entity_DB;
using MegaRobo.Contract;
using MegaRobo.ControlDevices;
using MegaRobo.Entities;
using MegaRobo.Logger;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Management;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;
namespace MegaRobo.C00225155.AppServer.ExecuteWorks
{
/// <summary>
/// 这里主要是针对配置站服务控制1ml移液枪的逻辑
/// </summary>
public partial class StationService_MaterialDosing: StationServiceBase
{
/// <summary>
/// 1ml枪头 Z轴初始化
/// </summary>
/// <returns></returns>
private async Task GunZAxisInit_M1(DeviceNames pipetteDevice, PipetteService pipetteService)
{
this.Logger.LogInformation($"{pipetteDevice}Z轴初始化");
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
pipetteService.Disconnect();
await pipetteService.ConnectionAsync();
dictResult = await pipetteService.InitZaxis(IdList.ToArray());
if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
this.Logger.LogError($"{pipetteDevice}Z轴初始化失败,{PipetteErrorDic[errorkey]}");
}
}
/// <summary>
/// 1ml枪头 总初始化
/// </summary>
/// <returns></returns>
private async Task GunAllInit_M1(DeviceNames pipetteDevice, PipetteService pipetteService)
{
this.Logger.LogInformation($"{pipetteDevice}总初始化");
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
dictResult = await pipetteService.InitZaxis(IdList.ToArray());
if (dictResult != null)
{
dictResult = await pipetteService.InitPump();
}
if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
this.Logger.LogError($"{pipetteDevice}总初始化失败,{PipetteErrorDic[errorkey]}");
}
}
/// <summary>
/// 1ml枪头 取TIP头
/// </summary>
/// <returns></returns>
private async Task<bool> GunPickUpTip_M1(DeviceNames pipetteDevice, PipetteService pipetteService, TipTypeEnum tipVolume)
{
if (TestMode) return true;
ushort tipType = 7;
uint go = 0;
if (tipVolume.Equals(TipTypeEnum._300UL))//300ul slim的有滤芯的、导电的枪头
{
tipType = 9; go = 0;
}
else if (tipVolume.Equals(TipTypeEnum._50UL)) //50ul的有滤芯的、导电的枪头
{
tipType = 3;
}
else if (tipVolume.Equals(TipTypeEnum._1000UL))
{
tipType = 7;//1000ul的有滤芯的、导电的枪头
}
this.Logger.LogInformation($"{pipetteDevice}取Tip-tipType(9:300,3:50,7:1000):{tipType}");
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
dictResult = await pipetteService.TipInstall(tipType: tipType, go, IdList.ToArray());
await pipetteService.InitZaxis(); //Z轴带动泵模块向上运动到最高处
if (dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00") || dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "76"))
{
this.Logger.LogInformation($"{pipetteDevice}取Tip成功");
return true;
}
else if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
//WeakReferenceMessenger.Default.Send(new ConfirmMessage()
//{
// Header = $"{pipetteDevice}取Tip失败",
// Content = $"{PipetteErrorDic[errorkey]}",
// OkButtonContent = "继续",
// CancelButtonContent = "取消",
//});
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = $"{pipetteDevice}取Tip失败" , Content = $"{PipetteErrorDic[errorkey]}" });
this.Logger.LogError($"{pipetteDevice}取Tip失败,{PipetteErrorDic[errorkey]}");
await GunAllInit_M1(pipetteDevice, pipetteService);
return false;
}
return false;
}
//public async Task ZMove(uint pos)
//{
// IEnumerable<uint> pipetteIdList = new List<uint> { 1 };
// pipetteIdList = pipetteService_1ml.PipetteList.Select(x => x.Id);
// foreach (var id in pipetteIdList)
// {
// var dictRes = await pipetteService_1ml.MoveZaxis(0, id);
// }
//}
/// <summary>
/// 1ml枪头 丢弃Tip头
/// </summary>
/// <returns></returns>
private async Task GunDiscardTip_M1(DeviceNames pipetteDevice, PipetteService pipetteService)
{
if (TestMode) return;
this.Logger.LogInformation($"{pipetteDevice}丢Tip");
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
//var dictResult = await pipetteService_1ml.TipUninstall(1);
//await pipetteService_1ml.InitZaxis();
//if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
//{
// this.Logger.LogError($"{DeviceNames.Pipette_Config_1ml}丢Tip失败,{dictResult.LastOrDefault().Value}");
//}
dictResult = await pipetteService.InitPump(IdList.ToArray());
await pipetteService.InitZaxis();
if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
WeakReferenceMessenger.Default.Send(new ConfirmMessage()
{
Header = $"{pipetteDevice}丢Tip失败",
Content = $"{PipetteErrorDic[errorkey]}",
OkButtonContent = "继续",
CancelButtonContent = "取消",
});
this.Logger.LogError($"{pipetteDevice}丢Tip失败,{PipetteErrorDic[errorkey]}");
await GunAllInit_M1(pipetteDevice, pipetteService);
}
}
private async Task GunAbsorb_M1(DeviceNames pipetteDevice, PipetteService pipetteService, string liquidName, int tiporder, double absorbVolumn, SourceLiquidBottleModel sourceLiquidBottleModel)
{
if (TestMode) return;
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
var curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_Dose>(x => x.LiquidName == liquidName && x.TipType == tiporder); //&& x.TipType == tiporder 暂时屏蔽
if (curLiqud == null || curLiqud.Count == 0)
{
curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_Dose>(x => x.TipType == tiporder);
}
var curLiqud_M1 = curLiqud.FirstOrDefault();
curLiqud_M1.TipType = tiporder;
curLiqud_M1.LiquidVolume = (int)Math.Abs(absorbVolumn * curLiqud_M1.Ratio);
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
this.Logger.LogInformation($"{pipetteDevice}开始吸液,吸液量{curLiqud_M1.LiquidVolume}ul");
dictResult = await OnSuckFluid(pipetteService, IdList, curLiqud_M1, 1, 1, sourceLiquidBottleModel);
//for (int i = 1; i < 3; i++) //若吸液失败,二次吸液
{
if (dictResult != null)
{
if (dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
this.Logger.LogInformation($"{pipetteDevice}吸液成功");
await pipetteService.InitZaxis();
}
else
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
this.Logger.LogError($"{pipetteDevice}吸液失败,{PipetteErrorDic[errorkey]}");
WeakReferenceMessenger.Default.Send(new ConfirmMessage()
{
Header = $"{pipetteDevice}吸液失败",
Content = $"{PipetteErrorDic[errorkey]}",
OkButtonContent = "继续",
CancelButtonContent = "取消",
});
await pipetteService.InitZaxis();
}
}
else
{
await pipetteService.InitZaxis();
}
}
}
/// <summary>
/// 1ml枪头 分液
/// </summary>
/// <param name="liquidName">液体名称</param>
/// <param name="volumn">分液体积</param>
/// <returns></returns>
private async Task GunDispensing_M1(DeviceNames pipetteDevice, PipetteService pipetteService, string liquidName, int tipOrder,uint vol, SampleBottleModel sampleBottleModel)
{
if (TestMode) return;
IDictionary<uint, string> dictResult = new Dictionary<uint, string>();
//IList<uint> listId = new List<uint>();
Liquid_lml_Dose curLiqud_M1 = new Liquid_lml_Dose();
IList<uint> IdList = new List<uint>();
switch (pipetteDevice)
{
case DeviceNames.Pipette_Dose_1ml_1:
IdList = new List<uint> { 1 };
break;
case DeviceNames.Pipette_Dose_1ml_2:
IdList = new List<uint> { 2 };
break;
case DeviceNames.Pipette_Dose_1ml_3:
IdList = new List<uint> { 3 };
break;
case DeviceNames.Pipette_Dose_1ml_4:
IdList = new List<uint> { 4 };
break;
default:
break;
}
this.Logger.LogInformation($"{pipetteDevice}开始分液");
var curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_Dose>(x => x.LiquidName == liquidName && x.TipType == tipOrder); //
if (curLiqud == null || curLiqud.Count == 0)
{
curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_Dose>(x => x.TipType == tipOrder);
}
curLiqud_M1 = curLiqud.FirstOrDefault();
if (sampleBottleModel.SampleBottleType == SampleBottleTypeEnum._12mL)
{
curLiqud_M1.DispenHeight -= 300; //12ml样品瓶比5ml高约3cm
}
dictResult = await OnDispenFluid(pipetteService, IdList, curLiqud_M1, vol);//(uint)Math.Abs(volumn)
if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
{
string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
this.Logger.LogError($"{pipetteDevice}分液失败,{PipetteErrorDic[errorkey]}");
WeakReferenceMessenger.Default.Send(new ConfirmMessage()
{
Header = $"{pipetteDevice}分液失败",
Content = $"{PipetteErrorDic[errorkey]}",
OkButtonContent = "继续",
CancelButtonContent = "取消",
});
await pipetteService.InitZaxis();
}
else
{
this.Logger.LogInformation($"{pipetteDevice}分液成功");
await pipetteService.InitZaxis();
}
}
private async Task<IDictionary<uint, string>> OnSuckFluid(PipetteService pipetteService, IList<uint> listId, Liquid_lml_Dose liquidProduct, int subid, int asperIndex = 1, SourceLiquidBottleModel sourceLiquidBottleModel = null)
{
IDictionary<uint, string> resultData;
try
{
if (liquidProduct == null) return null;
uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
uint liquidReagentCode = (uint)liquidProduct.LiquidParamId; //移液枪液体编号
uint vol = (uint)liquidProduct.LiquidVolume;//吸液体积
uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
uint pos = (uint)liquidProduct.AspireHeight; //液面探测其实高度 或者固定吸液高度
if (lld == 0) //qrbian todo:需要区分1000μl,300μl,50μl,计算余量对应的吸液高度 根据sourceLiquidBottleModel sourceLiquidBottleModel.RemainVolume
{
//底部高度三种tip不一样 = 底部高度 - 液体剩余高度 + 浸入高度三种tip不一样
//int heightMax = liquidProduct.TipType == 3 ? 1000 : (liquidProduct.TipType == 2 ? 300 : 50); //tip到底部高度最大值
int heightMax = 2220;
//int inHeight = liquidProduct.TipType == 3 ? 1000 : (liquidProduct.TipType == 2 ? 300 : 50); //浸入高度
int inHeight = 50; //浸入高度
if (sourceLiquidBottleModel.RemainVolume > 40)
{
sourceLiquidBottleModel.RemainVolume = 40;
}
int liquidRemainHeight = (int)(100 * sourceLiquidBottleModel.RemainVolume / (Math.PI * 1.25 * 1.25));
int realHeight = heightMax - liquidRemainHeight + inHeight; //底部高度向上抬升液体高度再浸入液面高度
realHeight = realHeight > heightMax ? heightMax : realHeight; //确保不能超过底部高度
//pos = 1700; //todo:将上面的heightMax、inHeight修改这个替换成realHeight
pos = (uint)realHeight;
}
IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
foreach (var id in listId)
{
idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, lld));
}
resultData = await pipetteService.SuckFluid(idArrayParams);
}
catch (Exception ex)
{
this.Logger.LogError($"{DeviceNames.Pipette_Dose_1ml_1}吸液异常:{ex}");
throw;
}
return resultData;
}
private async Task<IDictionary<uint, string>> OnDispenFluid1(PipetteService pipetteService, IList<uint> listId, Liquid_lml_Dose liquidProduct, uint dispos)
{
IDictionary<uint, string> resultData = new Dictionary<uint, string>();
try
{
if (liquidProduct == null) return null;
uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
uint liquidReagentCode = (uint)liquidProduct.LiquidParamId; //移液枪液体编号
uint vol = (uint)liquidProduct.LiquidVolume;//吸液体积
uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
uint pos = dispos;//吸液高度
IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
foreach (var id in listId)
{
idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, 0));
}
resultData = await pipetteService.DrainageFluid(idArrayParams);
}
catch (Exception ex)
{
this.Logger.LogError($"{DeviceNames.Pipette_Dose_1ml_1}分液异常,异常原因:{ex}");
}
return resultData;
}
private async Task<IDictionary<uint, string>> OnDispenFluid(PipetteService pipetteService, IList<uint> listId, Liquid_lml_Dose liquidProduct, uint volume)
{
IDictionary<uint, string> resultData = new Dictionary<uint, string>();
try
{
if (liquidProduct == null) return null;
uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
uint liquidReagentCode = (uint)liquidProduct.LiquidParamId;//移液枪液体编号
uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
uint pos = (uint)liquidProduct.DispenHeight;//分液高度
uint vol = volume;
IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
foreach (var id in listId)
{
idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, 0));
}
resultData = await pipetteService.DrainageFluid(idArrayParams);
}
catch (Exception ex)
{
this.Logger.LogError($"{DeviceNames.Pipette_Dose_1ml_1}分液异常,异常原因:{ex.ToString()}");
}
return resultData;
}
}
}