using NX_CommonClassLibrary; using NX_LogClassLibrary; using NX_ModelClassLibrary.BaseModel; using NX_ModelClassLibrary.Common; using NX_ModelClassLibrary.CrnModel; using NX_ModelClassLibrary.CustomEnum; using NX_ModelClassLibrary.CustomEvent; using NX_ModelClassLibrary.OpcModel; using NX_ModelClassLibrary.WmsTask; using NX_OpcUaClientLibrary; using NX_WcsBiz.CommonBusiness; using NX_WcsBiz.WcsDispatch; using NX_WcsDal.CommonBusiness; using NX_WcsDal.WcsBusiness; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace NX_WcsBiz.WcsBusiness { public class Crn_Biz { #region 单例模式 /// /// 单例模式对象 /// private static Crn_Biz _instance = null; private static readonly object lockObj = new object(); /// /// 单例模式方法 /// public static Crn_Biz Instance { get { if (_instance == null) { lock (lockObj) { if (_instance == null) { _instance = new Crn_Biz(); } } } return _instance; } } #endregion #region 全局变量 /// /// 堆垛机设备所属PLC信息列表 /// public List crnBasPlcMdList; /// /// 堆垛机设备列表 /// public List crnDevList; /// /// 堆垛机设备类型 /// public BasWcsDevTypeMd crnDevTypeMd; /// /// 堆垛机当前作业指令集合信息。 /// public Hashtable CurrentWorkingCmdList; /// /// 堆垛机当前作业指令状态集合信息。 /// public Hashtable CrnCurrentWorkingStatusList; /// /// 日志显示帮助类对象 /// public ShowLogToFrmHelper showLogToFrm = new ShowLogToFrmHelper(); /// /// 日志头部 /// private readonly string LogHeadText = "堆垛机业务类 ==>> "; #endregion #region 堆垛机主业务 /// /// 初始化堆垛机业务类 /// /// public bool Init() { try { crnDevTypeMd = BasCommon_Biz.Instance.basWcsDevTypeMdList.FirstOrDefault(x => x.DevTypeCode == "CrnType"); crnDevList = BasCommon_Biz.Instance.basWcsDevMdList.FindAll(x => x.DevTypeCode == crnDevTypeMd.DevTypeCode); crnBasPlcMdList = new List(); CurrentWorkingCmdList = Hashtable.Synchronized(new Hashtable()); CrnCurrentWorkingStatusList = Hashtable.Synchronized(new Hashtable()); foreach (BasWcsDevMd item in crnDevList) { BasWcsPlcMd tmpMd = crnBasPlcMdList.FirstOrDefault(x => x.PlcCode == item.DevPlcNo); if (tmpMd != null) { crnBasPlcMdList.Add(tmpMd); } CurrentWorkingCmdList.Add(item, new WcsCrnCmdMd()); CrnCurrentWorkingStatusList.Add(item, CrnDevWorkStatusEnumExt.待机); } ShowLogToForm($"初始化堆垛机业务类成功!", true, LogTypeEnum.Run); return true; } catch (Exception ex) { ShowLogToForm($"初始化堆垛机业务类发生异常!【{ex.Message}】", true, LogTypeEnum.Err); return false; } } /// /// 堆垛机主业务函数 /// /// public void CrnMainBizRunFunc(BasWcsDevMd basWcsDevMd) { try { WcsCrnCmdMd currTmpCmd = CurrentWorkingCmdList[basWcsDevMd] == null ? null : (WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd]; if (currTmpCmd == null || currTmpCmd.CrnCmdId == 0) { //加载当前堆垛机未完成指令 currTmpCmd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, true, null); } if (currTmpCmd == null || currTmpCmd.CrnCmdId == 0) { //加载空闲指令 //currTmpCmd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); //if (currTmpCmd != null && currTmpCmd.CrnCmdId > 0) //{ // ShowLogToForm(GetCrnBizRunLog("堆垛机加载空闲指令数据成功!", currTmpCmd), true, LogTypeEnum.Run); //} currTmpCmd = CrnCmdDynamicHandle(basWcsDevMd); } if (currTmpCmd != null && currTmpCmd.CmdNo > 0) { if (!CurrentWorkingCmdList.ContainsValue(currTmpCmd)) { CurrentWorkingCmdList[basWcsDevMd] = currTmpCmd; } CurrPlcProtocolEnum plcProtocolEnum = EnumExtensionHelper.GetEnumObj(AppConfigHelper.Get("CurrPlcProtocol")); switch (plcProtocolEnum) { case CurrPlcProtocolEnum.第一版: switch (currTmpCmd.CmdStatus) { case CrnCmdStatusEnum.初始创建: SendPlcCrnCmd((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; case CrnCmdStatusEnum.已下发PLC: UpdateCurrCrnCmdWorking((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; case CrnCmdStatusEnum.执行中: FinishCurrCrnCmd((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; default: break; } break; case CurrPlcProtocolEnum.第二版: currTmpCmd = DoubleBinMoveTaskHandle(currTmpCmd); switch (currTmpCmd.CmdStatus) { case CrnCmdStatusEnum.初始创建: SendPlcCrnCmd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; case CrnCmdStatusEnum.已下发PLC: UpdateCurrCrnCmdWorkingd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; case CrnCmdStatusEnum.执行中: FinishCurrCrnCmd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd); break; default: break; } break; case CurrPlcProtocolEnum.第三版: break; default: break; } } } catch (Exception ex) { ShowLogToForm($"堆垛机主业务函数运行发生异常!【{ex.Message}】", true, LogTypeEnum.Err); } } #region 第一版PLC交互协议的控制逻辑 /// /// 下发堆垛机PLC指令信息 /// /// 堆垛机指令对象 /// 堆垛机基础信息对象 private void SendPlcCrnCmd(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); WcsOpcItemMd ForkOriginSignalOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOriginSignal"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0"); bool ForkOriginSignal = Convert.ToBoolean(ForkOriginSignalOpcItemMd.OpcItemValue ?? "False"); if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnum.待机 && AlarmNo == 0 && ForkOriginSignal) { #region 下发PLC指令 WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd"); WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo"); WcsOpcItemMd WCS_S_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkRowNo"); WcsOpcItemMd WCS_S_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkColNo"); WcsOpcItemMd WCS_S_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkLayerNo"); WcsOpcItemMd WCS_E_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkRowNo"); WcsOpcItemMd WCS_E_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkColNo"); WcsOpcItemMd WCS_E_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkLayerNo"); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkRowNo, wcsCrnCmdMd.SbinRow)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业排数据:【{wcsCrnCmdMd.SbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkColNo, wcsCrnCmdMd.SbinCol)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业列数据:【{wcsCrnCmdMd.SbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkLayerNo, wcsCrnCmdMd.SbinLayer)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkRowNo, wcsCrnCmdMd.EbinRow)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkColNo, wcsCrnCmdMd.EbinCol)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkLayerNo, wcsCrnCmdMd.EbinLayer)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnum.取放货)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnum.取放货}-{(int)WcsWriteCrnCmdTypeEnum.取放货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.已下发PLC; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnum.取放货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run); } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnum.取放货}-{(int)WcsWriteCrnCmdTypeEnum.取放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC起始作业列数据:【{wcsCrnCmdMd.SbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业排数据:【{wcsCrnCmdMd.SbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } #endregion } } /// /// 更新堆垛机指令作业中数据 /// /// 堆垛机指令对象 /// 堆垛机基础信息对象 private void UpdateCurrCrnCmdWorking(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0"); if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnum.运行中 && AlarmNo == 0) { wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.执行中; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令状态更新为执行中!", wcsCrnCmdMd), true, LogTypeEnum.Run); } } /// /// 堆垛机指令完成函数 /// /// 堆垛机指令对象 /// 堆垛机基础信息对象 private void FinishCurrCrnCmd(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); WcsOpcItemMd ForkOriginSignalOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOriginSignal"); WcsOpcItemMd TaskNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "TaskNo"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0"); bool ForkOriginSignal = Convert.ToBoolean(ForkOriginSignalOpcItemMd.OpcItemValue ?? "False"); int TaskNo = Convert.ToInt32(TaskNoOpcItemMd.OpcItemValue ?? "0"); if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnum.放货完成 && AlarmNo == 0 && ForkOriginSignal && TaskNo == wcsCrnCmdMd.CmdNo) { #region 下发PLC确认收到放货完成信号 WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd"); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC 确认收到取放货任务完成数据:【{WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}-{(int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.完成; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); if (Convert.ToInt32(AppConfigHelper.Get("CrnAutoTest")) == 0) { #region 调用任务反馈,完成堆垛机指令。生成下一步的数据。 //调用任务反馈,完成堆垛机指令。生成下一步的数据。 BasBinMd eBinMd = Crn_Dal.Instance.GetBinMdOfCode(wcsCrnCmdMd.EbinNo); BasWcsLocMd eLocMd; if (eBinMd.BinType == BasBinTypeEnum.出库口) { eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc" && x.RegionCode == wcsCrnCmdMd.RegionCode && x.LocBinExtMsg == eBinMd.BinCode); } else { eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc" && x.LocBinExtMsg == wcsCrnCmdMd.RegionCode); } DispUntilityReturnMd retmd = TaskResponse_Disp.Instance.TaskResponseHandleFunc(new TaskResponseMd { TrayCode = wcsCrnCmdMd.TrayCode, PalletCode = wcsCrnCmdMd.PalletCode, TaskNo = wcsCrnCmdMd.TaskNo, CmdNo = wcsCrnCmdMd.CmdNo, CurrentLocNo = eLocMd.LocCode, TaskResponseType = DispatchResponseHandleTypeEnum.堆垛机指令反馈完成 }); if (retmd.IsSuccess) { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束成功!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Run); CurrentWorkingCmdList[basWcsDevMd] = null; } else { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束失败!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Err); } #endregion } else { CurrentWorkingCmdList[basWcsDevMd] = null; //插入一条新的空闲堆垛机指令 Crn_Dal.Instance.InsertTestCrnCmd(basWcsDevMd.DevCode); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC 确认收到取放货任务完成数据:【{WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}-{(int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } #endregion } } #endregion 第一版PLC交互协议的控制逻辑 #region 第二版PLC交互协议的控制逻辑 private WcsCrnCmdMd DoubleBinMoveTaskHandle(WcsCrnCmdMd wcsCrnCmdMd) { if (wcsCrnCmdMd.CmdType == CrnCmdTypeEnum.IN && wcsCrnCmdMd.EExtensionIdx == 2) { WmsBalanceMd balanceMd = Crn_Dal.Instance.GetIntroversionBinBalanceMd(wcsCrnCmdMd.EExtensionGroup, wcsCrnCmdMd.EExtensionIdx - 1, wcsCrnCmdMd.RegionCode); if (balanceMd != null) { WmsTskTaskMd tskTaskMd = Crn_Dal.Instance.GetIntroversionBinMoveWmsTaskMd(balanceMd); if (tskTaskMd != null) { return null; } else { BasWcsLocMd RegiongLocNo = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc"); BasRegionMd regionMd = Crn_Dal.Instance.GetRegionMd(wcsCrnCmdMd.RegionCode); BasBinMd CurrBinMd = Crn_Dal.Instance.GetBinMdOfCode(balanceMd.BinCode); List DistributableShelfLst = BasCommon_Biz.Instance.GetCrnRelationShelfLst(CurrBinMd); BasBinMd emptyBin = BasCommon_Biz.Instance.GetDoubleExtensionEmptyBinMd(regionMd.RegionCode, DistributableShelfLst, balanceMd.TrayCode); Crn_Dal.Instance.InsertIntroversionBinMoveWmsTask(RegiongLocNo, regionMd, balanceMd, emptyBin); return null; } } } if (wcsCrnCmdMd.CmdType == CrnCmdTypeEnum.OUT && wcsCrnCmdMd.SExtensionIdx == 2) { WmsBalanceMd balanceMd = Crn_Dal.Instance.GetIntroversionBinBalanceMd(wcsCrnCmdMd.SExtensionGroup, wcsCrnCmdMd.SExtensionIdx - 1, wcsCrnCmdMd.RegionCode); if (balanceMd != null) { WmsTskTaskMd tskTaskMd = Crn_Dal.Instance.GetIntroversionBinMoveWmsTaskMd(balanceMd); if (tskTaskMd != null) { return null; } else { BasWcsLocMd RegiongLocNo = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc"); BasRegionMd regionMd = Crn_Dal.Instance.GetRegionMd(wcsCrnCmdMd.RegionCode); BasBinMd CurrBinMd = Crn_Dal.Instance.GetBinMdOfCode(balanceMd.BinCode); List DistributableShelfLst = BasCommon_Biz.Instance.GetCrnRelationShelfLst(CurrBinMd); BasBinMd emptyBin = BasCommon_Biz.Instance.GetDoubleExtensionEmptyBinMd(regionMd.RegionCode, DistributableShelfLst, balanceMd.TrayCode); Crn_Dal.Instance.InsertIntroversionBinMoveWmsTask(RegiongLocNo, regionMd, balanceMd, emptyBin); return null; } } } return wcsCrnCmdMd; } private void SendPlcCrnCmd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); WcsOpcItemMd LevelStopAccuracyOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "LevelStopAccuracy"); WcsOpcItemMd ForkOriginOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOrigin"); WcsOpcItemMd ForkStaticStatusOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkStaticStatus"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0"); bool ForkOriginSignal = Convert.ToBoolean(ForkOriginOpcItemMd.OpcItemValue ?? "False"); bool LevelStopAccuracySignal = Convert.ToBoolean(LevelStopAccuracyOpcItemMd.OpcItemValue ?? "False"); bool ForkStaticStatusSignal = Convert.ToBoolean(ForkStaticStatusOpcItemMd.OpcItemValue ?? "False"); //联机自动 待机 无报警 货叉原位 水平停准 货叉静止 if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnumExt.待机 && AlarmNo == 0 && ForkOriginSignal && LevelStopAccuracySignal && ForkStaticStatusSignal) { #region 下发PLC指令 WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd"); WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo"); WcsOpcItemMd WCS_PalletCode = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_PalletCode"); WcsOpcItemMd WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkRowNo"); WcsOpcItemMd WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkColNo"); WcsOpcItemMd WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkLayerNo"); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.SbinRow)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.SbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.SbinCol)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.SbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.SbinLayer)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode)) { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.取货)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.取货}-{(int)WcsWriteCrnCmdTypeEnumExt.取货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.已下发PLC; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.取货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run); } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.取货}-{(int)WcsWriteCrnCmdTypeEnumExt.取货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.SbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.SbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.SbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } #endregion } } private void UpdateCurrCrnCmdWorkingd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0"); if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnumExt.取货中 && AlarmNo == 0) { wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.执行中; CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.取货中; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令状态更新为执行中!", wcsCrnCmdMd), true, LogTypeEnum.Run); } } private void FinishCurrCrnCmd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd) { WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel"); WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus"); WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo"); WcsOpcItemMd LevelStopAccuracyOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "LevelStopAccuracy"); WcsOpcItemMd ForkOriginOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOrigin"); WcsOpcItemMd ForkStaticStatusOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkStaticStatus"); CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj(WorkModelOpcItemMd.OpcItemValue); CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj(WorkStatuslOpcItemMd.OpcItemValue); int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0"); bool ForkOriginSignal = Convert.ToBoolean(ForkOriginOpcItemMd.OpcItemValue ?? "False"); bool LevelStopAccuracySignal = Convert.ToBoolean(LevelStopAccuracyOpcItemMd.OpcItemValue ?? "False"); bool ForkStaticStatusSignal = Convert.ToBoolean(ForkStaticStatusOpcItemMd.OpcItemValue ?? "False"); WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd"); WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo"); WcsOpcItemMd WCS_PalletCode = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_PalletCode"); WcsOpcItemMd WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkRowNo"); WcsOpcItemMd WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkColNo"); WcsOpcItemMd WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkLayerNo"); CrnDevWorkStatusEnumExt currCrnWorkStatus = (CrnDevWorkStatusEnumExt)CrnCurrentWorkingStatusList[basWcsDevMd]; switch (currCrnWorkStatus) { case CrnDevWorkStatusEnumExt.取货中: //联机自动 取货完成 无报警 货叉原位 水平停准 货叉静止 if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnumExt.取货完成 && AlarmNo == 0 && ForkOriginSignal && LevelStopAccuracySignal && ForkStaticStatusSignal) { if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.EbinRow)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.EbinCol)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.EbinLayer)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode)) { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.放货)) { CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.放货中; ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.放货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run); } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } break; case CrnDevWorkStatusEnumExt.放货中: //联机自动 放货完成 无报警 货叉原位 水平停准 货叉静止 if (WorkModel == CrnDevWorkModeEnum.联机自动 && WorkStatus == CrnDevWorkStatusEnumExt.放货完成 && AlarmNo == 0 && ForkOriginSignal && LevelStopAccuracySignal && ForkStaticStatusSignal) { if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.EbinRow)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.EbinCol)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.EbinLayer)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo)) { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode)) { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.确认收到放货完成)) { CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.放货完成; ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}-{(int)WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run); } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun); } } break; case CrnDevWorkStatusEnumExt.放货完成: wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.完成; //更新数据库指令状态信息 Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd); if (Convert.ToInt32(AppConfigHelper.Get("CrnAutoTest")) == 0) { #region 调用任务反馈,完成堆垛机指令。生成下一步的数据。 //调用任务反馈,完成堆垛机指令。生成下一步的数据。 BasBinMd eBinMd = Crn_Dal.Instance.GetBinMdOfCode(wcsCrnCmdMd.EbinNo); BasWcsLocMd eLocMd; if (eBinMd.BinType == BasBinTypeEnum.出库口) { eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc" && x.RegionCode == wcsCrnCmdMd.RegionCode && x.LocBinExtMsg == eBinMd.BinCode); } else { eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc" && x.LocBinExtMsg == wcsCrnCmdMd.RegionCode); } DispUntilityReturnMd retmd = TaskResponse_Disp.Instance.TaskResponseHandleFunc(new TaskResponseMd { TrayCode = wcsCrnCmdMd.TrayCode, PalletCode = wcsCrnCmdMd.PalletCode, TaskNo = wcsCrnCmdMd.TaskNo, CmdNo = wcsCrnCmdMd.CmdNo, CurrentLocNo = eLocMd.LocCode, TaskResponseType = DispatchResponseHandleTypeEnum.堆垛机指令反馈完成 }); if (retmd.IsSuccess) { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束成功!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Run); CurrentWorkingCmdList[basWcsDevMd] = null; CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.待机; } else { ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束失败!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Err); } #endregion } else { CurrentWorkingCmdList[basWcsDevMd] = null; CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.待机; //插入一条新的空闲堆垛机指令 Crn_Dal.Instance.InsertTestCrnCmd(basWcsDevMd.DevCode); } break; default: break; } } #endregion 第二版PLC交互协议的控制逻辑 /// /// 获取出库口输送线有货状态 /// /// private bool GetOutBinLocTranHaveGoodsStatus() { BasWcsLocMd locMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc"); BasWcsDevMd basWcsTranDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == locMd.LocExtMsg); WcsOpcItemMd tmpFrontHaveGoodsFlagOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsTranDevMd.DevCode && x.PlcCode == basWcsTranDevMd.DevPlcNo && x.OpcItemCode == "FrontHaveGoodsFlag"); WcsOpcItemMd tmpBackEndHaveGoodsFlagOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsTranDevMd.DevCode && x.PlcCode == basWcsTranDevMd.DevPlcNo && x.OpcItemCode == "BackEndHaveGoodsFlag"); return Convert.ToBoolean(tmpFrontHaveGoodsFlagOpcItem.OpcItemValue) || Convert.ToBoolean(tmpBackEndHaveGoodsFlagOpcItem.OpcItemValue); } /// /// 动态调度堆垛机执行的指令 /// /// 堆垛机设备对象 /// private WcsCrnCmdMd CrnCmdDynamicHandle(BasWcsDevMd basWcsDevMd) { if (AppConfigHelper.Get("CrnCurrentWorkingCmdType") == "0") //当前准备执行入库指令 { int crnCurrColumn = Convert.ToInt32(ReadCrnOpcItem(basWcsDevMd.DevCode, "WorkRow")); //执行入库任务时,判断堆垛机当前列的位置,如果当前列大于10,就去寻找能否捎带一个出库任务。 if (crnCurrColumn > 10) { WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString()); if (tmpCrmCmdMd != null) { if (GetOutBinLocTranHaveGoodsStatus()) { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); if (tmpCrmCmdMd != null) { //更新下一次堆垛机指令执行的任务类型。 AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1"); return tmpCrmCmdMd; } } else { return tmpCrmCmdMd; } } else { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); if (tmpCrmCmdMd != null) { //更新下一次堆垛机指令执行的任务类型。 AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1"); return tmpCrmCmdMd; } else { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString()); if (tmpCrmCmdMd != null) { if (!GetOutBinLocTranHaveGoodsStatus()) { return tmpCrmCmdMd; } } } } } else { WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); if (tmpCrmCmdMd != null) { //更新下一次堆垛机指令执行的任务类型。 AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1"); return tmpCrmCmdMd; } else { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString()); if (tmpCrmCmdMd != null) { if (!GetOutBinLocTranHaveGoodsStatus()) { return tmpCrmCmdMd; } } } } } else //当前准备执行出库指令 { WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString()); if (tmpCrmCmdMd != null) { if (!GetOutBinLocTranHaveGoodsStatus()) { //更新下一次堆垛机指令执行的任务类型。 AppConfigHelper.Update("CrnCurrentWorkingCmdType", "0"); return tmpCrmCmdMd; } else { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); if (tmpCrmCmdMd != null) { return tmpCrmCmdMd; } } } else { tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString()); if (tmpCrmCmdMd != null) { return tmpCrmCmdMd; } } } return null; } #endregion #region 桌面显示Log、记录log到文本 /// /// 桌面显示Log、记录log到文本 /// /// log内容 /// 是否输出到桌面日志端。true:输出桌面;false:只记录文本 /// 日志类型枚举 private void ShowLogToForm(string msg, bool isShowFormFlag, LogTypeEnum logTypeEnum) { if (isShowFormFlag) { showLogToFrm.ShowLog(new ShowLogToFrmEventArgs(LogHeadText + msg)); } LogHelper.WriteLog(LogHeadText + msg, logTypeEnum); } private string GetCrnBizRunLog(string prefixStr, WcsCrnCmdMd wcsCrnCmdMd) { return $"{prefixStr} -- 任务号:【{wcsCrnCmdMd.TaskNo}】指令号:【{wcsCrnCmdMd.CmdNo}】组盘码:【{wcsCrnCmdMd.TrayCode}】托盘号:【{wcsCrnCmdMd.PalletCode}】起始库位:【{wcsCrnCmdMd.SbinNo}】起始排:【{wcsCrnCmdMd.SbinRow}】起始列:【{wcsCrnCmdMd.SbinCol}】起始层:【{wcsCrnCmdMd.SbinLayer}】终点库位:【{wcsCrnCmdMd.EbinNo}】终点排:【{wcsCrnCmdMd.EbinRow}】终点列:【{wcsCrnCmdMd.EbinCol}】终点层:【{wcsCrnCmdMd.EbinLayer}】指令类型:【{wcsCrnCmdMd.CmdType}】动作类型:【{wcsCrnCmdMd.ActiveType}】指令状态:【{wcsCrnCmdMd.CmdStatus}】异常标识:【{wcsCrnCmdMd.ErrFlag}】指令Log:【{wcsCrnCmdMd.CmdLog}】异常Log:【{wcsCrnCmdMd.ErrLog}】"; } #endregion #region 测试代码 public void ThRunFun() { Random rm = new Random(); showLogToFrm.ShowLog(new ShowLogToFrmEventArgs(rm.Next().ToString())); } #endregion public List LoadCurrentWorkingCrnCmd() { return Crn_Dal.Instance.LoadCurrentWorkingCrnCmd(); } public string CrnManualControl(string crnDevNo,int sBinRow,int sBinCol,int sBinLayer,int eBinRow, int eBinCol, int eBinLayer, WcsWriteCrnCmdTypeEnum workingType) { BasWcsDevMd basWcsDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == crnDevNo); WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd"); WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo"); WcsOpcItemMd WCS_S_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkRowNo"); WcsOpcItemMd WCS_S_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkColNo"); WcsOpcItemMd WCS_S_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkLayerNo"); WcsOpcItemMd WCS_E_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkRowNo"); WcsOpcItemMd WCS_E_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkColNo"); WcsOpcItemMd WCS_E_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkLayerNo"); string cmdNo = BasCommon_Dal.Instance.GetSysSequence("Cmd_No"); if (workingType == WcsWriteCrnCmdTypeEnum.取放货) { if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkRowNo, sBinRow)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业排数据成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkColNo, sBinCol)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业列数据:【{sBinCol}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkLayerNo, sBinLayer)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业层数据:【{sBinLayer}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkRowNo, eBinRow)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业排数据:【{eBinRow}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkColNo, eBinCol)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业列数据:【{eBinCol}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkLayerNo, eBinLayer)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业层数据:【{eBinLayer}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, cmdNo)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun); ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】", false, LogTypeEnum.Run); return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】"; } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业层数据:【{eBinRow}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业列数据:【{eBinCol}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业排数据:【{eBinRow}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业层数据:【{sBinLayer}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业列数据:【{sBinCol}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业排数据:【{sBinRow}】失败!", false, LogTypeEnum.OPCRun); } return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令失败!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】"; } else if (workingType == WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成) { if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, cmdNo)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】成功!", false, LogTypeEnum.OPCRun); if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun); ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】", true, LogTypeEnum.Run); return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】"; } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun); } } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】失败!", false, LogTypeEnum.OPCRun); } return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令失败!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】"; } else { if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType)) { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun); ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】", true, LogTypeEnum.Run); return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】"; } else { //TODO:后续增加LOG ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun); return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】"; } } } public List LoadAllCrnCmd(WcsCrnCmdSearchMd searchMd) { return Crn_Dal.Instance.LoadAllCrnCmd(searchMd); } public object ReadCrnOpcItem(string crnDevNo,string opcItemCode) { BasWcsDevMd basWcsDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == crnDevNo); WcsOpcItemMd tmpOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == opcItemCode); return tmpOpcItem.OpcItemValue; } public void InsertTestCrnCmd(string dev_no) { Crn_Dal.Instance.InsertTestCrnCmd(dev_no); } public void DeleteTestCrnCmd() { Crn_Dal.Instance.DeleteTestCrnCmd(); } } }