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.Controls.Run.Com;
|
using XHandler.View;
|
using XHandler.View.MethodProperty;
|
using XImaging.Automation.Service.Interface;
|
using XImagingXhandler.XDAL;
|
using static HxEnum.OtherEnum;
|
|
namespace XHandler.Controls
|
{
|
/// <summary>
|
/// 涂布转板控制逻辑类
|
/// </summary>
|
public class CoatingTransferControl
|
{
|
#region 变量
|
// 系统语言
|
private string m_currentCulture = string.Empty;
|
private WellCalc wellCalc = new WellCalc();
|
|
#region 涂布用变量
|
public static MethodCoatingAndTransfer CoatingData = null;
|
|
// 当前孔在所有有效孔中的排序
|
private static int m_curValidWellIndex = -1;
|
// 全部有效孔位list:A1、B1、C1
|
private static List<string> m_lstAllValidWells = new List<string>();
|
// 涂布台面位置
|
private static string m_coatingLatticeName = string.Empty;
|
// 涂布板位lattice_id
|
private static int m_latticeid = -1;
|
// 涂布耗材条码
|
private static string m_coatingLabwareBarcode = string.Empty;
|
// 当前涂布板位的台面信息
|
private static XmlNode m_curCoatingLabNode = null;
|
// 当前涂布的孔位:A1
|
private static string m_curValidWell = string.Empty;
|
// 剩余有效孔位list:B1、C1
|
private static List<string> m_lstResidueValidWells = new List<string>();
|
// 主z轴默认安全坐标点距
|
private static float m_zAxisSafeVal = 0;
|
#endregion
|
|
#region BLL
|
private static CoatingBll coatingBll = new CoatingBll();
|
private BacteriaBll bacteriaBll = new BacteriaBll();
|
#endregion
|
|
// 运行界面
|
public static RunWnd LaunchView = null;
|
public HxSocketClient socketTcpClientToRemote = null;
|
#endregion
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public CoatingTransferControl()
|
{
|
m_currentCulture = Shared.SoftwareInformation.currentculture;
|
}
|
|
#region 执行涂布转板
|
/// <summary>
|
/// 执行涂布转板
|
/// </summary>
|
/// <param name="xmlEnv"></param>
|
/// <param name="methodNode"></param>
|
/// <param name="isSimulator"></param>
|
/// <returns>0:异常结束, 1:正常继续(跳出for),2:正常结束</returns>
|
public int ExecuteCoatingTransfer(XmlNode xmlEnv, XmlNode methodNode, bool isSimulator)
|
{
|
int nResult = 2;
|
var platformNodeList = xmlEnv.SelectNodes("platform");
|
string strMethodName = methodNode.SelectSingleNode("name").InnerText;
|
|
#region 任务被取消
|
if (LaunchView._cancelSource.IsCancellationRequested)
|
{
|
nResult = 0;
|
return nResult;
|
}
|
#endregion
|
|
#region RunLog start
|
if (m_currentCulture.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:");
|
}
|
#endregion
|
|
try
|
{
|
#region 数据准备
|
// 获取涂布信息
|
if (!GetInfo(methodNode, xmlEnv, isSimulator))
|
{
|
nResult = 0;
|
return nResult;
|
}
|
#endregion
|
|
// 涂布板位的开盖 => 挑选节点已经执行
|
#region 涂布
|
// 获取板位坐标
|
Lattice latticeDes = LatticeDB.GetLatticeDataByIdFromdb(m_latticeid.ToString());
|
// 获取耗材信息
|
Labware labwareDes = LabwareDB.GetLabware(CoatingData.coatingLabwareAValue);
|
// 获取板位孔的坐标数据
|
List<TipsTable> lstTipsTable = ControlCom.GenerateWellCoordinate(labwareDes, latticeDes);
|
|
// 获取耗材上指定孔位的坐标
|
TipsTable targetWellInfo = lstTipsTable.SingleOrDefault(t => t.lattice_id.Equals(m_latticeid.ToString())
|
&& t.labware_id.Equals(CoatingData.coatingLabwareAValue)
|
&& t.wellname.Equals(m_curValidWell));
|
|
#region 涂布方式 1:回字型 2:Z字型;3:上下移动
|
if (CoatingData.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.HuiziMode) ||
|
CoatingData.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.ZMode) ||
|
CoatingData.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.UpDownMode))
|
{
|
#region 涂布
|
CoatingMParam coatingMParam = new CoatingMParam();
|
coatingMParam.xAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_X.ToString());
|
coatingMParam.yAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_Y.ToString());
|
coatingMParam.armId = Convert.ToInt32(CoatingData.armValue);
|
coatingMParam.channelId = 1;
|
float zVal = targetWellInfo.axis_b_Z;
|
if (ChoiceTransferControl.BacteriaInfo != null)
|
{
|
// 涂布距离底部距离
|
zVal = zVal - float.Parse(ChoiceTransferControl.BacteriaInfo.coating_position_distance.ToString());
|
}
|
coatingMParam.zAxisVal = zVal < 0 ? 0 : zVal; // 涂布主z轴移动坐标点距
|
coatingMParam.zChAxisVal = coatingMParam.zAxisVal;
|
coatingMParam.coatingShape = CoatingData.coatingModeValue; // 涂布形状:1:回形;2:Z形;3:上下
|
// 涂布范围值:如果是圆形孔值为半径;如是方形孔值为边长一半
|
coatingMParam.rangeVal = labwareDes.well_shape == 1 ?
|
((float)labwareDes.well_mouth_radius) : ((float)(labwareDes.well_top_x / 2.0d));
|
coatingMParam.basezAxisVal = m_zAxisSafeVal; // 主z轴默认安全坐标点距
|
coatingMParam.coatingSpeed = float.Parse(ConfigurationManager.AppSettings["coatingSpeed"].ToString()); // 涂布电机速度
|
coatingMParam.coatingTipsOutWidth = ControlCom.OutWidthOfTip; // 涂布枪头头部外宽度
|
coatingMParam.coatingTipsInWidth = ControlCom.InWidthOfTip; // 涂布枪头头部内宽度
|
coatingMParam.enableSupersonic = 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.latticeName = m_coatingLatticeName;
|
|
// 上下移动
|
if (coatingMParam.coatingShape == EnumManagement.GetEnumValue(CoatingModeEnum.UpDownMode))
|
{
|
coatingMParam.zAxisVal -= CoatingData.distanceFromBottom;
|
coatingMParam.zAxisOffsetVal = CoatingData.shakeDistanceValue;
|
coatingMParam.zAxisOffsetCount = CoatingData.shakeCountValue;
|
}
|
|
// 执行涂布动作
|
bool bIsOk = ControlCom.RunCoating(LaunchView, strMethodName, coatingMParam, targetWellInfo, m_curValidWell,
|
m_coatingLatticeName, m_coatingLabwareBarcode, isSimulator);
|
if (!bIsOk)
|
{
|
return 0;
|
}
|
#endregion
|
}
|
#endregion
|
|
#region 涂布方式 5:放液
|
else if (CoatingData.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.DispenseMode))
|
{
|
if (ChoiceTransferControl.ChoiceData == null)
|
{
|
LoggerRunHelper.ErrorLog(string.Format("[ExecuteCoatingTransfer]: ChoiceTransferControl.ChoiceData = null !!!"));
|
return 0;
|
}
|
|
// 放液
|
bool bDispense = ControlCom.DoDispense(LaunchView, strMethodName, ChoiceTransferControl.ChoiceData.choiceAgoAspirateData,
|
labwareDes, latticeDes, targetWellInfo, m_coatingLabwareBarcode, isSimulator);
|
if (!bDispense)
|
{
|
return 0;
|
}
|
}
|
#endregion
|
|
#endregion
|
|
#region 卸载Tip,丢在垃圾桶
|
UnloadTipsControl unloadTipsControl = new UnloadTipsControl(Shared.SoftwareInformation.currentculture);
|
unloadTipsControl.launchView = LaunchView;
|
unloadTipsControl.socketTcpClientToRemote = socketTcpClientToRemote;
|
bool bUnloadResult = unloadTipsControl.ExecuteUnloadTipsInToTrash(platformNodeList, methodNode, isSimulator);
|
LaunchView.currentIsLoadingTips = false;
|
#endregion
|
|
#region 自动关盖
|
// 获取挑菌类型所有效的孔
|
ResidueValidWells residueValidWells = ChoiceTransferControl.GetResidueValidWells();
|
bool isForceCloseClover = residueValidWells == null ? true : false;
|
|
// 自动关闭挑选板盖
|
bool bResult = ChoiceTransferControl.CloseClover(xmlEnv, isSimulator, isForceCloseClover);
|
if (!bResult)
|
{
|
return 0;
|
}
|
|
// 自动关闭涂布板盖
|
bResult = CloseClover(xmlEnv, isSimulator, isForceCloseClover);
|
if (!bResult)
|
{
|
return 0;
|
}
|
#endregion
|
|
// 删除当前涂布孔位
|
m_lstResidueValidWells.RemoveAt(0);
|
// 更新剩余有效孔位
|
m_curCoatingLabNode.SelectSingleNode("residueValidWells").InnerText = string.Join(",", m_lstResidueValidWells);
|
}
|
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 + ";");
|
nResult = 0;
|
|
#region Del
|
//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
|
#endregion
|
}
|
|
return nResult;
|
}
|
#endregion
|
|
#region 自动开挑选板盖
|
/// <summary>
|
/// 自动开挑选板盖
|
/// </summary>
|
/// <param name="xmlEnv"></param>
|
/// <param name="methodNode"></param>
|
/// <param name="isSimulator"></param>
|
/// <returns></returns>
|
public static bool OpenClover(XmlNode xmlEnv, XmlNode methodNode, bool isSimulator)
|
{
|
bool bResult = true;
|
|
// 获取涂布信息
|
if (!GetInfo(methodNode, xmlEnv, isSimulator))
|
{
|
bResult = false;
|
return bResult;
|
}
|
|
// 自动开盖: 当前孔是第一个有效孔
|
if (CoatingData != null &&
|
CoatingData.autoOpenCloseCover == 1 &&
|
m_curValidWellIndex == 0)
|
{
|
// 挑菌的板放盖位号:P2,P3
|
List<string> listCoatingCoverLatticeId = ComUtility.GetPlateCoverLatticeName();
|
|
// 转移板盖到放盖位方法
|
string strTransferPlateCoverMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
|
"\\" + ConfigurationManager.AppSettings["transferDesPlateCoverMethod"].ToString();
|
|
// 转移目标板的盖到放盖位:P13->P3
|
bResult = ControlCom.DoReadMethodFileAndActionTransfer(strTransferPlateCoverMethodFileName, xmlEnv, m_coatingLatticeName, PositonTypeEnum.Desktop, GripperModelEnum.Right,
|
listCoatingCoverLatticeId[1], PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, LaunchView, TransferTypeEnum.Open);
|
return bResult;
|
}
|
|
return bResult;
|
}
|
|
/// <summary>
|
/// 自动关挑选板盖
|
/// </summary>
|
/// <param name="xmlEnv"></param>
|
/// <param name="isSimulator"></param>
|
/// <param name="isForceCloseClover">是否强制关盖</param>
|
/// <returns></returns>
|
public static bool CloseClover(XmlNode xmlEnv, bool isSimulator, bool isForceCloseClover = false)
|
{
|
bool bResult = true;
|
|
// 自动关盖: 当前孔是第最后一个有效孔
|
if (CoatingData != null &&
|
CoatingData.autoOpenCloseCover == 1 &&
|
((m_curValidWellIndex == m_lstAllValidWells.Count() - 1) || isForceCloseClover))
|
{
|
// 挑菌的板放盖位号:P2,P3
|
List<string> listCoatingCoverLatticeId = ComUtility.GetPlateCoverLatticeName();
|
// 转移板盖到放盖位方法
|
string strTransferPlateCoverMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
|
"\\" + ConfigurationManager.AppSettings["transferDesPlateCoverMethod"].ToString();
|
|
// 转移目标板的盖到板上:P2->P10
|
bResult = ControlCom.DoReadMethodFileAndActionTransfer(strTransferPlateCoverMethodFileName, xmlEnv, listCoatingCoverLatticeId[1], PositonTypeEnum.Desktop, GripperModelEnum.Right,
|
m_coatingLatticeName, PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, LaunchView, TransferTypeEnum.Close);
|
return bResult;
|
}
|
|
return bResult;
|
}
|
#endregion
|
|
/// <summary>
|
/// 获取涂布信息
|
/// </summary>
|
/// <param name="methodNode"></param>
|
/// <param name="xmlEnv"></param>
|
/// <param name="isSimulator"></param>
|
/// <returns></returns>
|
private static bool GetInfo(XmlNode methodNode, XmlNode xmlEnv, bool isSimulator)
|
{
|
#region 数据准备1
|
// 获取涂布转移数据
|
CoatingData = coatingBll.GenerateMethodCoatingAndTransferDataByXmlNode(methodNode);
|
m_curCoatingLabNode = null; // 当前涂布板位的台面信息
|
m_curValidWell = string.Empty; // 当前涂布的孔位:A1
|
m_lstResidueValidWells = new List<string>(); // 剩余有效孔位list:B1、C1
|
m_coatingLatticeName = string.Empty; // 涂布台面位置
|
m_coatingLabwareBarcode = string.Empty; // 涂布耗材条码
|
|
// Z轴安全位置
|
m_zAxisSafeVal = (float)Convert.ToDouble(ConfigurationManager.AppSettings["zAxisSafeVal"]);
|
|
LoggerHelper.InfoLog($"[CoatingTransferControl]:Args: { JsonConvert.SerializeObject(CoatingData) }");
|
#endregion
|
|
#region 获取涂布类型所有效的孔
|
// 生成和涂布耗材类型一致的条件
|
string strCoatingLabwareWhere = string.Format("platform[labware_id='{0}']", CoatingData.coatingLabwareAValue);
|
// 获取满足涂布耗材类型的所有台面点位
|
XmlNodeList coatingLabwareNodeList = xmlEnv.SelectNodes(strCoatingLabwareWhere);
|
|
// 循环台面耗材点位,查找涂布耗材剩余量
|
#region 补充耗材数据准备
|
DataTable dtCoatingFile = new DataTable();
|
dtCoatingFile.Columns.Add("TargetB", typeof(string));
|
dtCoatingFile.Columns.Add("TargetBarcode", typeof(string));
|
dtCoatingFile.Columns.Add("IsNewPlateBatch", typeof(string));
|
#endregion
|
|
foreach (XmlNode coatingLabNode in coatingLabwareNodeList)
|
{
|
#region 补充耗材数据准备
|
DataRow dtRow = dtCoatingFile.NewRow();
|
dtRow["TargetB"] = coatingLabNode.SelectSingleNode("labware_sname").InnerText;
|
dtRow["TargetBarcode"] = "";
|
dtRow["IsNewPlateBatch"] = "false";
|
dtCoatingFile.Rows.Add(dtRow);
|
#endregion
|
|
string residueValidWells = coatingLabNode.SelectSingleNode("residueValidWells").InnerText;
|
|
// 有效孔字符串转换成List
|
m_lstResidueValidWells = ComUtility.GetValidWells(residueValidWells);
|
if (m_lstResidueValidWells.Count == 0)
|
{
|
continue;
|
}
|
|
m_curCoatingLabNode = coatingLabNode;
|
break;
|
}
|
|
// 涂布无剩余有效的孔,显示补充耗材提示
|
if (m_lstResidueValidWells.Count == 0)
|
{
|
// 状态6 报错/急停 红闪/蜂鸣5S
|
CommonBll.StatusLamp(6, isSimulator);
|
|
SetBarcodeDlgForAddConsumables setBarcodeDlg = null;
|
bool bIsBreak = false;
|
Application.Current.Dispatcher.Invoke(new Action(() =>
|
{
|
#region 条码赋值
|
string strMsg = string.Format(Properties.CoatingResource.strNoValidConsumables, Environment.NewLine);
|
setBarcodeDlg = new SetBarcodeDlgForAddConsumables(strMsg);
|
setBarcodeDlg.launchView = LaunchView;
|
setBarcodeDlg.dtCoatingFile = dtCoatingFile;
|
|
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 (XmlNode choiceLabwareNode in coatingLabwareNodeList)
|
{
|
string labwareNameUpdate = choiceLabwareNode.SelectSingleNode("labware_sname").InnerText;
|
DataRow[] selRowUpdate = dtCoatingFile.Select(string.Format("TargetB = '{0}'", labwareNameUpdate));
|
if (selRowUpdate != null)
|
{
|
string targetBarcode = selRowUpdate[0]["TargetBarcode"].ToString();
|
choiceLabwareNode.SelectSingleNode("labware_barcode").InnerText = targetBarcode;
|
}
|
// 更新已使用的涂布目标孔的颜色
|
ControlCom.UpdateDesPlateWellsColor(xmlEnv, choiceLabwareNode.SelectSingleNode("labware_sname").InnerText, LaunchView);
|
}
|
|
// 继续执行
|
|
// 状态4 运行 绿色
|
CommonBll.StatusLamp(4, isSimulator);
|
}
|
else
|
{
|
bIsBreak = true;
|
}
|
#endregion
|
}));
|
|
if (bIsBreak)
|
{
|
return false;
|
}
|
|
return GetInfo(methodNode, xmlEnv, isSimulator);
|
}
|
#endregion
|
|
#region 数据准备2
|
// 全部有效孔list
|
string allValidWells = m_curCoatingLabNode.SelectSingleNode("allValidWells").InnerText;
|
m_lstAllValidWells = ComUtility.GetValidWells(allValidWells);
|
// 当前涂布的孔位
|
m_curValidWell = m_lstResidueValidWells[0];
|
// 当前孔在所有有效孔中的排序
|
m_curValidWellIndex = m_lstAllValidWells.IndexOf(m_curValidWell);
|
// 涂布板位:P13
|
m_coatingLatticeName = m_curCoatingLabNode.SelectSingleNode("labware_sname").InnerText;
|
// 涂布耗材条码
|
m_coatingLabwareBarcode = m_curCoatingLabNode.SelectSingleNode("labware_barcode").InnerText;
|
// 涂布板位lattice_id
|
m_latticeid = ControlCom.GetLatticeId(Convert.ToInt32(m_curCoatingLabNode.SelectSingleNode("lattice_id").InnerText));
|
#endregion
|
|
return true;
|
}
|
}
|
}
|