Crn_Biz.cs 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. using NX_CommonClassLibrary;
  2. using NX_LogClassLibrary;
  3. using NX_ModelClassLibrary.BaseModel;
  4. using NX_ModelClassLibrary.Common;
  5. using NX_ModelClassLibrary.CrnModel;
  6. using NX_ModelClassLibrary.CustomEnum;
  7. using NX_ModelClassLibrary.CustomEvent;
  8. using NX_ModelClassLibrary.OpcModel;
  9. using NX_ModelClassLibrary.WmsTask;
  10. using NX_OpcUaClientLibrary;
  11. using NX_WcsBiz.CommonBusiness;
  12. using NX_WcsBiz.WcsDispatch;
  13. using NX_WcsDal.CommonBusiness;
  14. using NX_WcsDal.WcsBusiness;
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. namespace NX_WcsBiz.WcsBusiness
  22. {
  23. public class Crn_Biz
  24. {
  25. #region 单例模式
  26. /// <summary>
  27. /// 单例模式对象
  28. /// </summary>
  29. private static Crn_Biz _instance = null;
  30. private static readonly object lockObj = new object();
  31. /// <summary>
  32. /// 单例模式方法
  33. /// </summary>
  34. public static Crn_Biz Instance
  35. {
  36. get
  37. {
  38. if (_instance == null)
  39. {
  40. lock (lockObj)
  41. {
  42. if (_instance == null)
  43. {
  44. _instance = new Crn_Biz();
  45. }
  46. }
  47. }
  48. return _instance;
  49. }
  50. }
  51. #endregion
  52. #region 全局变量
  53. /// <summary>
  54. /// 堆垛机设备所属PLC信息列表
  55. /// </summary>
  56. public List<BasWcsPlcMd> crnBasPlcMdList;
  57. /// <summary>
  58. /// 堆垛机设备列表
  59. /// </summary>
  60. public List<BasWcsDevMd> crnDevList;
  61. /// <summary>
  62. /// 堆垛机设备类型
  63. /// </summary>
  64. public BasWcsDevTypeMd crnDevTypeMd;
  65. /// <summary>
  66. /// 堆垛机当前作业指令集合信息。
  67. /// </summary>
  68. public Hashtable CurrentWorkingCmdList;
  69. /// <summary>
  70. /// 堆垛机当前作业指令状态集合信息。
  71. /// </summary>
  72. public Hashtable CrnCurrentWorkingStatusList;
  73. /// <summary>
  74. /// 日志显示帮助类对象
  75. /// </summary>
  76. public ShowLogToFrmHelper showLogToFrm = new ShowLogToFrmHelper();
  77. /// <summary>
  78. /// 日志头部
  79. /// </summary>
  80. private readonly string LogHeadText = "堆垛机业务类 ==>> ";
  81. #endregion
  82. #region 堆垛机主业务
  83. /// <summary>
  84. /// 初始化堆垛机业务类
  85. /// </summary>
  86. /// <returns></returns>
  87. public bool Init()
  88. {
  89. try
  90. {
  91. crnDevTypeMd = BasCommon_Biz.Instance.basWcsDevTypeMdList.FirstOrDefault(x => x.DevTypeCode == "CrnType");
  92. crnDevList = BasCommon_Biz.Instance.basWcsDevMdList.FindAll(x => x.DevTypeCode == crnDevTypeMd.DevTypeCode);
  93. crnBasPlcMdList = new List<BasWcsPlcMd>();
  94. CurrentWorkingCmdList = Hashtable.Synchronized(new Hashtable());
  95. CrnCurrentWorkingStatusList = Hashtable.Synchronized(new Hashtable());
  96. foreach (BasWcsDevMd item in crnDevList)
  97. {
  98. BasWcsPlcMd tmpMd = crnBasPlcMdList.FirstOrDefault(x => x.PlcCode == item.DevPlcNo);
  99. if (tmpMd != null)
  100. {
  101. crnBasPlcMdList.Add(tmpMd);
  102. }
  103. CurrentWorkingCmdList.Add(item, new WcsCrnCmdMd());
  104. CrnCurrentWorkingStatusList.Add(item, CrnDevWorkStatusEnumExt.待机);
  105. }
  106. ShowLogToForm($"初始化堆垛机业务类成功!", true, LogTypeEnum.Run);
  107. return true;
  108. }
  109. catch (Exception ex)
  110. {
  111. ShowLogToForm($"初始化堆垛机业务类发生异常!【{ex.Message}】", true, LogTypeEnum.Err);
  112. return false;
  113. }
  114. }
  115. /// <summary>
  116. /// 堆垛机主业务函数
  117. /// </summary>
  118. /// <param name="basWcsDevMd"></param>
  119. public void CrnMainBizRunFunc(BasWcsDevMd basWcsDevMd)
  120. {
  121. try
  122. {
  123. WcsCrnCmdMd currTmpCmd = CurrentWorkingCmdList[basWcsDevMd] == null ? null : (WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd];
  124. if (currTmpCmd == null || currTmpCmd.CrnCmdId == 0)
  125. {
  126. //加载当前堆垛机未完成指令
  127. currTmpCmd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, true, null);
  128. }
  129. if (currTmpCmd == null || currTmpCmd.CrnCmdId == 0)
  130. {
  131. //加载空闲指令
  132. //currTmpCmd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  133. //if (currTmpCmd != null && currTmpCmd.CrnCmdId > 0)
  134. //{
  135. // ShowLogToForm(GetCrnBizRunLog("堆垛机加载空闲指令数据成功!", currTmpCmd), true, LogTypeEnum.Run);
  136. //}
  137. currTmpCmd = CrnCmdDynamicHandle(basWcsDevMd);
  138. }
  139. if (currTmpCmd != null && currTmpCmd.CmdNo > 0)
  140. {
  141. if (!CurrentWorkingCmdList.ContainsValue(currTmpCmd))
  142. {
  143. CurrentWorkingCmdList[basWcsDevMd] = currTmpCmd;
  144. }
  145. CurrPlcProtocolEnum plcProtocolEnum = EnumExtensionHelper.GetEnumObj<CurrPlcProtocolEnum>(AppConfigHelper.Get("CurrPlcProtocol"));
  146. switch (plcProtocolEnum)
  147. {
  148. case CurrPlcProtocolEnum.第一版:
  149. switch (currTmpCmd.CmdStatus)
  150. {
  151. case CrnCmdStatusEnum.初始创建:
  152. SendPlcCrnCmd((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  153. break;
  154. case CrnCmdStatusEnum.已下发PLC:
  155. UpdateCurrCrnCmdWorking((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  156. break;
  157. case CrnCmdStatusEnum.执行中:
  158. FinishCurrCrnCmd((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  159. break;
  160. default:
  161. break;
  162. }
  163. break;
  164. case CurrPlcProtocolEnum.第二版:
  165. currTmpCmd = DoubleBinMoveTaskHandle(currTmpCmd);
  166. switch (currTmpCmd.CmdStatus)
  167. {
  168. case CrnCmdStatusEnum.初始创建:
  169. SendPlcCrnCmd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  170. break;
  171. case CrnCmdStatusEnum.已下发PLC:
  172. UpdateCurrCrnCmdWorkingd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  173. break;
  174. case CrnCmdStatusEnum.执行中:
  175. FinishCurrCrnCmd_Version2((WcsCrnCmdMd)CurrentWorkingCmdList[basWcsDevMd], basWcsDevMd);
  176. break;
  177. default:
  178. break;
  179. }
  180. break;
  181. case CurrPlcProtocolEnum.第三版:
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. }
  188. catch (Exception ex)
  189. {
  190. ShowLogToForm($"堆垛机主业务函数运行发生异常!【{ex.Message}】", true, LogTypeEnum.Err);
  191. }
  192. }
  193. #region 第一版PLC交互协议的控制逻辑
  194. /// <summary>
  195. /// 下发堆垛机PLC指令信息
  196. /// </summary>
  197. /// <param name="wcsCrnCmdMd">堆垛机指令对象</param>
  198. /// <param name="basWcsDevMd">堆垛机基础信息对象</param>
  199. private void SendPlcCrnCmd(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  200. {
  201. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  202. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  203. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  204. WcsOpcItemMd ForkOriginSignalOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOriginSignal");
  205. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  206. CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnum>(WorkStatuslOpcItemMd.OpcItemValue);
  207. int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0");
  208. bool ForkOriginSignal = Convert.ToBoolean(ForkOriginSignalOpcItemMd.OpcItemValue ?? "False");
  209. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  210. WorkStatus == CrnDevWorkStatusEnum.待机 &&
  211. AlarmNo == 0 &&
  212. ForkOriginSignal)
  213. {
  214. #region 下发PLC指令
  215. WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd");
  216. WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo");
  217. WcsOpcItemMd WCS_S_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkRowNo");
  218. WcsOpcItemMd WCS_S_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkColNo");
  219. WcsOpcItemMd WCS_S_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkLayerNo");
  220. WcsOpcItemMd WCS_E_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkRowNo");
  221. WcsOpcItemMd WCS_E_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkColNo");
  222. WcsOpcItemMd WCS_E_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkLayerNo");
  223. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkRowNo, wcsCrnCmdMd.SbinRow))
  224. {
  225. //TODO:后续增加LOG
  226. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业排数据:【{wcsCrnCmdMd.SbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  227. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkColNo, wcsCrnCmdMd.SbinCol))
  228. {
  229. //TODO:后续增加LOG
  230. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业列数据:【{wcsCrnCmdMd.SbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  231. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkLayerNo, wcsCrnCmdMd.SbinLayer))
  232. {
  233. //TODO:后续增加LOG
  234. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  235. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkRowNo, wcsCrnCmdMd.EbinRow))
  236. {
  237. //TODO:后续增加LOG
  238. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  239. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkColNo, wcsCrnCmdMd.EbinCol))
  240. {
  241. //TODO:后续增加LOG
  242. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  243. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkLayerNo, wcsCrnCmdMd.EbinLayer))
  244. {
  245. //TODO:后续增加LOG
  246. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  247. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo))
  248. {
  249. //TODO:后续增加LOG
  250. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  251. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnum.取放货))
  252. {
  253. //TODO:后续增加LOG
  254. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnum.取放货}-{(int)WcsWriteCrnCmdTypeEnum.取放货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  255. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.已下发PLC;
  256. //更新数据库指令状态信息
  257. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  258. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnum.取放货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  259. }
  260. else
  261. {
  262. //TODO:后续增加LOG
  263. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnum.取放货}-{(int)WcsWriteCrnCmdTypeEnum.取放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  264. }
  265. }
  266. else
  267. {
  268. //TODO:后续增加LOG
  269. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  270. }
  271. }
  272. else
  273. {
  274. //TODO:后续增加LOG
  275. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  276. }
  277. }
  278. else
  279. {
  280. //TODO:后续增加LOG
  281. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  282. }
  283. }
  284. else
  285. {
  286. //TODO:后续增加LOG
  287. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC终点作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  288. }
  289. }
  290. else
  291. {
  292. //TODO:后续增加LOG
  293. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  294. }
  295. }
  296. else
  297. {
  298. //TODO:后续增加LOG
  299. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC起始作业列数据:【{wcsCrnCmdMd.SbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  300. }
  301. }
  302. else
  303. {
  304. //TODO:后续增加LOG
  305. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业排数据:【{wcsCrnCmdMd.SbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  306. }
  307. #endregion
  308. }
  309. }
  310. /// <summary>
  311. /// 更新堆垛机指令作业中数据
  312. /// </summary>
  313. /// <param name="wcsCrnCmdMd">堆垛机指令对象</param>
  314. /// <param name="basWcsDevMd">堆垛机基础信息对象</param>
  315. private void UpdateCurrCrnCmdWorking(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  316. {
  317. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  318. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  319. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  320. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  321. CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnum>(WorkStatuslOpcItemMd.OpcItemValue);
  322. int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0");
  323. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  324. WorkStatus == CrnDevWorkStatusEnum.运行中 &&
  325. AlarmNo == 0)
  326. {
  327. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.执行中;
  328. //更新数据库指令状态信息
  329. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  330. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令状态更新为执行中!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  331. }
  332. }
  333. /// <summary>
  334. /// 堆垛机指令完成函数
  335. /// </summary>
  336. /// <param name="wcsCrnCmdMd">堆垛机指令对象</param>
  337. /// <param name="basWcsDevMd">堆垛机基础信息对象</param>
  338. private void FinishCurrCrnCmd(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  339. {
  340. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  341. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  342. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  343. WcsOpcItemMd ForkOriginSignalOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOriginSignal");
  344. WcsOpcItemMd TaskNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "TaskNo");
  345. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  346. CrnDevWorkStatusEnum WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnum>(WorkStatuslOpcItemMd.OpcItemValue);
  347. int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0");
  348. bool ForkOriginSignal = Convert.ToBoolean(ForkOriginSignalOpcItemMd.OpcItemValue ?? "False");
  349. int TaskNo = Convert.ToInt32(TaskNoOpcItemMd.OpcItemValue ?? "0");
  350. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  351. WorkStatus == CrnDevWorkStatusEnum.放货完成 &&
  352. AlarmNo == 0 &&
  353. ForkOriginSignal &&
  354. TaskNo == wcsCrnCmdMd.CmdNo)
  355. {
  356. #region 下发PLC确认收到放货完成信号
  357. WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd");
  358. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成))
  359. {
  360. //TODO:后续增加LOG
  361. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC 确认收到取放货任务完成数据:【{WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}-{(int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  362. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.完成;
  363. //更新数据库指令状态信息
  364. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  365. if (Convert.ToInt32(AppConfigHelper.Get("CrnAutoTest")) == 0)
  366. {
  367. #region 调用任务反馈,完成堆垛机指令。生成下一步的数据。
  368. //调用任务反馈,完成堆垛机指令。生成下一步的数据。
  369. BasBinMd eBinMd = Crn_Dal.Instance.GetBinMdOfCode(wcsCrnCmdMd.EbinNo);
  370. BasWcsLocMd eLocMd;
  371. if (eBinMd.BinType == BasBinTypeEnum.出库口)
  372. {
  373. eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc" && x.RegionCode == wcsCrnCmdMd.RegionCode && x.LocBinExtMsg == eBinMd.BinCode);
  374. }
  375. else
  376. {
  377. eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc" && x.LocBinExtMsg == wcsCrnCmdMd.RegionCode);
  378. }
  379. DispUntilityReturnMd retmd = TaskResponse_Disp.Instance.TaskResponseHandleFunc(new TaskResponseMd
  380. {
  381. TrayCode = wcsCrnCmdMd.TrayCode,
  382. PalletCode = wcsCrnCmdMd.PalletCode,
  383. TaskNo = wcsCrnCmdMd.TaskNo,
  384. CmdNo = wcsCrnCmdMd.CmdNo,
  385. CurrentLocNo = eLocMd.LocCode,
  386. TaskResponseType = DispatchResponseHandleTypeEnum.堆垛机指令反馈完成
  387. });
  388. if (retmd.IsSuccess)
  389. {
  390. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束成功!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Run);
  391. CurrentWorkingCmdList[basWcsDevMd] = null;
  392. }
  393. else
  394. {
  395. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束失败!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Err);
  396. }
  397. #endregion
  398. }
  399. else
  400. {
  401. CurrentWorkingCmdList[basWcsDevMd] = null;
  402. //插入一条新的空闲堆垛机指令
  403. Crn_Dal.Instance.InsertTestCrnCmd(basWcsDevMd.DevCode);
  404. }
  405. }
  406. else
  407. {
  408. //TODO:后续增加LOG
  409. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC 确认收到取放货任务完成数据:【{WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}-{(int)WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  410. }
  411. #endregion
  412. }
  413. }
  414. #endregion 第一版PLC交互协议的控制逻辑
  415. #region 第二版PLC交互协议的控制逻辑
  416. private WcsCrnCmdMd DoubleBinMoveTaskHandle(WcsCrnCmdMd wcsCrnCmdMd)
  417. {
  418. if (wcsCrnCmdMd.CmdType == CrnCmdTypeEnum.IN && wcsCrnCmdMd.EExtensionIdx == 2)
  419. {
  420. WmsBalanceMd balanceMd = Crn_Dal.Instance.GetIntroversionBinBalanceMd(wcsCrnCmdMd.EExtensionGroup, wcsCrnCmdMd.EExtensionIdx - 1, wcsCrnCmdMd.RegionCode);
  421. if (balanceMd != null)
  422. {
  423. WmsTskTaskMd tskTaskMd = Crn_Dal.Instance.GetIntroversionBinMoveWmsTaskMd(balanceMd);
  424. if (tskTaskMd != null)
  425. {
  426. return null;
  427. }
  428. else
  429. {
  430. BasWcsLocMd RegiongLocNo = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc");
  431. BasRegionMd regionMd = Crn_Dal.Instance.GetRegionMd(wcsCrnCmdMd.RegionCode);
  432. BasBinMd CurrBinMd = Crn_Dal.Instance.GetBinMdOfCode(balanceMd.BinCode);
  433. List<BasShelfMd> DistributableShelfLst = BasCommon_Biz.Instance.GetCrnRelationShelfLst(CurrBinMd);
  434. BasBinMd emptyBin = BasCommon_Biz.Instance.GetDoubleExtensionEmptyBinMd(regionMd.RegionCode, DistributableShelfLst, balanceMd.TrayCode);
  435. Crn_Dal.Instance.InsertIntroversionBinMoveWmsTask(RegiongLocNo, regionMd, balanceMd, emptyBin);
  436. return null;
  437. }
  438. }
  439. }
  440. if (wcsCrnCmdMd.CmdType == CrnCmdTypeEnum.OUT && wcsCrnCmdMd.SExtensionIdx == 2)
  441. {
  442. WmsBalanceMd balanceMd = Crn_Dal.Instance.GetIntroversionBinBalanceMd(wcsCrnCmdMd.SExtensionGroup, wcsCrnCmdMd.SExtensionIdx - 1, wcsCrnCmdMd.RegionCode);
  443. if (balanceMd != null)
  444. {
  445. WmsTskTaskMd tskTaskMd = Crn_Dal.Instance.GetIntroversionBinMoveWmsTaskMd(balanceMd);
  446. if (tskTaskMd != null)
  447. {
  448. return null;
  449. }
  450. else
  451. {
  452. BasWcsLocMd RegiongLocNo = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc");
  453. BasRegionMd regionMd = Crn_Dal.Instance.GetRegionMd(wcsCrnCmdMd.RegionCode);
  454. BasBinMd CurrBinMd = Crn_Dal.Instance.GetBinMdOfCode(balanceMd.BinCode);
  455. List<BasShelfMd> DistributableShelfLst = BasCommon_Biz.Instance.GetCrnRelationShelfLst(CurrBinMd);
  456. BasBinMd emptyBin = BasCommon_Biz.Instance.GetDoubleExtensionEmptyBinMd(regionMd.RegionCode, DistributableShelfLst, balanceMd.TrayCode);
  457. Crn_Dal.Instance.InsertIntroversionBinMoveWmsTask(RegiongLocNo, regionMd, balanceMd, emptyBin);
  458. return null;
  459. }
  460. }
  461. }
  462. return wcsCrnCmdMd;
  463. }
  464. private void SendPlcCrnCmd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  465. {
  466. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  467. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  468. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  469. WcsOpcItemMd LevelStopAccuracyOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "LevelStopAccuracy");
  470. WcsOpcItemMd ForkOriginOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOrigin");
  471. WcsOpcItemMd ForkStaticStatusOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkStaticStatus");
  472. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  473. CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnumExt>(WorkStatuslOpcItemMd.OpcItemValue);
  474. int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0");
  475. bool ForkOriginSignal = Convert.ToBoolean(ForkOriginOpcItemMd.OpcItemValue ?? "False");
  476. bool LevelStopAccuracySignal = Convert.ToBoolean(LevelStopAccuracyOpcItemMd.OpcItemValue ?? "False");
  477. bool ForkStaticStatusSignal = Convert.ToBoolean(ForkStaticStatusOpcItemMd.OpcItemValue ?? "False");
  478. //联机自动 待机 无报警 货叉原位 水平停准 货叉静止
  479. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  480. WorkStatus == CrnDevWorkStatusEnumExt.待机 &&
  481. AlarmNo == 0 &&
  482. ForkOriginSignal &&
  483. LevelStopAccuracySignal &&
  484. ForkStaticStatusSignal)
  485. {
  486. #region 下发PLC指令
  487. WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd");
  488. WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo");
  489. WcsOpcItemMd WCS_PalletCode = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_PalletCode");
  490. WcsOpcItemMd WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkRowNo");
  491. WcsOpcItemMd WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkColNo");
  492. WcsOpcItemMd WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkLayerNo");
  493. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.SbinRow))
  494. {
  495. //TODO:后续增加LOG
  496. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.SbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  497. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.SbinCol))
  498. {
  499. //TODO:后续增加LOG
  500. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.SbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  501. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.SbinLayer))
  502. {
  503. //TODO:后续增加LOG
  504. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.SbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  505. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo))
  506. {
  507. //TODO:后续增加LOG
  508. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  509. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode))
  510. {
  511. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  512. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.取货))
  513. {
  514. //TODO:后续增加LOG
  515. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.取货}-{(int)WcsWriteCrnCmdTypeEnumExt.取货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  516. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.已下发PLC;
  517. //更新数据库指令状态信息
  518. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  519. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.取货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  520. }
  521. else
  522. {
  523. //TODO:后续增加LOG
  524. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.取货}-{(int)WcsWriteCrnCmdTypeEnumExt.取货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  525. }
  526. }
  527. else
  528. {
  529. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  530. }
  531. }
  532. else
  533. {
  534. //TODO:后续增加LOG
  535. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  536. }
  537. }
  538. else
  539. {
  540. //TODO:后续增加LOG
  541. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.SbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  542. }
  543. }
  544. else
  545. {
  546. //TODO:后续增加LOG
  547. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.SbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  548. }
  549. }
  550. else
  551. {
  552. //TODO:后续增加LOG
  553. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.SbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  554. }
  555. #endregion
  556. }
  557. }
  558. private void UpdateCurrCrnCmdWorkingd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  559. {
  560. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  561. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  562. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  563. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  564. CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnumExt>(WorkStatuslOpcItemMd.OpcItemValue);
  565. int AlarmNo = Convert.ToInt32(AlarmNoOpcItemMd.OpcItemValue ?? "0");
  566. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  567. WorkStatus == CrnDevWorkStatusEnumExt.取货中 &&
  568. AlarmNo == 0)
  569. {
  570. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.执行中;
  571. CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.取货中;
  572. //更新数据库指令状态信息
  573. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  574. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令状态更新为执行中!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  575. }
  576. }
  577. private void FinishCurrCrnCmd_Version2(WcsCrnCmdMd wcsCrnCmdMd, BasWcsDevMd basWcsDevMd)
  578. {
  579. WcsOpcItemMd WorkModelOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkModel");
  580. WcsOpcItemMd WorkStatuslOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkStatus");
  581. WcsOpcItemMd AlarmNoOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "AlarmNo");
  582. WcsOpcItemMd LevelStopAccuracyOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "LevelStopAccuracy");
  583. WcsOpcItemMd ForkOriginOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkOrigin");
  584. WcsOpcItemMd ForkStaticStatusOpcItemMd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "ForkStaticStatus");
  585. CrnDevWorkModeEnum WorkModel = EnumExtensionHelper.GetEnumObj<CrnDevWorkModeEnum>(WorkModelOpcItemMd.OpcItemValue);
  586. CrnDevWorkStatusEnumExt WorkStatus = EnumExtensionHelper.GetEnumObj<CrnDevWorkStatusEnumExt>(WorkStatuslOpcItemMd.OpcItemValue);
  587. int AlarmNo = Convert.ToInt32(WorkStatuslOpcItemMd.OpcItemValue ?? "0");
  588. bool ForkOriginSignal = Convert.ToBoolean(ForkOriginOpcItemMd.OpcItemValue ?? "False");
  589. bool LevelStopAccuracySignal = Convert.ToBoolean(LevelStopAccuracyOpcItemMd.OpcItemValue ?? "False");
  590. bool ForkStaticStatusSignal = Convert.ToBoolean(ForkStaticStatusOpcItemMd.OpcItemValue ?? "False");
  591. WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd");
  592. WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo");
  593. WcsOpcItemMd WCS_PalletCode = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_PalletCode");
  594. WcsOpcItemMd WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkRowNo");
  595. WcsOpcItemMd WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkColNo");
  596. WcsOpcItemMd WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WorkLayerNo");
  597. CrnDevWorkStatusEnumExt currCrnWorkStatus = (CrnDevWorkStatusEnumExt)CrnCurrentWorkingStatusList[basWcsDevMd];
  598. switch (currCrnWorkStatus)
  599. {
  600. case CrnDevWorkStatusEnumExt.取货中:
  601. //联机自动 取货完成 无报警 货叉原位 水平停准 货叉静止
  602. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  603. WorkStatus == CrnDevWorkStatusEnumExt.取货完成 &&
  604. AlarmNo == 0 &&
  605. ForkOriginSignal &&
  606. LevelStopAccuracySignal &&
  607. ForkStaticStatusSignal)
  608. {
  609. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.EbinRow))
  610. {
  611. //TODO:后续增加LOG
  612. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  613. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.EbinCol))
  614. {
  615. //TODO:后续增加LOG
  616. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  617. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.EbinLayer))
  618. {
  619. //TODO:后续增加LOG
  620. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  621. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo))
  622. {
  623. //TODO:后续增加LOG
  624. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  625. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode))
  626. {
  627. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  628. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.放货))
  629. {
  630. CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.放货中;
  631. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  632. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.放货}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  633. }
  634. else
  635. {
  636. //TODO:后续增加LOG
  637. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  638. }
  639. }
  640. else
  641. {
  642. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  643. }
  644. }
  645. else
  646. {
  647. //TODO:后续增加LOG
  648. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  649. }
  650. }
  651. else
  652. {
  653. //TODO:后续增加LOG
  654. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  655. }
  656. }
  657. else
  658. {
  659. //TODO:后续增加LOG
  660. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  661. }
  662. }
  663. else
  664. {
  665. //TODO:后续增加LOG
  666. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  667. }
  668. }
  669. break;
  670. case CrnDevWorkStatusEnumExt.放货中:
  671. //联机自动 放货完成 无报警 货叉原位 水平停准 货叉静止
  672. if (WorkModel == CrnDevWorkModeEnum.联机自动 &&
  673. WorkStatus == CrnDevWorkStatusEnumExt.放货完成 &&
  674. AlarmNo == 0 &&
  675. ForkOriginSignal &&
  676. LevelStopAccuracySignal &&
  677. ForkStaticStatusSignal)
  678. {
  679. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkRowNo, wcsCrnCmdMd.EbinRow))
  680. {
  681. //TODO:后续增加LOG
  682. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  683. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkColNo, wcsCrnCmdMd.EbinCol))
  684. {
  685. //TODO:后续增加LOG
  686. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  687. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WorkLayerNo, wcsCrnCmdMd.EbinLayer))
  688. {
  689. //TODO:后续增加LOG
  690. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC起始作业层数据:【{wcsCrnCmdMd.EbinLayer}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  691. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, wcsCrnCmdMd.CmdNo))
  692. {
  693. //TODO:后续增加LOG
  694. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  695. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_PalletCode, wcsCrnCmdMd.PalletCode))
  696. {
  697. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  698. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)WcsWriteCrnCmdTypeEnumExt.确认收到放货完成))
  699. {
  700. CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.放货完成;
  701. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}-{(int)WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}】成功!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  702. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】下发PLC:【{WcsWriteCrnCmdTypeEnumExt.确认收到放货完成}】指令成功!", wcsCrnCmdMd), true, LogTypeEnum.Run);
  703. }
  704. else
  705. {
  706. //TODO:后续增加LOG
  707. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业指令类型数据:【{WcsWriteCrnCmdTypeEnumExt.放货}-{(int)WcsWriteCrnCmdTypeEnumExt.放货}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  708. }
  709. }
  710. else
  711. {
  712. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC托盘号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  713. }
  714. }
  715. else
  716. {
  717. //TODO:后续增加LOG
  718. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC指令号数据:【{wcsCrnCmdMd.CmdNo}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  719. }
  720. }
  721. else
  722. {
  723. //TODO:后续增加LOG
  724. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业层数据:【{wcsCrnCmdMd.EbinLayer}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  725. }
  726. }
  727. else
  728. {
  729. //TODO:后续增加LOG
  730. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】OPC作业列数据:【{wcsCrnCmdMd.EbinCol}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  731. }
  732. }
  733. else
  734. {
  735. //TODO:后续增加LOG
  736. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】写入OPC作业排数据:【{wcsCrnCmdMd.EbinRow}】失败!", wcsCrnCmdMd), false, LogTypeEnum.OPCRun);
  737. }
  738. }
  739. break;
  740. case CrnDevWorkStatusEnumExt.放货完成:
  741. wcsCrnCmdMd.CmdStatus = CrnCmdStatusEnum.完成;
  742. //更新数据库指令状态信息
  743. Crn_Dal.Instance.UpdateCrnCmdStatus(wcsCrnCmdMd);
  744. if (Convert.ToInt32(AppConfigHelper.Get("CrnAutoTest")) == 0)
  745. {
  746. #region 调用任务反馈,完成堆垛机指令。生成下一步的数据。
  747. //调用任务反馈,完成堆垛机指令。生成下一步的数据。
  748. BasBinMd eBinMd = Crn_Dal.Instance.GetBinMdOfCode(wcsCrnCmdMd.EbinNo);
  749. BasWcsLocMd eLocMd;
  750. if (eBinMd.BinType == BasBinTypeEnum.出库口)
  751. {
  752. eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc" && x.RegionCode == wcsCrnCmdMd.RegionCode && x.LocBinExtMsg == eBinMd.BinCode);
  753. }
  754. else
  755. {
  756. eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc" && x.LocBinExtMsg == wcsCrnCmdMd.RegionCode);
  757. }
  758. DispUntilityReturnMd retmd = TaskResponse_Disp.Instance.TaskResponseHandleFunc(new TaskResponseMd
  759. {
  760. TrayCode = wcsCrnCmdMd.TrayCode,
  761. PalletCode = wcsCrnCmdMd.PalletCode,
  762. TaskNo = wcsCrnCmdMd.TaskNo,
  763. CmdNo = wcsCrnCmdMd.CmdNo,
  764. CurrentLocNo = eLocMd.LocCode,
  765. TaskResponseType = DispatchResponseHandleTypeEnum.堆垛机指令反馈完成
  766. });
  767. if (retmd.IsSuccess)
  768. {
  769. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束成功!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Run);
  770. CurrentWorkingCmdList[basWcsDevMd] = null;
  771. CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.待机;
  772. }
  773. else
  774. {
  775. ShowLogToForm(GetCrnBizRunLog($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【自动】指令结束失败!【{retmd.RetMsg}】", wcsCrnCmdMd), true, LogTypeEnum.Err);
  776. }
  777. #endregion
  778. }
  779. else
  780. {
  781. CurrentWorkingCmdList[basWcsDevMd] = null;
  782. CrnCurrentWorkingStatusList[basWcsDevMd] = CrnDevWorkStatusEnumExt.待机;
  783. //插入一条新的空闲堆垛机指令
  784. Crn_Dal.Instance.InsertTestCrnCmd(basWcsDevMd.DevCode);
  785. }
  786. break;
  787. default:
  788. break;
  789. }
  790. }
  791. #endregion 第二版PLC交互协议的控制逻辑
  792. /// <summary>
  793. /// 获取出库口输送线有货状态
  794. /// </summary>
  795. /// <returns></returns>
  796. private bool GetOutBinLocTranHaveGoodsStatus()
  797. {
  798. BasWcsLocMd locMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "OutLoc");
  799. BasWcsDevMd basWcsTranDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == locMd.LocExtMsg);
  800. WcsOpcItemMd tmpFrontHaveGoodsFlagOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsTranDevMd.DevCode && x.PlcCode == basWcsTranDevMd.DevPlcNo && x.OpcItemCode == "FrontHaveGoodsFlag");
  801. WcsOpcItemMd tmpBackEndHaveGoodsFlagOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsTranDevMd.DevCode && x.PlcCode == basWcsTranDevMd.DevPlcNo && x.OpcItemCode == "BackEndHaveGoodsFlag");
  802. return Convert.ToBoolean(tmpFrontHaveGoodsFlagOpcItem.OpcItemValue) || Convert.ToBoolean(tmpBackEndHaveGoodsFlagOpcItem.OpcItemValue);
  803. }
  804. /// <summary>
  805. /// 动态调度堆垛机执行的指令
  806. /// </summary>
  807. /// <param name="basWcsDevMd">堆垛机设备对象</param>
  808. /// <returns></returns>
  809. private WcsCrnCmdMd CrnCmdDynamicHandle(BasWcsDevMd basWcsDevMd)
  810. {
  811. if (AppConfigHelper.Get("CrnCurrentWorkingCmdType") == "0") //当前准备执行入库指令
  812. {
  813. int crnCurrColumn = Convert.ToInt32(ReadCrnOpcItem(basWcsDevMd.DevCode, "WorkRow"));
  814. //执行入库任务时,判断堆垛机当前列的位置,如果当前列大于10,就去寻找能否捎带一个出库任务。
  815. if (crnCurrColumn > 10)
  816. {
  817. WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString());
  818. if (tmpCrmCmdMd != null)
  819. {
  820. if (GetOutBinLocTranHaveGoodsStatus())
  821. {
  822. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  823. if (tmpCrmCmdMd != null)
  824. {
  825. //更新下一次堆垛机指令执行的任务类型。
  826. AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1");
  827. return tmpCrmCmdMd;
  828. }
  829. }
  830. else
  831. {
  832. return tmpCrmCmdMd;
  833. }
  834. }
  835. else
  836. {
  837. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  838. if (tmpCrmCmdMd != null)
  839. {
  840. //更新下一次堆垛机指令执行的任务类型。
  841. AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1");
  842. return tmpCrmCmdMd;
  843. }
  844. else
  845. {
  846. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString());
  847. if (tmpCrmCmdMd != null)
  848. {
  849. if (!GetOutBinLocTranHaveGoodsStatus())
  850. {
  851. return tmpCrmCmdMd;
  852. }
  853. }
  854. }
  855. }
  856. }
  857. else
  858. {
  859. WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  860. if (tmpCrmCmdMd != null)
  861. {
  862. //更新下一次堆垛机指令执行的任务类型。
  863. AppConfigHelper.Update("CrnCurrentWorkingCmdType", "1");
  864. return tmpCrmCmdMd;
  865. }
  866. else
  867. {
  868. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString());
  869. if (tmpCrmCmdMd != null)
  870. {
  871. if (!GetOutBinLocTranHaveGoodsStatus())
  872. {
  873. return tmpCrmCmdMd;
  874. }
  875. }
  876. }
  877. }
  878. }
  879. else //当前准备执行出库指令
  880. {
  881. WcsCrnCmdMd tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.OUT.ToString());
  882. if (tmpCrmCmdMd != null)
  883. {
  884. if (!GetOutBinLocTranHaveGoodsStatus())
  885. {
  886. //更新下一次堆垛机指令执行的任务类型。
  887. AppConfigHelper.Update("CrnCurrentWorkingCmdType", "0");
  888. return tmpCrmCmdMd;
  889. }
  890. else
  891. {
  892. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  893. if (tmpCrmCmdMd != null)
  894. {
  895. return tmpCrmCmdMd;
  896. }
  897. }
  898. }
  899. else
  900. {
  901. tmpCrmCmdMd = Crn_Dal.Instance.LoadCrnUnFinishedCmd(basWcsDevMd, false, CrnCmdTypeEnum.IN.ToString());
  902. if (tmpCrmCmdMd != null)
  903. {
  904. return tmpCrmCmdMd;
  905. }
  906. }
  907. }
  908. return null;
  909. }
  910. #endregion
  911. #region 桌面显示Log、记录log到文本
  912. /// <summary>
  913. /// 桌面显示Log、记录log到文本
  914. /// </summary>
  915. /// <param name="msg">log内容</param>
  916. /// <param name="isShowFormFlag">是否输出到桌面日志端。true:输出桌面;false:只记录文本</param>
  917. /// <param name="logTypeEnum">日志类型枚举</param>
  918. private void ShowLogToForm(string msg, bool isShowFormFlag, LogTypeEnum logTypeEnum)
  919. {
  920. if (isShowFormFlag)
  921. {
  922. showLogToFrm.ShowLog(new ShowLogToFrmEventArgs(LogHeadText + msg));
  923. }
  924. LogHelper.WriteLog(LogHeadText + msg, logTypeEnum);
  925. }
  926. private string GetCrnBizRunLog(string prefixStr, WcsCrnCmdMd wcsCrnCmdMd)
  927. {
  928. 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}】";
  929. }
  930. #endregion
  931. #region 测试代码
  932. public void ThRunFun()
  933. {
  934. Random rm = new Random();
  935. showLogToFrm.ShowLog(new ShowLogToFrmEventArgs(rm.Next().ToString()));
  936. }
  937. #endregion
  938. public List<WcsCrnCmdMd> LoadCurrentWorkingCrnCmd()
  939. {
  940. return Crn_Dal.Instance.LoadCurrentWorkingCrnCmd();
  941. }
  942. public string CrnManualControl(string crnDevNo,int sBinRow,int sBinCol,int sBinLayer,int eBinRow, int eBinCol, int eBinLayer, WcsWriteCrnCmdTypeEnum workingType)
  943. {
  944. BasWcsDevMd basWcsDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == crnDevNo);
  945. WcsOpcItemMd WCS_WorkCmd = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_WorkCmd");
  946. WcsOpcItemMd WCS_TaskNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_TaskNo");
  947. WcsOpcItemMd WCS_S_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkRowNo");
  948. WcsOpcItemMd WCS_S_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkColNo");
  949. WcsOpcItemMd WCS_S_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_S_WorkLayerNo");
  950. WcsOpcItemMd WCS_E_WorkRowNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkRowNo");
  951. WcsOpcItemMd WCS_E_WorkColNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkColNo");
  952. WcsOpcItemMd WCS_E_WorkLayerNo = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == "WCS_E_WorkLayerNo");
  953. string cmdNo = BasCommon_Dal.Instance.GetSysSequence("Cmd_No");
  954. if (workingType == WcsWriteCrnCmdTypeEnum.取放货)
  955. {
  956. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkRowNo, sBinRow))
  957. {
  958. //TODO:后续增加LOG
  959. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业排数据成功!", false, LogTypeEnum.OPCRun);
  960. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkColNo, sBinCol))
  961. {
  962. //TODO:后续增加LOG
  963. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业列数据:【{sBinCol}】成功!", false, LogTypeEnum.OPCRun);
  964. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_S_WorkLayerNo, sBinLayer))
  965. {
  966. //TODO:后续增加LOG
  967. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业层数据:【{sBinLayer}】成功!", false, LogTypeEnum.OPCRun);
  968. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkRowNo, eBinRow))
  969. {
  970. //TODO:后续增加LOG
  971. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业排数据:【{eBinRow}】成功!", false, LogTypeEnum.OPCRun);
  972. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkColNo, eBinCol))
  973. {
  974. //TODO:后续增加LOG
  975. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业列数据:【{eBinCol}】成功!", false, LogTypeEnum.OPCRun);
  976. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_E_WorkLayerNo, eBinLayer))
  977. {
  978. //TODO:后续增加LOG
  979. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业层数据:【{eBinLayer}】成功!", false, LogTypeEnum.OPCRun);
  980. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, cmdNo))
  981. {
  982. //TODO:后续增加LOG
  983. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】成功!", false, LogTypeEnum.OPCRun);
  984. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType))
  985. {
  986. //TODO:后续增加LOG
  987. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun);
  988. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】", false, LogTypeEnum.Run);
  989. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】";
  990. }
  991. else
  992. {
  993. //TODO:后续增加LOG
  994. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun);
  995. }
  996. }
  997. else
  998. {
  999. //TODO:后续增加LOG
  1000. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】失败!", false, LogTypeEnum.OPCRun);
  1001. }
  1002. }
  1003. else
  1004. {
  1005. //TODO:后续增加LOG
  1006. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业层数据:【{eBinRow}】失败!", false, LogTypeEnum.OPCRun);
  1007. }
  1008. }
  1009. else
  1010. {
  1011. //TODO:后续增加LOG
  1012. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业列数据:【{eBinCol}】失败!", false, LogTypeEnum.OPCRun);
  1013. }
  1014. }
  1015. else
  1016. {
  1017. //TODO:后续增加LOG
  1018. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC终点作业排数据:【{eBinRow}】失败!", false, LogTypeEnum.OPCRun);
  1019. }
  1020. }
  1021. else
  1022. {
  1023. //TODO:后续增加LOG
  1024. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业层数据:【{sBinLayer}】失败!", false, LogTypeEnum.OPCRun);
  1025. }
  1026. }
  1027. else
  1028. {
  1029. //TODO:后续增加LOG
  1030. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业列数据:【{sBinCol}】失败!", false, LogTypeEnum.OPCRun);
  1031. }
  1032. }
  1033. else
  1034. {
  1035. //TODO:后续增加LOG
  1036. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC起始作业排数据:【{sBinRow}】失败!", false, LogTypeEnum.OPCRun);
  1037. }
  1038. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令失败!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】起始排:【{sBinRow}】起始列:【{sBinCol}】起始层:【{sBinLayer}】终点排:【{eBinRow}】终点列:【{eBinCol}】终点层:【{eBinLayer}】";
  1039. }
  1040. else if (workingType == WcsWriteCrnCmdTypeEnum.确认收到取放货任务完成)
  1041. {
  1042. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_TaskNo, cmdNo))
  1043. {
  1044. //TODO:后续增加LOG
  1045. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】成功!", false, LogTypeEnum.OPCRun);
  1046. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType))
  1047. {
  1048. //TODO:后续增加LOG
  1049. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun);
  1050. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】", true, LogTypeEnum.Run);
  1051. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令成功!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】";
  1052. }
  1053. else
  1054. {
  1055. //TODO:后续增加LOG
  1056. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun);
  1057. }
  1058. }
  1059. else
  1060. {
  1061. //TODO:后续增加LOG
  1062. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC指令号数据:【{cmdNo}】失败!", false, LogTypeEnum.OPCRun);
  1063. }
  1064. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC【{workingType}】指令失败!指令号:【{cmdNo}】指令类型:【{workingType}-{(int)workingType}】";
  1065. }
  1066. else
  1067. {
  1068. if (LeadOpcUaClientHelper.Instance.WriteOpcItemValue(WCS_WorkCmd, (int)workingType))
  1069. {
  1070. //TODO:后续增加LOG
  1071. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】成功!", false, LogTypeEnum.OPCRun);
  1072. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】", true, LogTypeEnum.Run);
  1073. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】";
  1074. }
  1075. else
  1076. {
  1077. //TODO:后续增加LOG
  1078. ShowLogToForm($"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】【手动】写入OPC作业指令类型数据:【{workingType}-{(int)workingType}】失败!", false, LogTypeEnum.OPCRun);
  1079. return $"堆垛机:【{basWcsDevMd.DevCode}-{basWcsDevMd.DevName}】--【手动】下发PLC:【{workingType}】指令成功!指令类型:【{workingType}-{(int)workingType}】";
  1080. }
  1081. }
  1082. }
  1083. public List<WcsCrnCmdMd> LoadAllCrnCmd(WcsCrnCmdSearchMd searchMd)
  1084. {
  1085. return Crn_Dal.Instance.LoadAllCrnCmd(searchMd);
  1086. }
  1087. public object ReadCrnOpcItem(string crnDevNo,string opcItemCode)
  1088. {
  1089. BasWcsDevMd basWcsDevMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == crnDevNo);
  1090. WcsOpcItemMd tmpOpcItem = BasCommon_Biz.Instance.allOpcItemList.FirstOrDefault(x => x.DevCode == basWcsDevMd.DevCode && x.PlcCode == basWcsDevMd.DevPlcNo && x.OpcItemCode == opcItemCode);
  1091. return tmpOpcItem.OpcItemValue;
  1092. }
  1093. public void InsertTestCrnCmd(string dev_no)
  1094. {
  1095. Crn_Dal.Instance.InsertTestCrnCmd(dev_no);
  1096. }
  1097. public void DeleteTestCrnCmd()
  1098. {
  1099. Crn_Dal.Instance.DeleteTestCrnCmd();
  1100. }
  1101. }
  1102. }