using DataEntity; using DataEntity.Share; using DataRWDAL; using DriverLib.Engine; using System; using System.Collections.Generic; using System.Linq; using System.Xml; using XCommon; using XCommon.Log; using XCore; using XCoreBLL; using XHandler.Controls.Run.Com; using XHandler.View; using XImagingXhandler.XDAL; namespace XHandler.Controls { /// /// 泵加液运行处理 /// public class PumpDispenseControl { string strCurrentCulture = ""; WellCalc wellCalc = new WellCalc(); LatticeBll latticeBll = new LatticeBll(); PumpDispenseBll pumpDispenseBll = new PumpDispenseBll(); public RunWnd launchView = null; LiquidAccuracyBll liquidAccuracyBll = new LiquidAccuracyBll(); public PumpDispenseControl(string strCurrentCulture) { this.strCurrentCulture = strCurrentCulture; } #region 执行吸液,返回结果字符串 /// /// 执行吸液,返回结果字符串 /// /// 板位节点信息 /// 装载方法属性节点对象 /// z轴安全距离 /// 0:连接谁;1:仿真 /// public bool ExecutePumpDispense(XmlNode xmlEnv, XmlNode methodNode, float zAxisVal, bool isSimulator) { bool result = true; HxResult ret = new HxResult(); if (launchView._cancelSource.IsCancellationRequested) { result = false; return result; } #region Start Log if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strStart.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】start:"); } #endregion #region 数据准备 string labwareText = methodNode.SelectSingleNode("labware/text").InnerText; string strLabwareid = methodNode.SelectSingleNode("labware/value").InnerText; string armName = methodNode.SelectSingleNode("arm/text").InnerText; string armId = methodNode.SelectSingleNode("arm/value").InnerText; string latticenum = methodNode.SelectSingleNode("position/text").InnerText; //string latticeId= string strWells = methodNode.SelectSingleNode("wellarray").InnerText; // 每泵参数 List pumpParams = new List(); var drops = methodNode.SelectNodes("pump"); if (drops != null) { foreach (XmlNode x in drops) { Pump d = new Pump(); d.name = x.SelectSingleNode("name").InnerText; d.volume = Convert.ToDouble(x.SelectSingleNode("volume").InnerText); d.liquidValue = x.SelectSingleNode("liquidid/value").InnerText; d.liquidText = x.SelectSingleNode("liquidid/text").InnerText; d.liquidRSValue = x.SelectSingleNode("liquidrangeid/value").InnerText; d.liquidRSText = x.SelectSingleNode("liquidrangeid/text").InnerText; d.liquidTypeValue = x.SelectSingleNode("liquidtypeid/value").InnerText; d.liquidTypeText = x.SelectSingleNode("liquidtypeid/text").InnerText; pumpParams.Add(d); } } #endregion #region 数据验证 Labware labwares = LabwareDB.GetLabware(strLabwareid); string[] wells = new string[] { }; string wellVariable = string.Empty; if (!string.IsNullOrEmpty(strWells)) { //判断是否包含等号,如果是包含等号的,则是变量控制孔位 if (strWells.Contains(",")) { wells = strWells.Split(','); } else if (strWells.Contains("=")) { } } else if (strWells.Contains("=")) { wellVariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable variable = new Variable(); // 从当前变量字典中取出变量的值 for (int i = 0; i < launchView.gloadVariable.Count; i++) { Variable v = launchView.gloadVariable.Peek(); if (v.variablename == wellVariable) { variable = v; break; } } } // 给孔位排序 if (strWells.Contains(',')) { string suffix = wells[0].Substring(1, wells[0].Length - 1); List sortWellName = new List(); if (Shared.ChannelCount == 1) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + suffix; if (wells.Contains(rowWellName)) { sortWellName.Add(rowWellName); } } wells = sortWellName.ToArray(); } else if (Shared.ChannelCount > 1) { #region Del //List sortWellNameSH = new List();//用来按列的孔位名称 ////上海的移液枪正常排列,A1,B1,C1,D1,E1,F1,G1,H1 //for (int j = 1; j < labwares.number_column; j++) //{ // int countWell = 0;//当前选择的孔位数量 // sortWellNameSH.Clear(); // for (int i = 0; i < labwares.number_row; i++) // { // string rowName = ComUtility.GetRowChar(i);//创建行号 // string rowWellName = rowName + j; // if (wells.Contains(rowWellName)) // { // sortWellNameSH.Add(rowWellName); // countWell++; // } // } // if (wells.Length == countWell && countWell == chs.Length) // { // wells = sortWellNameSH.ToArray(); // break; // } // else // { // if (strCurrentCulture.Equals("zh-CN")) // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strError.ToString() + Properties.RunAspirateResource.strChannelMatch.ToString()); // } // else // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Channels aren't match with these wells, please check!"); // } // result = false; // return result; // } //} #endregion } } else if (!string.IsNullOrEmpty(strWells) && !strWells.Contains(',') && !strWells.Contains("=")) // 只有一个孔位 { wells = new string[] { strWells }; } else if (strWells.Contains("=")) // 利用循环 { Variable variable = new Variable(); string strvariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable globalVariable = null; globalVariable = ControlCom.SearchGlobalVariable(launchView, strvariable); if (!string.IsNullOrEmpty(globalVariable.variablename)) { variable = globalVariable; } if (variable.variablename.Equals(string.Empty) && strvariable.Length >= 1)//没有查找到变量名,看看是不是表达式,并求出表达式值 { Stack stackTem = new Stack();//临时存储变量过得对象 int totalLoop = launchView.gloadVariable.Count; // 从当前变量字典中取出变量的值 for (int i = 0; i < totalLoop; i++) { Variable v = launchView.gloadVariable.Pop(); //取出最近的一个匹配变量 stackTem.Push(v); if (strvariable.Contains(v.variablename)) { variable = v; break; } } int totalLoopTem = stackTem.Count; for (int i = 0; i < totalLoopTem; i++) { Variable v = stackTem.Pop(); launchView.gloadVariable.Push(v); } Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); string strExpress = strvariable.Replace(variable.variablename, variable.variablecurval); variable.variablecurval = Microsoft.JScript.Eval.JScriptEvaluate(strExpress, ve).ToString(); } List sortWellName = new List(); for (int j = 1; j <= labwares.number_column; j++) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + j; sortWellName.Add(rowWellName); } } wells = new string[1]; wells[0] = sortWellName[Convert.ToInt32(variable.variablecurval) - 1]; } // 判断方法中的板位和板子是否能对应上设置的台面 Lattice lattice = new Lattice(); TabletopTemplate tabletopTemplate = TabletopTemplateDB.GetCurrentAppTabletopTemplateCollectionFromdb(); //增加台面模板判断 if (tabletopTemplate == null) { lattice = LatticeDB.GetLatticeDataByIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number); } else { lattice = LatticeDB.GetLatticeDataByLatticeNumAndTempIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number, tabletopTemplate.tabletopid); } int xmlLatticeId = Convert.ToInt32(latticenum.Substring(1));//ControlCom.GetLatticeId(Convert.ToInt32(lattice.lattice_id), false); var latticeXn = xmlEnv.SelectSingleNode("platform[lattice_id='" + xmlLatticeId.ToString() + "']"); if (latticeXn != null) { labwares.labware_sname = latticeXn.SelectNodes("labware")[0].SelectSingleNode("labware_sname").InnerText; } else { if (lattice.is_trash.Equals(1)) { } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutLattice.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } } #endregion #region 执行构建 try { // 获取当前台面的板子吸液列的坐标 Lattice slattice = DataRWDAL.LatticeDB.GetLatticeDataByIdFromdb(lattice.lattice_id); if (lattice.is_trash.Equals(1)) { // 获取板位孔的坐标数据 //List dtWells = ControlCom.GenerateWellCoordinate(labwares, slattice); //根据循环处理孔位 //TipsTable tipsTable = null; //tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) // && t.labware_id.Equals(strLabwareid) // && t.wellname.Equals(wells[0])); if (armName == "泵臂") { AddLiquidMParamSH addLiquidMParamSH = new AddLiquidMParamSH(); addLiquidMParamSH.armId = Convert.ToInt32(armId); int[] channels = new int[pumpParams.Count]; float[] fVolumes = new float[pumpParams.Count]; float[] xVals = new float[pumpParams.Count]; float[] yVals = new float[pumpParams.Count]; addLiquidMParamSH.channelId = channels; addLiquidMParamSH.channelCount = pumpParams.Count; Liquid liquid = null; for (int i = 0; i < pumpParams.Count; i++) { channels[i] = Convert.ToInt32(pumpParams[i].name.Substring(pumpParams[i].name.Length - 1, 1)); fVolumes[i] = (float)Convert.ToDouble(pumpParams[i].volume); xVals[i] = (float)lattice.lattice_X + 60f; yVals[i] = (float)lattice.lattice_X + 60f; // 液体参数 liquid = LiquidDB.GetALiquidFromdb(pumpParams[i].liquidValue); } addLiquidMParamSH.volume = fVolumes; addLiquidMParamSH.xAxisVal = xVals; addLiquidMParamSH.yAxisVal = yVals; addLiquidMParamSH.zAxisVal = (float)lattice.lattice_Z - 50f; addLiquidMParamSH.speed = (float)liquid.dispense_speed; addLiquidMParamSH.addLiquidAfterDelay = liquid.after_dispense_delay; addLiquidMParamSH.basezAxisVal = 0; launchView.SetWaitOne();//暂停 ret = pumpDispenseBll.ExecutePumpDispense(addLiquidMParamSH, isSimulator); System.Threading.Thread.Sleep(3000); //更新孔位颜色 if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseFail.ToString() + ret.AlarmInfo + " 板位 " + lattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseFail.ToString() + ret.AlarmInfo + " 板位 " + lattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: dispense of pump was failed on trash bin lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: dispense of pump was failed on trash bin lattice! Error info:" + ret.AlarmInfo); } result = false; return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseSuccess.ToString() + " 板位 " + lattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseSuccess.ToString() + " 板位 " + lattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + lattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + lattice.lattice_num + " lattice!"); } } } } else { // 获取板位孔的坐标数据 List dtWells = ControlCom.GenerateWellCoordinate(labwares, slattice); //根据循环处理孔位 TipsTable tipsTable = null; tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) && t.labware_id.Equals(strLabwareid) && t.wellname.Equals(wells[0])); tipsTable.axis_b_Z = tipsTable.axis_b_Z + ControlCom.CurrentLengthOfTip;//被减的枪头要加回来 if (armName == "泵臂") { AddLiquidMParamSH addLiquidMParamSH = new AddLiquidMParamSH(); addLiquidMParamSH.armId = Convert.ToInt32(armId); int[] channels = new int[pumpParams.Count]; float[] fVolumes = new float[pumpParams.Count]; float[] xVals = new float[pumpParams.Count]; float[] yVals = new float[pumpParams.Count]; addLiquidMParamSH.channelId = channels; addLiquidMParamSH.channelCount = pumpParams.Count; Liquid liquid = null; for (int i = 0; i < pumpParams.Count; i++) { channels[i] = Convert.ToInt32(pumpParams[i].name.Substring(pumpParams[i].name.Length - 1, 1)); fVolumes[i] = (float)Convert.ToDouble(pumpParams[i].volume); xVals[i] = (float)tipsTable.axis_b_X; yVals[i] = (float)tipsTable.axis_b_Y; // 液体参数 liquid = LiquidDB.GetALiquidFromdb(pumpParams[i].liquidValue); } addLiquidMParamSH.volume = fVolumes; addLiquidMParamSH.xAxisVal = xVals; addLiquidMParamSH.yAxisVal = yVals; addLiquidMParamSH.zAxisVal = tipsTable.axis_b_Z-(float)labwares.labware_height; addLiquidMParamSH.speed = (float)liquid.dispense_speed; addLiquidMParamSH.addLiquidAfterDelay = liquid.after_dispense_delay; addLiquidMParamSH.basezAxisVal = 0; launchView.SetWaitOne();//暂停 launchView.UpdateLabwareWells(tipsTable, wells, 2); ret = pumpDispenseBll.ExecutePumpDispense(addLiquidMParamSH, isSimulator); System.Threading.Thread.Sleep(500); //更新孔位颜色 launchView.UpdateLabwareWells(tipsTable, wells, 3); if (ret.Result != ResultType.Success) { string channelTxt = string.Join(",", channels); launchView.addDataIntoReport("泵" + channelTxt, addLiquidMParamSH.volume[0].ToString(), new string[1] { tipsTable.wellname }, "0");//来源泵 launchView.addFinishDataIntoReport(tipsTable, slattice.lattice_num, addLiquidMParamSH.volume[0].ToString(), new string[1] { tipsTable.wellname }, "0", new string[1] { "" });//目标孔 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseFail.ToString() + ret.AlarmInfo + " 孔 " + tipsTable.wellname + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseFail.ToString() + ret.AlarmInfo + " 孔 " + tipsTable.wellname + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + tipsTable.wellname + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + tipsTable.wellname + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; return result; } else { string channelTxt = string.Join(",", channels); launchView.addDataIntoReport("泵" + channelTxt, addLiquidMParamSH.volume[0].ToString(), new string[1] { tipsTable.wellname }, "1");//来源泵 launchView.addFinishDataIntoReport(tipsTable, slattice.lattice_num, addLiquidMParamSH.volume[0].ToString(), new string[1] { tipsTable.wellname }, "1", new string[1] { "" });//目标孔 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseSuccess.ToString() + " 孔 " + tipsTable.wellname + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunDispenseResource.strDispenseSuccess.ToString() + " 孔 " + tipsTable.wellname + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + tipsTable.wellname + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + tipsTable.wellname + " of " + slattice.lattice_num + " lattice!"); } } } } } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strError.ToString() + " 源 " + ex.Source + " 错误信息 " + ex.Message + ";"); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】error:source:" + ex.Source + ";error:" + ex.Message + ";"); } result = false; } #endregion return result; } #endregion } }