Base_SingleRgv.cs 15 KB

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