Base_SingleRgv3.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. using SqlSugar;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading;
  7. using WCS.Data;
  8. using WCS.Data.Models;
  9. using WCS.Data.Utils;
  10. using WCS.PLC.Model.Equipment;
  11. namespace WCS.PLC
  12. {
  13. public class Base_SingleRgv3 : Base_Rgv
  14. {
  15. #region Constructor
  16. public Base_SingleRgv3() : base() { }
  17. #endregion;
  18. #region property
  19. //工位编号
  20. protected string RgvPos { get; set; }
  21. /// <summary>
  22. /// RGV上料点列表
  23. /// </summary>
  24. protected override List<WCS_RGVOutInInfo> RGVOnPosList
  25. {
  26. get
  27. {
  28. var _onPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "OnMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).OrderBy(v => v.LastOnMatTime).ToList();
  29. return _onPosList;
  30. }
  31. }
  32. /// <summary>
  33. /// RGV下料点列表
  34. /// </summary>
  35. protected override List<WCS_RGVOutInInfo> RGVUpPosList
  36. {
  37. get
  38. {
  39. var _upPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "UpMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).OrderBy(v => v.LastUpMatTime).ToList();
  40. return _upPosList;
  41. }
  42. }
  43. #endregion;
  44. #region Method
  45. private int _locRgvExecute = 0;
  46. public override void Run()
  47. {
  48. if (Interlocked.Exchange(ref _locRgvExecute, 1) == 0)
  49. {
  50. try
  51. {
  52. RgvExecute();
  53. }
  54. catch (Exception ex)
  55. {
  56. string errormsg = string.Format("Rgv[{0}]执行异常,消息:{1}", PlcName, ex.ToString());
  57. LogMessageHelper.RecordLogMessage(errormsg, ex);
  58. }
  59. finally
  60. {
  61. Interlocked.Exchange(ref _locRgvExecute, 0);
  62. }
  63. }
  64. }
  65. internal void RgvExecute()
  66. {
  67. //RGV完成任务
  68. Rgv_Finish();
  69. //上下料
  70. OnUpMateriel();
  71. //其它功能
  72. Rgv_OtherExtend();
  73. }
  74. internal void Rgv_Finish()
  75. {
  76. if (Rgv.DB521_Finish_1)
  77. {
  78. var task = Current.TaskSet.FirstOrDefault(v => v.TASK_NO == Rgv.DB521_TaskID_1 && v.TASK_RGVNO == PlcName);
  79. if (task != null)
  80. {
  81. task.TASK_RGVNO = "";
  82. if (task.TASK_WKSTATUS == 7) task.TASK_WKSTATUS = (int)WkStatus.RGV完成;
  83. string stratPos = Rgv.DB521_StartPosition_1.ToString();
  84. string endPos = Rgv.DB521_DestPosition_1.ToString();
  85. TryCachHelper.TryExecute((db) =>
  86. {
  87. string routeSet = task.TASK_POSIDNEXT;
  88. if (task.TASK_POSIDNEXT == "1196")
  89. routeSet = "1199";
  90. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = task.TASK_WKSTATUS, TASK_POSIDCUR = task.TASK_POSIDNEXT, TASK_POSIDNEXT = routeSet, TASK_RGVNO = "", TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  91. .Where(it => it.TASK_NO == task.TASK_NO)
  92. .ExecuteCommand();
  93. DateTime dt = SugarBase.DB.GetDate();
  94. db.Updateable<WCS_RGVOutInInfo>(it => new WCS_RGVOutInInfo() { LastOnMatTime = dt })
  95. .Where(it => it.RGVOUTIN_CONVNO == stratPos).ExecuteCommand();
  96. db.Updateable<WCS_RGVOutInInfo>(it => new WCS_RGVOutInInfo() { LastUpMatTime = dt })
  97. .Where(it => it.RGVOUTIN_CONVNO == endPos).ExecuteCommand();
  98. DateTime lastfinishtime = db.GetDate();
  99. //更新最后完成时间
  100. db.Updateable<WCS_PLC>(it => new WCS_PLC() { PLC_LASTFINISHTIME = lastfinishtime }).Where(it => it.PLC_NAME == PlcName).ExecuteCommand();
  101. });
  102. }
  103. }
  104. }
  105. internal void OnUpMateriel()
  106. {
  107. if (string.IsNullOrWhiteSpace(PlcName)) return;
  108. if (Rgv.DB521_SystemStatus != 1) return;
  109. if (Rgv.DB521_WorkMode != 1) return;
  110. if (!Rgv.DB521_Finish_1) return;
  111. if (Rgv.DB521_PH_Status_1) return;
  112. if (Rgv.DB520_Trigger_1 == 1) return;
  113. //是否存在执行的任务
  114. if (SugarBase.DB.Queryable<WCS_TASK>().Any(v => v.TASK_RGVNO == PlcName)) return;
  115. if (WaitExecTask.IsNotEmpty())
  116. {
  117. try
  118. {
  119. var taskitem = SugarBase.DB.Queryable<WCS_TASK>().First(v => v.TASK_NO == WaitExecTask.WaitExecTaskNo &&
  120. (v.TASK_POSIDNEXT != WaitExecTask.WaitExecUpMatPosNo) &&
  121. (v.TASK_POSIDCUR == WaitExecTask.WaitExecOnMatPosNo));
  122. if (taskitem == null)
  123. {
  124. WaitExecTask.Clear();
  125. }
  126. else
  127. {
  128. var rgvwrite = new WCSWriteToRgvSignal()
  129. {
  130. Plc = RgvPlc,
  131. RgvPos = RgvPosEnum.一号工位,
  132. DBName = WCS_PLCItem.WCS_DBSet.FirstOrDefault(v => v.DB_TypeCh == DB_TypeEnum.WCS可读可写DB).DB_NAME,
  133. RgvNo = PlcName,
  134. WriteStartAddress = Rgv.EquDbInfo_ReadWrite.DBReadIndox,
  135. Tasknum = taskitem.TASK_NO,
  136. StartPosition = Convert.ToInt32(WaitExecTask.WaitExecOnMatPosNo),
  137. DestPosition = Convert.ToInt32(WaitExecTask.WaitExecUpMatPosNo)
  138. };
  139. Log4netHelper.Logger_Info.InfoFormat("存在预执行任务[{0}]直接执行", taskitem.TASK_NO);
  140. WriteTask(rgvwrite);
  141. }
  142. }
  143. catch (Exception ex)
  144. {
  145. WaitExecTask.Clear();
  146. LogMessageHelper.RecordLogMessage(ex);
  147. }
  148. return;
  149. }
  150. foreach (var item in RGVOnPosList)
  151. {
  152. try
  153. {
  154. var conv = ConveyorHelper.GetConveyorSignal(item.PLCNAME, item.RGVOUTIN_CONVNO);
  155. if (conv.DB521_Tasknum <= 0) continue;
  156. var task = SugarBase.DB.Queryable<WCS_TASK>().Single(v => v.TASK_POSIDCUR == item.RGVOUTIN_CONVNO && conv.DB521_Tasknum == v.TASK_NO);
  157. if (task == null || task.TASK_WKSTATUS != (int)WkStatus.输送机执行) continue;
  158. //查询任务下料点列表
  159. var routeSet = EquRouteHelper.QueryRoute(item.RGVOUTIN_CONVNO, task.TASK_POSIDTO)
  160. .Where(v => v.ROUTE_STARTPOS == item.RGVOUTIN_CONVNO)
  161. .Select(t => t.ROUTE_SONPOS).ToList();
  162. if (routeSet.Count() == 0)
  163. {
  164. if (task.TASK_POSIDFROM == "1094" || task.TASK_POSIDFROM == "Pvc_4_Full01" || task.TASK_POSIDFROM == "Pvc_4_Full02" || task.TASK_POSIDFROM == "Pvc_4_Back")
  165. {
  166. routeSet.Add("1120");
  167. }
  168. else
  169. {
  170. LogMessageHelper.RecordLogMessage(string.Format("任务[{0}]当前地址[{1}]目标地址[{2}]未查询到路由地址。", task.TASK_NO, item.RGVOUTIN_CONVNO, task.TASK_POSIDTO));
  171. continue;
  172. }
  173. }
  174. if (!CheckOnTaskToPos(task, item.RGVOUTIN_CONVNO)) continue;
  175. var rgvUpPosList = QueryRgvUpPosList(item.RGVOUTIN_CONVNO);
  176. rgvUpPosList = rgvUpPosList.Where(v => routeSet.Any(t => t.Contains(v.RGVOUTIN_CONVNO))).ToList();
  177. if (rgvUpPosList.Any(v => v.SrmTunnelNo <= 0) == false && task.TASK_POSIDTO == srm)
  178. {
  179. if (string.IsNullOrWhiteSpace(task.TASK_ITEM7) || task.TASK_ITEM7 == "0")
  180. {
  181. //预分配堆垛机巷道
  182. ThreadHelper.TaskThread(BaseWorkflow.PreparatoryAssignSrmTunnel, task, 2000);
  183. }
  184. if (string.IsNullOrWhiteSpace(task.TASK_ITEM7))
  185. {
  186. rgvUpPosList = new List<WCS_RGVOutInInfo>();//清零
  187. }
  188. else
  189. {
  190. //根据巷道预分配调整下料口顺序
  191. var srmTunnelList = task.TASK_ITEM7.Split(',');
  192. var rgvUpPosSet = rgvUpPosList.Where(v => srmTunnelList.Contains(v.SrmTunnelNo.ToString())).ToList();
  193. var rgvUpPosList_temp = new List<WCS_RGVOutInInfo>();
  194. srmTunnelList.ToList().ForEach(v => rgvUpPosList_temp.Add(rgvUpPosSet.First(t => t.SrmTunnelNo.ToString() == v)));
  195. rgvUpPosList = rgvUpPosList_temp;
  196. }
  197. }
  198. string upPosConvNo = string.Empty;
  199. //检测下料位置是否可用
  200. foreach (var upItem in rgvUpPosList)
  201. {
  202. var upConv = ConveyorHelper.GetConveyorSignal(upItem.PLCNAME, upItem.RGVOUTIN_CONVNO);
  203. if (upConv.CvDB51_PH_Status == false && upConv.DB521_Tasknum == 0 && upConv.DB521_Request == false || (upItem.IsCheckUpMatPos == false))
  204. {
  205. if (SugarBase.DB.Queryable<WCS_TASK>().Any(v => v.TASK_POSIDCUR == upItem.RGVOUTIN_CONVNO && v.TASK_POSIDNEXT == upItem.RGVOUTIN_CONVNO) && upItem.IsCheckUpMatPos)
  206. {
  207. LogMessageHelper.RecordLogMessage(string.Format("穿梭车[{0}]下料位置[{1}]PLC无光电和任务号但WCS存在任务。", PlcName, upItem.RGVOUTIN_CONVNO));
  208. }
  209. else
  210. {
  211. if (CheckUpTaskToPos(task, upItem.RGVOUTIN_CONVNO))
  212. {
  213. if (!string.IsNullOrWhiteSpace(task.TASK_ITEM7))
  214. {
  215. var srminitem = Current.WCS_SrmOutInInfoSet.FirstOrDefault(v => v.SRMOUTIN_CONVNO == upItem.RGVOUTIN_CONVNO);
  216. //任务分配巷道
  217. var result = TryCachHelper.TryExecute((db) =>
  218. {
  219. db.Updateable<WCS_TASK>(it => new WCS_TASK()
  220. {
  221. TASK_EndTunnelNum = upItem.SrmTunnelNo.ToString(),
  222. TASK_POSIDTO = srminitem.SRMOUTIN_SRMNO,
  223. TASK_SRMNO = srminitem.SRMOUTIN_SRMNO,
  224. TASK_EDITUSERNO = "WCS",
  225. TASK_EDITDATETIME = DateTime.Now
  226. })
  227. .Where(it => it.TASK_NO == task.TASK_NO)
  228. .ExecuteCommand();
  229. });
  230. if (!string.IsNullOrWhiteSpace(result))
  231. {
  232. throw new Exception(string.Format("WMS任务[{0}]分配巷道更新任务失败,原因[{1}]", task.TASK_WMSNO, result));
  233. }
  234. }
  235. upPosConvNo = upItem.RGVOUTIN_CONVNO;
  236. break;
  237. }
  238. }
  239. }
  240. }
  241. if (string.IsNullOrWhiteSpace(upPosConvNo)) continue;
  242. var rgvwrite = new WCSWriteToRgvSignal();
  243. rgvwrite.Plc = RgvPlc;
  244. rgvwrite.RgvPos = RgvPosEnum.一号工位;
  245. rgvwrite.DBName = WCS_PLCItem.WCS_DBSet.FirstOrDefault(v => v.DB_TypeCh == DB_TypeEnum.WCS可读可写DB).DB_NAME;
  246. rgvwrite.RgvNo = PlcName;
  247. rgvwrite.WriteStartAddress = Rgv.EquDbInfo_ReadWrite.DBReadIndox;
  248. rgvwrite.Tasknum = task.TASK_NO;
  249. rgvwrite.StartPosition = Convert.ToInt32(item.RGVOUTIN_CONVNO);
  250. rgvwrite.DestPosition = Convert.ToInt32(upPosConvNo);
  251. Log4netHelper.Logger_ProductLog.InfoFormat("不存在预执行任务[{0}]先写入信息", task.TASK_NO);
  252. WriteTask(rgvwrite);
  253. if (WaitExecTask.IsNotEmpty()) break;
  254. }
  255. catch (Exception ex)
  256. {
  257. LogMessageHelper.RecordLogMessage(ex);
  258. }
  259. }
  260. }
  261. protected override void UpdateRgvTaskStatus(SqlSugarClient db, WCSWriteToRgvSignal rgvwrite)
  262. {
  263. var task = Current.TaskSet.First(t => t.TASK_NO == rgvwrite.Tasknum);
  264. string msg = string.Empty;
  265. if (rgvwrite.TaskType == 3)
  266. {
  267. //移动
  268. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.RGV移动, TASK_RGVNO = PlcName, TASK_ITEM4 = rgvwrite.StartPosition.ToString(), TASK_POSIDNEXT = rgvwrite.DestPosition.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  269. .Where(it => it.TASK_NO == task.TASK_NO)
  270. .ExecuteCommand();
  271. msg = string.Format("穿梭车[{0}]开始执行移动任务[{1}]起始点[{2}]终点[{3}]", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition);
  272. }
  273. else
  274. {
  275. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.RGV执行中, TASK_RGVNO = PlcName, TASK_ITEM4 = rgvwrite.StartPosition.ToString(), TASK_POSIDNEXT = rgvwrite.DestPosition.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  276. .Where(it => it.TASK_NO == task.TASK_NO)
  277. .ExecuteCommand();
  278. msg = string.Format("穿梭车[{0}]开始执行上下料任务[{1}]上料点[{2}]下料点[{3}]", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition);
  279. }
  280. if (!string.IsNullOrWhiteSpace(msg))
  281. {
  282. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, rgvwrite.DestPosition.ToString(), msg);
  283. }
  284. }
  285. /// <summary>
  286. /// 查询RGV下料列表(就近原则)
  287. /// </summary>
  288. protected List<WCS_RGVOutInInfo> QueryRgvUpPosList(string onPosConvNo)
  289. {
  290. var tempList = Current.WCS_RGVOutInInfoSet.Where(v => v.RGVOUTIN_ISSTOP == false && v.RGVOUTIN_RGVNO == PlcName && (v.RGVOUTIN_OUTINTYPE == "UpMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).ToList();
  291. var curItem = RGVOnPosList.FirstOrDefault(v => v.RGVOUTIN_CONVNO == onPosConvNo);
  292. if (curItem != null)
  293. {
  294. foreach (var item in tempList)
  295. {
  296. int difference = item.RGVOUTIN_SEQUENCE - curItem.RGVOUTIN_SEQUENCE;
  297. item.RGVCURRENT_SEQUENCE = Math.Abs(difference);
  298. }
  299. }
  300. return tempList.OrderBy(v => v.RGVCURRENT_SEQUENCE).ToList();
  301. }
  302. protected virtual bool CheckOnTaskToPos(WCS_TASK task, string onPosConvNo) { return true; }
  303. protected virtual bool CheckUpTaskToPos(WCS_TASK task, string upPosConvNo) { return true; }
  304. protected virtual void Rgv_OtherExtend() { }
  305. #endregion;
  306. }
  307. }