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
{
///
/// 涂布转板控制逻辑类
///
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 m_lstAllValidWells = new List();
// 涂布台面位置
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 m_lstResidueValidWells = new List();
// 主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
///
/// 构造函数
///
public CoatingTransferControl()
{
m_currentCulture = Shared.SoftwareInformation.currentculture;
}
#region 执行涂布转板
///
/// 执行涂布转板
///
///
///
///
/// 0:异常结束, 1:正常继续(跳出for),2:正常结束
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 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 自动开挑选板盖
///
/// 自动开挑选板盖
///
///
///
///
///
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 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;
}
///
/// 自动关挑选板盖
///
///
///
/// 是否强制关盖
///
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 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
///
/// 获取涂布信息
///
///
///
///
///
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(); // 剩余有效孔位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;
}
}
}