using DataEntity.Rack;
using DataEntity.Share;
using DataRWDAL;
using DriverLib.Engine;
using HxEnum;
using HxSocket;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Xml;
using XCommon;
using XCommon.Log;
using XCore;
using XHandler.Class;
using XHandler.Controls.Run.Com;
using XHandler.View;
using XHandler.View.MethodProperty;
using XImagingXhandler.XDAL;
using static HxEnum.OtherEnum;
namespace XHandler.Controls
{
///
/// 涂布文件控制类
///
public class CoatingFileControl
{
#region 变量
private string strCurrentCulture = "";
private WellCalc wellCalc = new WellCalc();
#region BLL
private LatticeBll latticeBll = new LatticeBll();
private AspirateBll aspirateBll = new AspirateBll();
private DispenseBll dispenseBll = new DispenseBll();
private UltrasonicBll ultrasonicBll = new UltrasonicBll();
#endregion
private MethodFrame methodFrame = new MethodFrame();
private CoatingFileBll coatingFileBll = new CoatingFileBll();
private CoatingBll coatingBll = new CoatingBll();
private LoadTipsBll loadTipsBll = new LoadTipsBll();
private string circularBarcode = string.Empty; // 记录下当前圆皿
private string plate1Barcode = string.Empty; // 记录下当前涂布的皿号
private string plate2Barcode = string.Empty;
private string choiceCenterPointVal = string.Empty; // 挑菌中心点位
private List listCoatingCoverLatticeId = new List(); // 涂布的板放盖位号:P2,P3
public RunWnd launchView = null;
public HxSocketClient socketTcpClientToRemote = null;
#endregion
///
/// 构造函数
///
public CoatingFileControl(string strCurrentCulture)
{
this.strCurrentCulture = strCurrentCulture;
// 挑菌中心点位
choiceCenterPointVal = ConfigurationManager.AppSettings["choiceCenterPointVal"].ToString();
// 涂布的板放盖位号:P2,P3
listCoatingCoverLatticeId = ComUtility.GetPlateCoverLatticeName();
}
#region 执行涂布文件,返回结果字符串
///
/// 执行涂布文件,返回结果字符串
///
///
///
///
///
///
public bool ExecuteCoatingFile(XmlNode xmlEnv, XmlNode methodNode, float zAxisVal, bool isSimulator)
{
bool result = true;
var platformNodeList = xmlEnv.SelectNodes("platform");
string strMethodName = methodNode.SelectSingleNode("name").InnerText;
if (launchView._cancelSource.IsCancellationRequested)
{
result = false;
return result;
}
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strStart.ToString());
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】start:");
}
try
{
#region 数据准备
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strPrepareData);
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: prepare data;");
}
MethodCoatingFile methodCoatingFile = coatingFileBll.GenerateMethodCoatingFileDataByXmlNode(methodNode);//获取涂布移液表
methodCoatingFile.transferDataTable = SelectFile(methodNode.SelectSingleNode("filePath").InnerText);
LoggerHelper.InfoLog($"[CoatingFileControl]:Args: {JsonConvert.SerializeObject(methodCoatingFile)}");
//从Excel文件读取当前挑选参数数据
string filePath = ConfigurationManager.AppSettings["choiceFilePath"];
DataTable dtParam = null;
if (!launchView.isRemotingOper)
{
// 单机运行时,作成 挑菌下发参数.xls
dtParam = DoUpdateCoatingMode(methodNode, filePath);
}
else
{
dtParam = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
}
int choice_category = Convert.ToInt32(dtParam.Rows[29][2].ToString()); // 挑选类别:0:点选; 1:穿刺
int choice_distance_mode = Convert.ToInt32((dtParam.Rows[10][2] != "") ? dtParam.Rows[10][2].ToString() : "0"); // 挑菌时离底或离菌表面,目前是离底
float choice_distance_value = (float)Convert.ToDouble((dtParam.Rows[11][2] != "") ? dtParam.Rows[11][2].ToString() : "0"); // 离底或菌表面距离
// 挑菌x、y轴偏移距离(毫米)
float choice_xAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[12][2] != "") ? dtParam.Rows[12][2].ToString() : "0"); // 挑菌时x坐标偏移
float choice_yAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[13][2] != "") ? dtParam.Rows[13][2].ToString() : "0"); // 挑菌时y坐标偏移
float coating_bottom_distance = (float)Convert.ToDouble((dtParam.Rows[14][2] != "") ? dtParam.Rows[14][2].ToString() : "0"); // 涂布离底或菌表面距离
float coating_xAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[15][2] != "") ? dtParam.Rows[15][2].ToString() : "0"); // 涂布时x坐标偏移
float coating_yAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[16][2] != "") ? dtParam.Rows[16][2].ToString() : "0"); // 涂布时y坐标偏移
int coating_mode = Convert.ToInt32((dtParam.Rows[17][2] != "") ? dtParam.Rows[17][2].ToString() : "0"); // 涂布方式 1:回字型; 2:Z字型; 3:上下移动; 4:吸放液; 5:放液
float press_distance = (float)Convert.ToDouble((dtParam.Rows[30][2] != "") ? dtParam.Rows[30][2].ToString() : "0"); // 挑菌时下压距离
float coatingspeed = (float)Convert.ToDouble((dtParam.Rows[18][2] != "") ? dtParam.Rows[18][2].ToString() : "0"); // 涂布动作速度
float fCircularDishMount = (float)Convert.ToDouble(ConfigurationManager.AppSettings["circularDishMount"]); // 圆形皿底托高度
int[] charray = Shared.ChannelsId;
string channelNums = Shared.ChannelsId.Count().ToString();
methodNode.SelectSingleNode("channels").InnerText = channelNums; // 更新一下枪通道数据
int iChioceTotal = methodCoatingFile.transferDataTable.Rows.Count; // 待涂布的数据总条目数
int realChioceTotal = iChioceTotal / launchView.choiceTimes; // 实际菌落的个数
#endregion
#region 数据验证
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strCheckData);
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: check data;");
}
#endregion
//判断是否是双涂布的文件,如果是双涂布的文件数据则分通道的处理方式不同;如果是单涂布的文件数据则正常分通道涂布即可
#region 挑菌+涂布
#region Lite_Choice、T200
if (Shared.ChannelCount == 1)
{
if (methodCoatingFile.transferDataTable.Rows.Count == 0)
{
// 文件涂布不执行,继续执行后面的动作方法
result = true;
return result;
}
#region 准备参数
// 转移目标板到涂布位方法
string strTransferDesPlateMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
"\\" + ConfigurationManager.AppSettings["transferDesPlateMethod"].ToString();
// 转移目标板盖到涂布放盖位方法
string strTransferDesPlateCoverMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
"\\" + ConfigurationManager.AppSettings["transferDesPlateCoverMethod"].ToString();
// 待涂布的数据总条目数
iChioceTotal = methodCoatingFile.transferDataTable.Rows.Count;
DataTable dtCoatingFile = methodCoatingFile.transferDataTable;
string targetWellName = dtCoatingFile.Rows[0][methodCoatingFile.destinationWell].ToString(); // 目标板孔位: A1
List lstDesPlateInfo = new List(); // 目标板已开盖的点位名称
// 所有目标板
DataView dvCoatingFile = new DataView(dtCoatingFile);
DataTable dtDistinct = dvCoatingFile.ToTable(true, methodCoatingFile.destinationLabware);
// 前回涂布板位
List lstCoatingLastLabwareName = new List();
string strLog = string.Empty;
// 拍照点位名称
string strSrcPlateName = ConfigurationManager.AppSettings["choiceLatticeId"].ToString();
#endregion
launchView.SetWaitOne();//暂停
#region 圆形皿超声
int nRtn = ControlCom.DoUltrasonicForFileCoating(launchView, xmlEnv, methodNode, methodCoatingFile, strSrcPlateName, isSimulator);
// 0:正常;1:继续;2:停止
if (nRtn == 2)
{
return false;
}
#endregion
#region 循环挑菌数量
for (int iChoiceIndex = 0; iChoiceIndex < iChioceTotal; iChoiceIndex++) // 循环控制待挑选的所有菌落
{
DataRow rowItem = dtCoatingFile.Rows[iChoiceIndex];
string strSrcRealPlateName = rowItem[methodCoatingFile.sourceLabware].ToString(); // 来源板真实点位名称
string strSrcPlateBarcode = rowItem["SourceBarcode"].ToString(); // 来源板Barcode
string strChoiceWellXYZ = rowItem[methodCoatingFile.sourceWell].ToString(); // 挑菌板孔位坐标
string strDesPlateName = rowItem[methodCoatingFile.destinationLabware].ToString(); // 目标板名称:P4
string strDesWell = rowItem[methodCoatingFile.destinationWell].ToString(); // 目标板孔位
bool isNewPlateBatch = bool.Parse(rowItem["IsNewPlateBatch"].ToString()); // 是否是新一批次的目标板(目标板不够用时,需要弹窗,人工补充耗材后点击继续)
bool isPlateLastWell = bool.Parse(rowItem["IsPlateLastWell"].ToString()); // 是否是一个板子最后的一个有效孔
bool isOpenCover = !lstDesPlateInfo.Exists(it => it.LabwarePositon.Equals(strDesPlateName));// 是否开盖
int diff = ((iChoiceIndex + 1) % launchView.choiceTimes);
launchView.SetWaitOne();//暂停
#region 是否为当前挑菌点的第一次涂布动作; 是否为当前挑菌点的最后一次涂布动作
bool isPointFirstTime = false;
bool isPointLastTime = false;
if (launchView.choiceTimes == 1)
{
isPointFirstTime = true;
isPointLastTime = true;
}
else
{
isPointFirstTime = ((iChoiceIndex + 1) % launchView.choiceTimes) != 0 ? true : false;
isPointLastTime = ((iChoiceIndex + 1) % launchView.choiceTimes) == 0 ? true : false;
}
#endregion
if (isPointFirstTime)
{
#region 判断台面上目标板是否够用
if ((isNewPlateBatch && iChoiceIndex != 0))
{
// 状态6 报错/急停 红闪/蜂鸣5S
CommonBll.StatusLamp(6, isSimulator);
SetBarcodeDlgForAddConsumables setBarcodeDlg = null;
bool bIsBreak = false;
Application.Current.Dispatcher.Invoke(new Action(() =>
{
string strMsg = string.Format(Properties.CoatingResource.strNoValidConsumables, Environment.NewLine);
setBarcodeDlg = new SetBarcodeDlgForAddConsumables(strMsg);
setBarcodeDlg.launchView = launchView;
setBarcodeDlg.dtCoatingFile = dtCoatingFile;
setBarcodeDlg.StartIndex = iChoiceIndex;
SolidColorBrush mybtn1_Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(70, 0, 0, 0));
setBarcodeDlg.Background = (System.Windows.Media.Brush)mybtn1_Brush;
setBarcodeDlg.ShowDialog();
if (setBarcodeDlg.DialogResult == true)
{
foreach (DataRow rowItemDes in dtDistinct.Rows)
{
// 更新已使用的涂布目标孔的颜色
ControlCom.UpdateDesPlateWellsColor(xmlEnv, rowItemDes[methodCoatingFile.destinationLabware].ToString(), launchView);
}
// 继续执行
// 状态4 运行 绿色
CommonBll.StatusLamp(4, isSimulator);
}
else
{
bIsBreak = true;
}
}));
if (bIsBreak)
{
result = true;
break;
}
}
#endregion
#region 目标板 开盖
// 涂布板位自动开关盖
if (isOpenCover && methodCoatingFile.autoOpenCloseCoverCoating)
{
for (int choiceTimeIndex = 0; choiceTimeIndex < launchView.choiceTimes; choiceTimeIndex++)
{
#region Del
//// 转移目标板到涂布位:PX->P10
//result =ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateMethodFileName, strDesPlateName, coatingLatticeId, isSimulator, launchView);
//if (!result)
//{
// return result;
//}
//coatingPlate.LatticeNum = strDesPlateName;
#endregion
CoatingLabware coatingLabware = new CoatingLabware();
coatingLabware.LabwarePositon = choiceTimeIndex == 0 ?
strDesPlateName :
dtCoatingFile.Rows[iChoiceIndex + 1][methodCoatingFile.destinationLabware].ToString(); // 耗材所在的位置
coatingLabware.LabwareCoverPositon = listCoatingCoverLatticeId[choiceTimeIndex]; // 耗材开盖放置的位置
lstDesPlateInfo.Add(coatingLabware);
// 转移目标板的盖到涂布位放盖位:P10->P2
result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateCoverMethodFileName, xmlEnv, coatingLabware.LabwarePositon, PositonTypeEnum.Desktop, GripperModelEnum.Right,
coatingLabware.LabwareCoverPositon, PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, launchView, TransferTypeEnum.Open);
if (!result)
{
return result;
}
}
}
#endregion
#region 超声探测
if (methodCoatingFile.isEnableultrasonic && isOpenCover) // 已开启超声 && 开盖
{
// N个目标板 先超声探测
bool bIsOk = DoUltrasonic(xmlEnv, methodNode, lstDesPlateInfo, methodCoatingFile, isSimulator);
if (!bIsOk)
{
return false;
}
}
#endregion
}
#region 安装涂布头
// 当前挑菌点的第一次涂布动作
// 多块目标板挑菌前要换枪头
if (isPointFirstTime || methodCoatingFile.pickAgoChangeTipEveryTime)
{
// 先去安装枪头
float tipoffsetLength = float.Parse(methodNode.SelectSingleNode("coatingOffset").InnerText);
bool bLoadTipResult = ControlCom.LoadTipAutomation(xmlEnv.SelectNodes("platform"), methodNode,
isSimulator, launchView, socketTcpClientToRemote, tipoffsetLength);
if (!bLoadTipResult)
{
return false;
}
}
#endregion
#region 挑菌前吸液
MethodChoiceAgoAspirateChild aspirateData = methodCoatingFile.choiceAgoAspirateData;
aspirateData.armValue = methodCoatingFile.armValue;
if ((isPointFirstTime || methodCoatingFile.pickAgoChangeTipEveryTime) &&
aspirateData.bEnableBeforeAspirate)
{
// 获取吸液耗材板位
var latticeAspirateNode = xmlEnv.SelectSingleNode("platform[labware_id='" + aspirateData.labwareValue + "']");
// 获取当前台面板位信息
int nLatticeIdAspirate = ControlCom.GetLatticeId(Convert.ToInt32(latticeAspirateNode.SelectSingleNode("lattice_id").InnerText));
Lattice latticeAspirate = LatticeDB.GetLatticeDataByIdFromdb(nLatticeIdAspirate.ToString());
bool bBeforeAspirate = ControlCom.DoBeforeAspirate(launchView, xmlEnv, strMethodName, aspirateData, latticeAspirate,
aspirateData.wellarray, aspirateData.labwareValue, "None", isSimulator);
if (!bBeforeAspirate)
{
return false;
}
}
#endregion
#region 挑选
// 当前挑菌点的第一次涂布动作
// 每次涂布前都挑菌
if (isPointFirstTime || methodCoatingFile.pickEveryTime)
{
string strScrlabwareid = ""; // 来源板耗材ID;
string strScrLatticeid = ""; // 来源板位置ID
// 用来源板名字取查找来源板的类型
var latticeXn = xmlEnv.SelectSingleNode("platform[labware_sname='" + strSrcPlateName + "']");
if (latticeXn != null)
{
strScrlabwareid = latticeXn.SelectSingleNode("labware_id").InnerText;
strScrLatticeid = latticeXn.SelectSingleNode("lattice_id").InnerText;
// 获取拍照位的坐标
Labware labwareSrc = LabwareDB.GetLabware(strScrlabwareid);
int latticeIdSrc = ControlCom.GetLatticeId(Convert.ToInt32(strScrLatticeid));
Lattice latticeSrc = LatticeDB.GetLatticeDataByIdFromdb(latticeIdSrc.ToString());
if (labwareSrc != null)
{
string[] vChoiceWellXYZSplit = strChoiceWellXYZ.Split(','); // 分割后的挑菌板孔位坐标
ChoiceMParam choiceMParam = new ChoiceMParam();
choiceMParam.xAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[0]) + choice_xAxis_offsite;
choiceMParam.yAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[1]) + choice_yAxis_offsite;
choiceMParam.xAxisOffsetVal = 0; // x轴移动到的坐标点距后再次动作偏移的x距离
choiceMParam.yAxisOffsetVal = 0; // y轴移动到的坐标点距后再次动作偏移的y距离
choiceMParam.armId = Convert.ToInt32(methodCoatingFile.armValue); // 挑选所用机械臂Id
choiceMParam.channelId = 1; // 挑选所用通道Id
choiceMParam.choiceMode = choice_category; // 挑菌模式:1:单选; 2:穿刺
choiceMParam.basezAxisVal = zAxisVal; // z轴默认安全坐标点距
choiceMParam.enableSupersonic = methodCoatingFile.isEnableultrasonic; // 挑菌时是否开启超声波探测值作为Z轴值:true:用;false:不用
choiceMParam.currentLengthOfTip = ControlCom.CurrentLengthOfTip; // 当前挑菌安装枪头后,枪增加的长度
choiceMParam.choiceTimeOnSameplace = 1; // 同一个菌落点第几次挑选
choiceMParam.latticeName = strSrcPlateName; // 挑菌板位名称
if (methodCoatingFile.choiceCategory == EnumManagement.GetEnumValue(ChoiceModeEnum.SigleSelectMode)) // 单选
{
choiceMParam.xAxisOffsetVal = 0;
choiceMParam.yAxisOffsetVal = 0;
choiceMParam.zAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[2]) - choice_distance_value;
}
else if (methodCoatingFile.choiceCategory == EnumManagement.GetEnumValue(ChoiceModeEnum.PricksMode)) // 穿刺
{
choiceMParam.xAxisOffsetVal = choice_xAxis_offsite;
choiceMParam.yAxisOffsetVal = choice_yAxis_offsite;
// 丝状真菌:固定高度挑菌
choiceMParam.zAxisVal = (float)latticeSrc.lattice_Z - (float)Convert.ToDouble(labwareSrc.well_bottom_height) -
ControlCom.CurrentLengthOfTip - choice_distance_value - fCircularDishMount;
}
choiceMParam.zPressDownVal = press_distance;
// 执行挑菌动作
bool bIsOk = ControlCom.RunChoice(launchView, strMethodName, choiceMParam, strChoiceWellXYZ,
strSrcRealPlateName, strSrcPlateBarcode, isSimulator);
if (!bIsOk)
{
return false;
}
}
}
else
{
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strChoiceLatticeWithout);
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】progress:Can't find lattice!");
}
result = false;
return result;
}
}
else
{
DateTime startTime = DateTime.Now;
DateTime endTime = DateTime.Now;
launchView.addChoiceDataIntoReport(null, strSrcRealPlateName, "0", new string[] { strChoiceWellXYZ }, "pass", "",
startTime, endTime, "Choice", strSrcPlateBarcode);
}
#endregion
#region 涂布
string strDesLabwareName = strDesPlateName; // 目标板名称:P10
string strDeslabwareid = ""; // 目标板耗材id;
string strDesLatticeid = ""; // 目标板位置Id
string strDesLabwareBarcode = ""; // 目标板条码
var latticeDesXn = xmlEnv.SelectSingleNode("platform[labware_sname='" + strDesLabwareName + "']");
if (latticeDesXn != null)
{
strDeslabwareid = latticeDesXn.SelectSingleNode("labware_id").InnerText;
strDesLatticeid = latticeDesXn.SelectSingleNode("lattice_id").InnerText;
//strDesLabwareBarcode = latticeDesXn.SelectSingleNode("labware_barcode").InnerText;
strDesLabwareBarcode = rowItem["TargetBarcode"].ToString(); // 目标板条码
// 获取待涂布板位的坐标
Labware labwareDes = LabwareDB.GetLabware(strDeslabwareid);
int latticeIdDes = ControlCom.GetLatticeId(Convert.ToInt32(strDesLatticeid));
Lattice latticeDes = LatticeDB.GetLatticeDataByIdFromdb(latticeIdDes.ToString());
if (labwareDes != null)
{
// 获取孔位信息
TipsTable targetWellInfo = ControlCom.GetWellInfo(labwareDes, latticeDes, latticeIdDes, strDeslabwareid, strDesWell);
if (targetWellInfo != null)
{
#region 涂布方式 1:回字型 2:Z字型;3:上下移动
if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.HuiziMode) ||
methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.ZMode) ||
methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.UpDownMode))
{
#region 涂布参数设置
CoatingMParam coatingMParam = new CoatingMParam();
coatingMParam.xAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_X.ToString()) + coating_xAxis_offsite;
coatingMParam.yAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_Y.ToString()) + coating_yAxis_offsite;
coatingMParam.armId = Convert.ToInt32(methodCoatingFile.armValue);
coatingMParam.channelId = 1;
float zVal = targetWellInfo.axis_b_Z - (float)coating_bottom_distance;
coatingMParam.zAxisVal = zVal < 0 ? 0 : zVal; // 涂布主z轴移动坐标点距
coatingMParam.zChAxisVal = coatingMParam.zAxisVal; // 涂布通道z轴移动坐标点距
coatingMParam.coatingShape = coating_mode; // 涂布方式 1:回字型 2:Z字型;3:上下移动
// 孔洞形状,1:圆柱体;2:立方体
// 涂布范围值:如果是圆形孔值为半径;如是方形孔值为边长一半
coatingMParam.rangeVal = labwareDes.well_shape == 1 ?
((float)labwareDes.well_mouth_radius) : ((float)(labwareDes.well_top_x / 2.0d));
coatingMParam.basezAxisVal = zAxisVal; // 主z轴默认安全坐标点距
coatingMParam.coatingSpeed = coatingspeed; // 涂布电机速度
coatingMParam.coatingTipsOutWidth = ControlCom.OutWidthOfTip; // 涂布枪头头部外宽度
coatingMParam.coatingTipsInWidth = ControlCom.InWidthOfTip; // 涂布枪头头部内宽度
// isFirstSupersonic = true:本耗材第一次超声探测
if (isNewPlateBatch && isPointFirstTime)
{
lstCoatingLastLabwareName.Clear();
}
coatingMParam.isFirstSupersonic = !lstCoatingLastLabwareName.Contains(strDesLabwareName);
// 当前涂布板位更新到【前回涂布板位】
if (!lstCoatingLastLabwareName.Contains(strDesLabwareName))
{
lstCoatingLastLabwareName.Add(strDesLabwareName);
}
coatingMParam.enableSupersonic = methodCoatingFile.isEnableultrasonic; // 是否使用超声数据:true:是;false:否
coatingMParam.currentLengthOfTip = ControlCom.CurrentLengthOfTip; // 当前涂布安装枪头后,枪增加的长度
// 单孔板中心坐标x,y,z 字符串,逗号分割
coatingMParam.centerPointVal = ((float)latticeDes.lattice_X + ((float)latticeDes.lattice_length / 2)).ToString() + "," + ((float)latticeDes.lattice_Y + ((float)latticeDes.lattice_width / 2)).ToString() + "," + coatingMParam.zAxisVal.ToString();
//coatingMParam.xLengthOfGap = 10.0f; // 超声波x方向间隙
//coatingMParam.yLengthOfGap = 10.0f; // 超声波y方向间隙
coatingMParam.latticeName = strDesLabwareName; // 超声波探测涂布的板位名称
#endregion
// 执行涂布动作
bool bIsOk = ControlCom.RunCoating(launchView, strMethodName, coatingMParam, targetWellInfo, strDesWell,
strDesLabwareName, strDesLabwareBarcode, isSimulator);
if (!bIsOk)
{
return false;
}
}
#endregion
#region 涂布方式 4:吸放液
else if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.AspirateDispenseMode))
{
#region 混合参数设置
MixMParam mixMParam = new MixMParam();
mixMParam.xAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_X.ToString()); // x轴移动到的坐标点距
mixMParam.yAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_Y.ToString()); // y轴移动到的坐标点距
mixMParam.armId = Convert.ToInt32(methodCoatingFile.armValue); // 吸液所用机械臂Id
mixMParam.isSurvey = false; // 是否需要探测
mixMParam.mixCount = methodCoatingFile.mixcount; // 混合次数
mixMParam.mixvolume = (float)methodCoatingFile.mixvolume; // 混合时体积
mixMParam.mixAspiratePositionText = methodCoatingFile.mixAspiratePositionText; // 吸液距离类型名称
mixMParam.mixAspiratePositionValue = methodCoatingFile.mixAspiratePositionValue; // 吸液距离类型Id,0:液面; 1顶部;2:底部
if (methodCoatingFile.mixAspiratePositionValue == EnumManagement.GetEnumValue(MixPositionEnum.Top) ||
methodCoatingFile.mixAspiratePositionValue == EnumManagement.GetEnumValue(MixPositionEnum.Bottom)) // top、bottom
{
mixMParam.mixAspirateDistance = (float)methodCoatingFile.mixAspirateDistance; // 吸液距离
}
mixMParam.mixAspirateSpeed = (float)methodCoatingFile.mixAspirateSpeed; // 吸液速度
// 液体参数
string liquidpidValue = methodCoatingFile.liquidpidValue;
Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue);
mixMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume;
mixMParam.mixDispensePositionText = methodCoatingFile.mixDispensePositionText; // 排液距离类型名称
mixMParam.mixDispensePositionValue = methodCoatingFile.mixDispensePositionValue; // 排液距离类型Id,0:液面; 1顶部;2:底部
mixMParam.mixDispenseDistance = (float)methodCoatingFile.mixDispenseDistance; // 排液距离
mixMParam.mixDispenseSpeed = (float)methodCoatingFile.mixDispenseSpeed; // 排液速度
//liquidVolumeType 未传值
float zVal = targetWellInfo.axis_b_Z + ControlCom.CurrentLengthOfTipOffSetVal;
mixMParam.zAxisVal = zVal; // 混合时z轴移动坐标点距
mixMParam.wellzAxisVal = zVal - (float)labwareDes.well_height;
mixMParam.basezAxisVal = (float)Convert.ToDouble(ConfigurationManager.AppSettings["zAxisSafeVal"]);
#endregion
// 执行混合动作
bool bIsOk = ControlCom.RunMix(launchView, strMethodName, mixMParam, targetWellInfo, strDesWell,
strDesLabwareName, strDesLabwareBarcode, isSimulator);
if (!bIsOk)
{
return false;
}
}
#endregion
#region 涂布方式 5:放液
else if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.DispenseMode))
{
// 放液
bool bDispense = ControlCom.DoDispense(launchView, strMethodName, methodCoatingFile.choiceAgoAspirateData, labwareDes, latticeDes, targetWellInfo, strDesLabwareBarcode, isSimulator);
if (!bDispense)
{
return false;
}
}
#endregion
}
}
else
{
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strChoiceLatticeWithout);
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】progress:Can't find lattice!");
}
result = false;
return result;
}
}
else
{
if (strCurrentCulture.Equals("zh-CN"))
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strCoatingLatticeWithout);
}
else
{
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: lattice was wrong!");
}
result = false;
return result;
}
#endregion
#region 卸载Tip,丢在垃圾桶
if (isPointLastTime || methodCoatingFile.pickAgoChangeTipEveryTime)
{
UnloadTipsControl unloadTipsControl = new UnloadTipsControl(Shared.SoftwareInformation.currentculture);
unloadTipsControl.launchView = launchView;
unloadTipsControl.socketTcpClientToRemote = socketTcpClientToRemote;
bool bUnloadResult = unloadTipsControl.ExecuteUnloadTipsInToTrash(platformNodeList, methodNode, isSimulator);
launchView.currentIsLoadingTips = false;
}
#endregion
if (isPointLastTime)
{
#region 计算当前挑菌的个数
decimal dTemp = ((decimal)(iChoiceIndex + 1)) / (decimal)launchView.choiceTimes;
decimal realCurrentChioceCnt = Math.Ceiling(dTemp);
if (strCurrentCulture.Equals("zh-CN"))
{
strLog = string.Format("【{0}】>Xhandler: 【{1}】{2} {3}:{4}/{5}",
DateTime.Now.ToString("HH:mm:ss:fff"), methodCoatingFile.name,
Properties.MachineRunResource.strProgress, Properties.RunCoatingFileResource.strPickingBacteria, realCurrentChioceCnt, realChioceTotal);
}
else
{
strLog = string.Format("【{0}】>Xhandler: 【{1}】progress: picking bacteria:{2}/{3}",
DateTime.Now.ToString("HH:mm:ss:fff"), methodCoatingFile.name, realCurrentChioceCnt, realChioceTotal);
}
launchView.AddLogs(strLog);
#endregion
}
#region 目标板 关盖
// 不论是单板涂布还是双板涂布,都是在最后块目标板涂布之后再关盖
if (isPlateLastWell && isPointLastTime && methodCoatingFile.autoOpenCloseCoverCoating)
{
for (int choiceTimeIndex = 0; choiceTimeIndex < lstDesPlateInfo.Count; choiceTimeIndex++)
{
// 转移耗材盖到目标位:P11->P10
result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateCoverMethodFileName, xmlEnv, lstDesPlateInfo[choiceTimeIndex].LabwareCoverPositon, PositonTypeEnum.Desktop, GripperModelEnum.Right,
lstDesPlateInfo[choiceTimeIndex].LabwarePositon, PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, launchView, TransferTypeEnum.Close);
if (!result)
{
return result;
}
#region Del
//// 转移涂布位耗材到原来位置:P10->PX
//result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateMethodFileName, coatingLatticeId, coatingPlate.LatticeNum, isSimulator, launchView);
//if (!result)
//{
// return result;
//}
#endregion
}
lstDesPlateInfo.Clear();
// 继续执行
}
#endregion
}
#endregion
}
#endregion
#endregion
}
catch (Exception ex)
{
LoggerHelper.ErrorLog("ERROR:", ex);
#region Exception
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + strMethodName + "】error:source:" + ex.Source + ";error:" + ex.Message + ";");
result = false;
MethodMsg methodMsg = new MethodMsg(
Guid.NewGuid().ToString(),
"ID202_Choice_machine",
5,
"",
"ExecuteCoatingFile",
"1001",
"error source:" + ex.Source + ";error:" + ex.Message,
6,
0
);
if (socketTcpClientToRemote != null)
{
socketTcpClientToRemote.sendmessageError(socketTcpClientToRemote.CreateSendMsgContent(methodMsg, false), launchView.isRemotingOper);
}
#endregion
}
return result;
}
///
/// 执行超声探测
///
///
///
///
///
///
///
private bool DoUltrasonic(XmlNode plateNode, XmlNode methodNode, List lstDesPlateInfo, MethodCoatingFile methodCoatingFile, bool isSimulator)
{
// 1、2
for (int choiceTimeIndex = 0; choiceTimeIndex < lstDesPlateInfo.Count; choiceTimeIndex++)
{
// 执行超声单步操作
string labwarePositon = lstDesPlateInfo[choiceTimeIndex].LabwarePositon;
int nRtn = ControlCom.DoUltrasonicForFileCoating(launchView, plateNode, methodNode, methodCoatingFile, labwarePositon, isSimulator);
// 0:正常;1:继续;2:停止
if (nRtn == 2)
{
return false;
}
}
return true;
}
///
/// 单机运行时,作成 挑菌下发参数.xls
///
///
///
private DataTable DoUpdateCoatingMode(XmlNode xmlNode, string filePath)
{
DataTable dtCoatingParams = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
string strValName = "属性值";
#region 数据准备
if (dtCoatingParams.Rows.Count > 29)
{
// 挑菌方式:0:单选; 1:穿刺; 2:吸放液; 3:放液
dtCoatingParams.Rows[29][strValName] = xmlNode.SelectSingleNode("choiceCategory").InnerText;
}
// 涂布方式
dtCoatingParams.Rows[17][strValName] = xmlNode.SelectSingleNode("coatingmodeValue").InnerText; // 画面上涂布方式 0:回字型 1:Z字型;2:上下移动
#endregion
ExcelAndCsvHelper.WriteDataTableToExcelFile(dtCoatingParams, filePath);
return dtCoatingParams;
}
#endregion
#region 重新加载文件数据
private DataTable SelectFile(string file)
{
string ext = System.IO.Path.GetExtension(file);
DataTable transferData = null;
if (string.Compare(ext, ".csv", true) == 0)
transferData = ExcelAndCsvHelper.GetDataTableFromCsvFile(file, false);
else
transferData = ExcelAndCsvHelper.GetDataTableFromExcelFile(file, true);
if (transferData == null)
{
transferData = new DataTable();
}
return transferData;
}
#endregion
}
}