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 } }