Base_Srm.cs 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. using Newtonsoft.Json;
  2. using SqlSugar;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. using WCS.Data;
  10. using WCS.Data.Models;
  11. using WCS.Data.Utils;
  12. using WCS.PLC.Model.Equipment;
  13. namespace WCS.PLC
  14. {
  15. public class Base_Srm: Base_EquPlc
  16. {
  17. #region Properties
  18. /// <summary>
  19. /// 任务要执行的当前路由信息
  20. /// </summary>
  21. //protected WCS_EQUIPMENTROUTE CurrentRoute { get; set; }
  22. /// <summary>
  23. /// 堆垛机信号
  24. /// </summary>
  25. protected SrmSignal EquSignal
  26. {
  27. get
  28. {
  29. return WCS_PLCItem.WCS_EquipmentInfoSet[0].EquSignal_Srm;
  30. }
  31. }
  32. /// <summary>
  33. /// 写入DB名称
  34. /// </summary>
  35. protected int WriteDbName
  36. {
  37. get
  38. {
  39. return WCS_PLCItem.WCS_DBSet[0].DB_NAME;
  40. }
  41. }
  42. /// <summary>
  43. /// 堆垛机出入库口设置列表
  44. /// </summary>
  45. protected List<WCS_SrmOutInInfo> SrmOutInInfoSet = new List<WCS_SrmOutInInfo>();
  46. #endregion;
  47. #region Constructor
  48. public Base_Srm() : base()
  49. {
  50. }
  51. #endregion;
  52. #region Method
  53. private int _locExecute = 0;
  54. public override void Run()
  55. {
  56. if (Interlocked.Exchange(ref _locExecute, 1) == 0)
  57. {
  58. try
  59. {
  60. //加载刷新堆垛机执行需要的最新参数设置
  61. Init_Refresh();
  62. //分配入库货位
  63. ThreadHelper.TaskThread(AssignInWareCell);
  64. if (WCS_PLCItem.IsConnSuccess == false) return;
  65. if (string.IsNullOrWhiteSpace(PlcName)) return;
  66. //写入心跳
  67. //WriteHandShake();
  68. //完成任务
  69. SRMCompleteTask();
  70. //执行任务
  71. SRMStartExecuteTask();
  72. }
  73. catch (Exception ex)
  74. {
  75. string errormsg = string.Format("堆垛机[{0}]执行异常,消息:{1}", PlcName, ex.ToString());
  76. LogMessageHelper.RecordLogMessage(errormsg, ex);
  77. }
  78. finally
  79. {
  80. Interlocked.Exchange(ref _locExecute, 0);
  81. }
  82. }
  83. }
  84. /// <summary>
  85. /// 加载堆垛机刷新数据
  86. /// </summary>
  87. private void Init_Refresh()
  88. {
  89. var srmconvinfoset = Current.WCS_SrmOutInInfoSet.Where(v => v.SRMOUTIN_SRMNO == PlcName && v.SRMOUTIN_ISSTOP == false).OrderBy(p => p.SRMOUTIN_PRIORITY).OrderBy(t => t.SRMOUTIN_SEQUENCE).ToList();
  90. if (SrmOutInInfoSet.Count != srmconvinfoset.Count || //元素个数不相同
  91. srmconvinfoset.Any(v => v.SRMOUTIN_ISUPDATE)) //元素已更新
  92. {
  93. SrmOutInInfoSet = srmconvinfoset;
  94. SugarBase.DB.Updateable<WCS_SrmOutInInfo>(it => new WCS_SrmOutInInfo() { SRMOUTIN_ISUPDATE = false })
  95. .Where(it => it.SRMOUTIN_SRMNO == PlcName)
  96. .ExecuteCommand();
  97. }
  98. }
  99. /// <summary>
  100. /// 写入心跳
  101. /// </summary>
  102. protected void WriteHandShake()
  103. {
  104. int heartbeat = 0;
  105. if (EquSignal.DB521_Handshake_to_wcs)
  106. {
  107. if (EquSignal.DB520_Handshake_from_wcs == 0)
  108. {
  109. heartbeat = 1;
  110. }
  111. }
  112. else
  113. {
  114. if (EquSignal.DB520_Handshake_from_wcs == 1)
  115. {
  116. heartbeat = 0;
  117. }
  118. }
  119. //写入心跳
  120. if (WCS_PLCItem.Plc.WriteSignal((ushort)WriteDbName, 0, 2, heartbeat) == false)
  121. {
  122. Log4netHelper.Logger_Error.ErrorFormat(string.Format("堆垛机PLC[{0}]写入心跳失败", PlcName));
  123. //throw new Exception(string.Format("堆垛机PLC[{0}]写入心跳失败", SrmNo));
  124. }
  125. }
  126. /// <summary>
  127. /// 堆垛机任务完成
  128. /// </summary>
  129. protected virtual void SRMCompleteTask()
  130. {
  131. try
  132. {
  133. //当前任务完成
  134. if (EquSignal.DB521_Task_Finishi == false) return;
  135. //查询任务
  136. var task = SugarBase.DB.Queryable<WCS_TASK>().First(v => v.TASK_NO == EquSignal.DB521_Taskfinishi_ID);
  137. if (task == null) return;
  138. if (task.TASK_WKSTATUS >= 99) return;
  139. if ((task.TASK_COMTYPE == (int)ComTypeEnum.入库 && task.TASK_POSIDTO.Length > 5) || task.TASK_COMTYPE == (int)ComTypeEnum.移库)
  140. {
  141. //完成任务
  142. string result = TryCachHelper.TryTranExecute((db) =>
  143. {
  144. //修改任务的状态
  145. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = 99, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  146. .Where(it => it.TASK_NO == task.TASK_NO)
  147. .ExecuteCommand();
  148. //添加修改明细
  149. string msg = string.Format("任务[{0}]完成", task.TASK_NO);
  150. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, task.TASK_POSIDTO, msg);
  151. });
  152. DateTime lastfinishtime = SugarBase.DB.GetDate();
  153. //更新最后完成时间
  154. SugarBase.DB.Updateable<WCS_PLC>(it => new WCS_PLC() { PLC_LASTFINISHTIME = lastfinishtime }).Where(it => it.PLC_NAME == task.TASK_SRMNO).ExecuteCommand();
  155. if (string.IsNullOrWhiteSpace(result))
  156. {
  157. if (task.TASK_COMTYPE == (int)ComTypeEnum.入库)
  158. {
  159. SrmConvNoMoveToLast(task.TASK_POSIDCUR);
  160. }
  161. }
  162. }
  163. else if (task.TASK_COMTYPE == (int)ComTypeEnum.出库 || task.TASK_COMTYPE == (int)ComTypeEnum.搬运)
  164. {
  165. if (task.TASK_WKSTATUS == (int)WkStatus.堆垛机执行)
  166. {
  167. //var routeSet = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO);
  168. //var routes = routeSet.Where(v => v.ROUTE_STARTPOS == task.TASK_SRMNO).ToList();
  169. //var route = QueryOutEquRouteItem(task, routes);
  170. int wksstatus = 6;
  171. //if (route.ISEND)
  172. //{
  173. // wksstatus = 99;
  174. //}
  175. string result = TryCachHelper.TryTranExecute((db) =>
  176. {
  177. //修改任务的状态
  178. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = wksstatus, TASK_POSIDCUR = task.TASK_POSIDNEXT, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  179. .Where(it => it.TASK_NO == task.TASK_NO)
  180. .ExecuteCommand();
  181. //添加修改明细
  182. string msg = string.Format("任务[{0}]堆垛机完成,修改当前地址为[{1}]", task.TASK_NO, task.TASK_POSIDNEXT);
  183. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDNEXT, task.TASK_POSIDNEXT, msg);
  184. });
  185. DateTime lastfinishtime = SugarBase.DB.GetDate();
  186. //更新最后完成时间
  187. SugarBase.DB.Updateable<WCS_PLC>(it => new WCS_PLC() { PLC_LASTFINISHTIME = lastfinishtime }).Where(it => it.PLC_NAME == task.TASK_SRMNO).ExecuteCommand();
  188. if (string.IsNullOrWhiteSpace(result))
  189. {
  190. SrmConvNoMoveToLast(task.TASK_POSIDNEXT);
  191. }
  192. }
  193. }
  194. //TaskComplete(task.TASK_SRMNO, task.TASK_ID, task.TASK_COMTYPE);
  195. }
  196. catch (Exception ex)
  197. {
  198. LogMessageHelper.RecordLogMessage(ex);
  199. }
  200. }
  201. /// <summary>
  202. /// 调整堆垛机出入口顺序
  203. /// </summary>
  204. /// <param name="convNo"></param>
  205. private void SrmConvNoMoveToLast(string convNo)
  206. {
  207. //检测是否是最后一项
  208. if (SrmOutInInfoSet[SrmOutInInfoSet.Count() - 1].SRMOUTIN_CONVNO == convNo) return;
  209. //查询要调整执行顺序的输送线
  210. var outininfo = SrmOutInInfoSet.FirstOrDefault(v => v.SRMOUTIN_CONVNO == convNo);
  211. //删除当前
  212. SrmOutInInfoSet.Remove(outininfo);
  213. //添加到最后
  214. SrmOutInInfoSet.Add(outininfo);
  215. }
  216. /// <summary>
  217. /// 任务完成
  218. /// </summary>
  219. /// <param name="db"></param>
  220. /// <param name="conveyorOut">设备编号</param>
  221. /// <param name="taskno">任务号</param>
  222. /// <param name="temptype">类型 1:入库任务完成 2:堆垛机出库任务完成 3.移库完成 4:出库任务完成 5.堆垛机码盘完成</param>
  223. //public void TaskComplete(string equNo, string task_id, int temptype)
  224. //{
  225. // var param = new TASKCOMPLETEPARAM();
  226. // param.TASK_ID = task_id;
  227. // param.FINISHTYPE = temptype;
  228. // RESULTINFO result = Current.WmsInterface.TASKCOMPLETE(param);
  229. // if (result.ISSUCCESS)
  230. // {
  231. // Log4netHelper.Logger_Info.InfoFormat(string.Format("堆垛机[{0}]完成WMS任务成功,传递参数:任务号[{1}]类型[{2}]反馈消息:[{3}]", equNo, task_id, temptype, result.MASSAGE));
  232. // }
  233. // else
  234. // {
  235. // Log4netHelper.Logger_Error.ErrorFormat(string.Format("堆垛机[{0}]完成WMS任务失败,传递参数:任务号[{1}]类型[{2}]反馈消息:[{3}]", equNo, task_id, temptype, result.MASSAGE));
  236. // }
  237. //}
  238. private void SRMStartExecuteTask()
  239. {
  240. //检测堆垛机模式
  241. if (EquSignal.DB521_Auto_status != (int)SrmModeEnum.远程) return;
  242. //检测堆垛机报警
  243. if (EquSignal.SrmDB541_Alarm) return;
  244. //检测堆垛机状态
  245. if (EquSignal.DB521_Srm_Status != (int)SrmStateFork1Enum.空闲) return;
  246. if (EquSignal.DB520_Task_trigger != 0) return;
  247. //检测堆垛机禁用
  248. //if (Current.SysSets.FirstOrDefault(v => v.SET_ID == SrmNo).SET_VALUE.Trim() == "1") return;
  249. TryCachHelper.TryExecute((db) =>
  250. {
  251. var taskSet = db.Queryable<WCS_TASK>().Where(v => v.TASK_SRMNO == PlcName).ToList();
  252. var task = taskSet.FirstOrDefault(v => (v.TASK_WKSTATUS == (int)WkStatus.堆垛机执行));
  253. if (task == null)
  254. {
  255. //移库
  256. if (PlcName == "srm01")
  257. {
  258. var firsttask = SugarBase.DB.Queryable<WCS_TASK>().Where(v => v.TASK_SRMNO == PlcName && v.TASK_COMTYPE == 2 && v.TASK_WKSTATUS <= 1).OrderBy(v => v.TASK_ADDDATETIME).First();
  259. if (firsttask == null)
  260. {
  261. //移库
  262. if (MoveStock(db)) return;
  263. }
  264. else
  265. {
  266. var dtime = SugarBase.DB.GetDate();
  267. if (firsttask.TASK_ADDDATETIME.AddMinutes(20) > dtime)//出库任务在20分钟内
  268. {
  269. //移库
  270. if (MoveStock(db)) return;
  271. }
  272. }
  273. }
  274. else
  275. {
  276. //移库
  277. if (MoveStock(db)) return;
  278. }
  279. taskSet = taskSet.Where(v => v.TASK_WKSTATUS <= 2).ToList();
  280. OutInStock(db, taskSet);
  281. }
  282. else
  283. {
  284. Log4netHelper.Logger_Error.ErrorFormat(string.Format("堆垛机[{0}]状态正常,但是存在执行中的任务[{1}]", PlcName, task.TASK_NO));
  285. }
  286. });
  287. }
  288. protected bool MoveStock(SqlSugarClient db)
  289. {
  290. bool result = false;
  291. var task = QueryMoveTask(db);
  292. if (task == null) return result;
  293. if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == WCS_PLCItem.PLC_NAME)
  294. {
  295. //分配货位
  296. bool assignresult = GetWareCell(task);
  297. if (assignresult == false) return result;
  298. //分配货位
  299. //bool assignresult = WareCell_Assign(db, task);
  300. //if (assignresult == false) return result;
  301. }
  302. var writeSignal = new WCSWriteToSrmSignal();
  303. writeSignal.Start_number = 0;
  304. writeSignal.End_number = 0;
  305. writeSignal.Goodtype = 0;
  306. //查询货位表巷道,深度
  307. //var location1 = db.Queryable<BASE_WARECELL>().First(v => v.F_NO == task.TASK_POSIDFROM);
  308. writeSignal.RowPos1 = task.FromRow; // location1.F_LINE;
  309. writeSignal.Travelpos1 = task.FromCol;
  310. writeSignal.Liftpos1 = task.FromLayer;
  311. //writeSignal.Fork_start_pos1 = location1.F_DEPTH;
  312. writeSignal.End_number = 0;
  313. //查询货位表巷道,深度
  314. //var location2 = db.Queryable<BASE_WARECELL>().First(v => v.F_NO == task.TASK_POSIDTO);
  315. writeSignal.RowPos2 = task.ToRow;//location2.F_LINE;
  316. writeSignal.Travelpos2 = task.ToCol;
  317. writeSignal.Liftpos2 = task.ToLayer;
  318. //writeSignal.Fork_dest_pos2 = location2.F_DEPTH;
  319. writeSignal.TaskID = task.TASK_NO;
  320. writeSignal.End_number = 0;
  321. //执行任务
  322. SrmOutIn(writeSignal, task.TASK_POSIDFROM, task.TASK_POSIDTO);
  323. result = true;
  324. return result;
  325. }
  326. private WCS_TASK QueryMoveTask(SqlSugarClient db)
  327. {
  328. WCS_TASK task = null;
  329. var movetaskSet = db.Queryable<WCS_TASK>().Where(v => v.TASK_COMTYPE == (int)ComTypeEnum.移库 && v.TASK_WKSTATUS <= 1 && v.TASK_SRMNO == WCS_PLCItem.PLC_NAME).ToList();
  330. if (movetaskSet.Count > 0) task = movetaskSet[0];
  331. return task;
  332. }
  333. public bool GetWareCell(WCS_TASK task)
  334. {
  335. string resultMsg = string.Empty;
  336. //调度接口获取货位
  337. var getWareCell = Current.WmsInterface.I_WCS_GetWareCell(new GetWareCellParam() { WMSTaskNum = task.TASK_WMSNO.ToString(), TunnelNum = task.TASK_EndTunnelNum, PickUpEquipmentNo = task.TASK_POSIDNEXT });
  338. if (getWareCell.ResType)
  339. {
  340. resultMsg = TryCachHelper.TryTranExecute((db) =>
  341. {
  342. //修改任务分配货位
  343. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = 2, TASK_POSIDNEXT = getWareCell.CellNo, TASK_POSIDTO = getWareCell.CellNo, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  344. .Where(it => it.TASK_NO == task.TASK_NO)
  345. .ExecuteCommand();
  346. //添加修改明细
  347. string msg = string.Format("任务[{0}]分配货位[{1}]成功。", task.TASK_NO, getWareCell.CellNo);
  348. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, task.TASK_POSIDNEXT, msg);
  349. });
  350. }
  351. else
  352. {
  353. resultMsg = string.Format("任务[{0}]调用接口分配货位[{1}]失败,原因:{2}", task.TASK_NO, getWareCell.CellNo, getWareCell.ResMessage);
  354. LogMessageHelper.RecordLogMessage(resultMsg);
  355. }
  356. if (string.IsNullOrWhiteSpace(resultMsg))
  357. {
  358. task.TASK_POSIDNEXT = getWareCell.CellNo;
  359. task.TASK_POSIDTO = getWareCell.CellNo;
  360. return true;
  361. }
  362. else
  363. {
  364. return false;
  365. }
  366. }
  367. //public bool WareCell_Assign(SqlSugarClient db, WCS_TASK task)
  368. //{
  369. // bool result = false;
  370. // Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]开始分配货位", task.TASK_NO));
  371. // var param = new WARECELL_ASSIGNPARAM();
  372. // param.TASK_ID = task.TASK_ID;
  373. // var posIdToMsg = Current.WmsInterface.WARECELL_ASSIGN(param);
  374. // string posIdTo = posIdToMsg.MSGCODE;
  375. // Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]分配货位结束,得到货位[{1}]", task.TASK_NO, posIdTo));
  376. // if (string.IsNullOrWhiteSpace(posIdToMsg.MSGCODE))
  377. // {
  378. // Log4netHelper.Logger_Error.ErrorFormat(posIdToMsg.MASSAGE);
  379. // }
  380. // else
  381. // {
  382. // Log4netHelper.Logger_Info.InfoFormat(posIdToMsg.MASSAGE);
  383. // var wcs_task = db.Queryable<WCS_TASK>().First(v => v.TASK_POSIDTO == posIdTo);
  384. // var warecell = db.Queryable<BASE_WARECELL>().First(v => v.F_NO == posIdTo);
  385. // if (warecell.F_STATENUM != 1)
  386. // {
  387. // Log4netHelper.Logger_Error.ErrorFormat(string.Format("货位[{0}]非空闲,分配货位错误", posIdTo));
  388. // }
  389. // else if (wcs_task != null)
  390. // {
  391. // Log4netHelper.Logger_Info.InfoFormat("货位[{0}]已经分配给任务[{1}]不能分给当前任务[{2}]", posIdTo, wcs_task.TASK_NO, task.TASK_NO);
  392. // }
  393. // //else if (posIdTo == lastastWareCell)
  394. // //{
  395. // // Current.Logger_Info.InfoFormat("任务[{0}]分配货位[{1}]当前状态[{2}]", task.TASK_NO, posIdTo, warecell.F_STATENUM);
  396. // // Current.Logger_Info.InfoFormat("任务[{0}]堆垛机[{1}]上次分配货位[{2}]本次分配货位[{3}],不能是相同货位。", task.TASK_NO, task.TASK_SRMNO, lastastWareCell, posIdTo);
  397. // //}
  398. // else
  399. // {
  400. // task.TASK_POSIDTO = posIdTo;
  401. // string assignresult = TryCachHelper.TryExecute((db2) => {
  402. // //更新任务目标地址
  403. // if (db2.Updateable<WCS_TASK>(v => new WCS_TASK() { TASK_POSIDTO = task.TASK_POSIDTO })
  404. // .Where(it => it.TASK_NO == task.TASK_NO)
  405. // .ExecuteCommand() < 0)
  406. // {
  407. // throw new Exception(string.Format("任务[{0}]更新目标地址为[{1}]失败", task.TASK_NO, task.TASK_POSIDTO));
  408. // }
  409. // //锁货位
  410. // //if (db2.Updateable<BASE_WARECELL>(v => new BASE_WARECELL() { F_STATENUM = 3 })
  411. // // .Where(it => it.F_NO == task.TASK_POSIDTO)
  412. // // .ExecuteCommand() < 0)
  413. // //{
  414. // // throw new Exception(string.Format("任务[{0}]锁定货位[{1}]失败", task.TASK_NO, task.TASK_POSIDTO));
  415. // //}
  416. // });
  417. // if (string.IsNullOrWhiteSpace(assignresult))
  418. // {
  419. // var base_warecell = db.Queryable<BASE_WARECELL>().First(v => v.F_NO == posIdTo);
  420. // if (base_warecell.F_STATENUM == 3)
  421. // {
  422. // Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]锁定货位[{1}]成功", task.TASK_NO, posIdTo));
  423. // //lastastWareCell = posIdTo;
  424. // }
  425. // else
  426. // {
  427. // Log4netHelper.Logger_Info.ErrorFormat(string.Format("任务[{0}]锁定货位[{1}]失败,请检测原因", task.TASK_NO, posIdTo));
  428. // result = false;
  429. // }
  430. // result = true;
  431. // }
  432. // }
  433. // }
  434. // return result;
  435. //}
  436. private void SrmOutIn(WCSWriteToSrmSignal srmSignal, string startPos, string posIdnext)
  437. {
  438. if (EquSignal.DB520_Start_number == srmSignal.Start_number &&
  439. EquSignal.DB520_End_number == srmSignal.End_number &&
  440. EquSignal.DB520_Goodtype == srmSignal.Goodtype &&
  441. EquSignal.DB520_Runmode == srmSignal.Runmode &&
  442. EquSignal.DB520_FromRowPos == srmSignal.RowPos1 &&
  443. EquSignal.DB520_FromColumnPos == srmSignal.Travelpos1 &&
  444. EquSignal.DB520_FromLayerPos == srmSignal.Liftpos1 &&
  445. EquSignal.DB520_Fork_start_pos1 == srmSignal.Fork_start_pos1 &&
  446. EquSignal.DB520_ToRowPos == srmSignal.RowPos2 &&
  447. EquSignal.DB520_ToColumnPos == srmSignal.Travelpos2 &&
  448. EquSignal.DB520_ToLayerPos == srmSignal.Liftpos2 &&
  449. EquSignal.DB520_Fork_dest_pos2 == srmSignal.Fork_dest_pos2 &&
  450. EquSignal.DB520_TaskID == srmSignal.TaskID)
  451. {
  452. string result = TryCachHelper.TryTranExecute((db) =>
  453. {
  454. var task = db.Queryable<WCS_TASK>().First(t => t.TASK_NO == srmSignal.TaskID);
  455. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.堆垛机执行, TASK_POSIDNEXT = posIdnext, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  456. .Where(it => it.TASK_NO == srmSignal.TaskID).ExecuteCommand();
  457. string msg = string.Format("任务[{0}]已下发给堆垛机执行,起点位置[{1}]目标地址[{2}]", task.TASK_NO, startPos, posIdnext);
  458. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, posIdnext, msg);
  459. if (EquSignal.DB520_Task_trigger != 1)
  460. {
  461. string mes = string.Format("读取plc信息:任务号[{0}]起始行[{1}]起始列[{2}]起始层[{3}]目标行[{4}]目标列[{5}]目标层[{6}]",
  462. EquSignal.DB520_TaskID, EquSignal.DB520_FromRowPos, EquSignal.DB520_FromColumnPos, EquSignal.DB520_FromLayerPos,
  463. EquSignal.DB520_ToRowPos, EquSignal.DB520_ToColumnPos, EquSignal.DB520_ToLayerPos);
  464. Log4netHelper.Logger_Info.InfoFormat(mes);
  465. if (WCS_PLCItem.Plc.WriteSignal((ushort)WriteDbName, 30, 2, 1))
  466. {
  467. Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]写入触发信号成功。", srmSignal.TaskID));
  468. }
  469. else
  470. {
  471. throw new Exception(string.Format("任务[{0}]写入触发信号失败。", srmSignal.TaskID));
  472. }
  473. }
  474. });
  475. if (!string.IsNullOrWhiteSpace(result))
  476. {
  477. throw new Exception(string.Format("任务[{0}]堆垛机执行失败,原因:[{1}]", srmSignal.TaskID, result));
  478. }
  479. }
  480. else
  481. {
  482. WriteTaskToSrm(srmSignal);
  483. }
  484. }
  485. private void SrmOutIn2(WCSWriteToSrmSignal srmSignal, string startPos, string posIdnext)
  486. {
  487. string result = TryCachHelper.TryTranExecute((db) =>
  488. {
  489. var task = db.Queryable<WCS_TASK>().First(t => t.TASK_NO == srmSignal.TaskID);
  490. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.堆垛机执行, TASK_POSIDNEXT = posIdnext, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  491. .Where(it => it.TASK_NO == srmSignal.TaskID).ExecuteCommand();
  492. string msg = string.Format("任务[{0}]已下发给堆垛机执行,起点位置[{1}]目标地址[{2}]", task.TASK_NO, startPos, posIdnext);
  493. CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, posIdnext, msg);
  494. List<byte> list = new List<byte>();
  495. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Start_number).ToList());
  496. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.End_number).ToList());
  497. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Goodtype).ToList());
  498. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Runmode).ToList());
  499. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.RowPos1).ToList());
  500. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Travelpos1).ToList());
  501. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Liftpos1).ToList());
  502. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Fork_start_pos1).ToList());
  503. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.RowPos2).ToList());
  504. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Travelpos2).ToList());
  505. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Liftpos2).ToList());
  506. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Fork_dest_pos2).ToList());
  507. list.AddRange(ExtendsUtil.UintToByte((uint)srmSignal.TaskID).ToList());
  508. ushort trigger = 1;
  509. list.AddRange(ExtendsUtil.UshortToByte(trigger).ToList());
  510. Log4netHelper.Logger_Info.InfoFormat(string.Format("写入任务[{0}]信息", srmSignal.TaskID));
  511. if (WCS_PLCItem.Plc.Write((ushort)WriteDbName, 2, list.ToArray()))
  512. {
  513. Log4netHelper.Logger_Info.InfoFormat(string.Format("堆垛机[{0}]写入任务[{1}]信息成功", PlcName, srmSignal.TaskID));
  514. }
  515. else
  516. {
  517. throw new Exception(string.Format("堆垛机[{0}]写入任务[{1}]信息失败", PlcName, srmSignal.TaskID));
  518. }
  519. });
  520. if (!string.IsNullOrWhiteSpace(result))
  521. {
  522. throw new Exception(string.Format("任务[{0}]堆垛机执行失败,原因:[{1}]", srmSignal.TaskID, result));
  523. }
  524. }
  525. private void WriteTaskToSrm(WCSWriteToSrmSignal srmSignal)
  526. {
  527. List<byte> list = new List<byte>();
  528. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Start_number).ToList());
  529. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.End_number).ToList());
  530. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Goodtype).ToList());
  531. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Runmode).ToList());
  532. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.RowPos1).ToList());
  533. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Travelpos1).ToList());
  534. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Liftpos1).ToList());
  535. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Fork_start_pos1).ToList());
  536. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.RowPos2).ToList());
  537. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Travelpos2).ToList());
  538. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Liftpos2).ToList());
  539. list.AddRange(ExtendsUtil.UshortToByte((ushort)srmSignal.Fork_dest_pos2).ToList());
  540. list.AddRange(ExtendsUtil.UintToByte((uint)srmSignal.TaskID).ToList());
  541. Log4netHelper.Logger_Info.InfoFormat(string.Format("写入任务[{0}]信息", srmSignal.TaskID));
  542. bool result = WCS_PLCItem.Plc.Write((ushort)WriteDbName, 2, list.ToArray());
  543. if (result)
  544. {
  545. Log4netHelper.Logger_Info.InfoFormat(string.Format("堆垛机[{0}]写入任务[{1}]信息成功", PlcName, srmSignal.TaskID));
  546. }
  547. else
  548. {
  549. throw new Exception(string.Format("堆垛机[{0}]写入任务[{1}]信息失败", PlcName, srmSignal.TaskID));
  550. }
  551. }
  552. private void OutInStock(SqlSugarClient db, List<WCS_TASK> tasks)
  553. {
  554. if (tasks.Count == 0) return;
  555. int taskMaxPriority = tasks.Max(v => v.TASK_PRIORITY);
  556. for (int index = taskMaxPriority; index >= 0; index--)
  557. {
  558. var tasks_Temp = tasks.Where(v => v.TASK_PRIORITY == index).ToList();
  559. if (tasks_Temp.Count > 0)
  560. {
  561. var task = QueryTask2(db, tasks_Temp);
  562. if (task != null)
  563. {
  564. if (task.TASK_COMTYPE == (int)ComTypeEnum.入库)
  565. {
  566. if (InStock(db, task)) break;
  567. }
  568. else if (task.TASK_COMTYPE == (int)ComTypeEnum.出库)
  569. {
  570. if (OutStock(db, task)) break;
  571. }
  572. else if (task.TASK_COMTYPE == (int)ComTypeEnum.搬运)
  573. {
  574. if (Carry(db, task)) break;
  575. }
  576. }
  577. }
  578. }
  579. }
  580. private WCS_TASK QueryTask2(SqlSugarClient db, List<WCS_TASK> tasks)
  581. {
  582. WCS_TASK wcs_task = null;
  583. //克隆集合
  584. List<WCS_SrmOutInInfo> outininfoSet = SrmOutInInfoSet.GetRange(0, SrmOutInInfoSet.Count);
  585. foreach (var outininfo in outininfoSet)
  586. {
  587. if (outininfo.SRMOUTIN_OUTINTYPE == "in" || outininfo.SRMOUTIN_OUTINTYPE == "outIn")
  588. {
  589. var intasks = tasks.SingleOrDefault(v => v.TASK_WKSTATUS != (int)WkStatus.堆垛机执行 &&
  590. v.TASK_POSIDCUR == outininfo.SRMOUTIN_CONVNO &&
  591. //v.TASK_POSIDNEXT == outininfo.SRMOUTIN_CONVNO &&
  592. (v.TASK_COMTYPE == 1 || v.TASK_COMTYPE == 4));
  593. if (intasks != null)
  594. {
  595. var temptask = QueryInConvTask(outininfo, intasks);
  596. if (temptask != null)
  597. {
  598. wcs_task = temptask;
  599. break;
  600. }
  601. }
  602. }
  603. if (outininfo.SRMOUTIN_OUTINTYPE == "out" || outininfo.SRMOUTIN_OUTINTYPE == "outIn")
  604. {
  605. //检测出口状态
  606. var convSignal = ConveyorHelper.GetConveyorSignal(outininfo.SRMOUTIN_CONVPLCNAME, outininfo.SRMOUTIN_CONVNO);
  607. if (convSignal.DB521_Request == false && convSignal.DB521_Tasknum <= 0 && convSignal.CvDB51_PH_Status == false)
  608. {
  609. var outTask = db.Queryable<WCS_TASK>().First(v => v.TASK_POSIDCUR == outininfo.SRMOUTIN_CONVNO);
  610. if (outTask == null ||
  611. ((outTask.TASK_WKSTATUS != (int)WkStatus.输送机执行) && (outTask.TASK_WKSTATUS != (int)WkStatus.堆垛机完成)))
  612. {
  613. //检测是否存在该出口的任务列表
  614. List<WCS_TASK> list = new List<WCS_TASK>();
  615. var taskList = tasks.Where(v => v.TASK_COMTYPE == 2 && v.TASK_WKSTATUS <= 1).ToList();
  616. WCS_EQUIPMENTROUTE routeitem = null;
  617. foreach (var task in taskList)
  618. {
  619. var routes = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO).Where(v => v.ROUTE_STARTPOS == PlcName).ToList();
  620. routeitem = routes.FirstOrDefault(v => v.ROUTE_SONPOS == outininfo.SRMOUTIN_CONVNO);
  621. //if (CurrentRoute == null)
  622. //{
  623. // LogMessageHelper.RecordLogMessage(string.Format("任务[{0}]目标地址[{1}]堆垛机[{2}]没有查询到路由。", task.TASK_NO, task.TASK_POSIDTO, PlcName));
  624. //}
  625. if (routeitem != null && CheckAreaOutAddress(task, routeitem))
  626. {
  627. if (task.TASK_WKSTATUS <= 1)
  628. {
  629. list.Add(task);
  630. }
  631. }
  632. }
  633. //有任务则调用虚方法并返回要执行的任务
  634. var curouttask = QueryOutTask(db, list);
  635. if (curouttask != null)
  636. {
  637. wcs_task = curouttask;
  638. break;
  639. }
  640. }
  641. }
  642. }
  643. //无任务则移动到最后
  644. SrmConvNoMoveToLast(outininfo.SRMOUTIN_CONVNO);
  645. }
  646. return wcs_task;
  647. }
  648. /// <summary>
  649. /// 查询堆垛机入库口任务
  650. /// </summary>
  651. protected virtual WCS_TASK QueryInConvTask(WCS_SrmOutInInfo outininfo, WCS_TASK task)
  652. {
  653. WCS_TASK wcs_task = null;
  654. var convSignal = ConveyorHelper.GetConveyorSignal(outininfo.SRMOUTIN_CONVPLCNAME, outininfo.SRMOUTIN_CONVNO);
  655. if (convSignal.DB521_Tasknum == task.TASK_NO && convSignal.CvDB51_PH_Status
  656. //&& convSignal.DB521_Goodsend.ToString() == outininfo.SRMOUTIN_CONVNO
  657. )
  658. {
  659. if (task.TASK_COMTYPE == 1)
  660. {
  661. if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == PlcName)
  662. {
  663. wcs_task = null;
  664. }
  665. else
  666. {
  667. wcs_task = task;
  668. }
  669. }
  670. else if (task.TASK_COMTYPE == 4)
  671. {
  672. var route = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO).FirstOrDefault(v => v.ROUTE_STARTPOS == PlcName);
  673. var srmoutin = SrmOutInInfoSet.SingleOrDefault(v => v.SRMOUTIN_CONVNO == route.ROUTE_NEXTPOS && v.SRMOUTIN_SRMNO == PlcName);
  674. //检测出口状态
  675. var outConv = ConveyorHelper.GetConveyorSignal(srmoutin.SRMOUTIN_CONVPLCNAME, srmoutin.SRMOUTIN_CONVNO);
  676. if (outConv.DB521_Tasknum == 0 && outConv.CvDB51_PH_Status == false)
  677. {
  678. wcs_task = task;
  679. }
  680. }
  681. }
  682. return wcs_task;
  683. }
  684. //private WCS_TASK QueryTask(SqlSugarClient db, List<WCS_TASK> tasks)
  685. //{
  686. // WCS_TASK wcs_task = null;
  687. // //查询最小优先级
  688. // int priority = SrmOutInInfoSet.Max(v => v.SRMOUTIN_PRIORITY);
  689. // for (int index = 1; index <= priority; index++)
  690. // {
  691. // //查询相同优先级的出入口
  692. // var outininfoSet_temp = SrmOutInInfoSet.Where(v => v.SRMOUTIN_PRIORITY == index && v.SRMOUTIN_ISSTOP == false).ToList();
  693. // //克隆集合
  694. // List<WCS_SrmOutInInfo> outininfoSet = outininfoSet_temp.GetRange(0, outininfoSet_temp.Count);
  695. // foreach (var outininfo in outininfoSet)
  696. // {
  697. // if (outininfo.SRMOUTIN_OUTINTYPE == "in")
  698. // {
  699. // //检测入库口状态
  700. // var convSignal = ConveyorHelper.GetConveyorSignal(outininfo.SRMOUTIN_CONVPLCNAME, outininfo.SRMOUTIN_CONVNO);
  701. // if (convSignal.DB521_Tasknum > 0 &&
  702. // convSignal.DB521_Goodsend.ToString() == outininfo.SRMOUTIN_CONVNO)
  703. // {
  704. // var curtask = tasks.FirstOrDefault(v => v.TASK_NO == convSignal.DB521_Tasknum);
  705. // if (curtask != null && curtask.TASK_WKSTATUS != (int)WkStatus.堆垛机执行)
  706. // {
  707. // wcs_task = curtask;
  708. // break;
  709. // }
  710. // }
  711. // }
  712. // else if (outininfo.SRMOUTIN_OUTINTYPE == "out")
  713. // {
  714. // //检测出口状态
  715. // var convSignal = ConveyorHelper.GetConveyorSignal(outininfo.SRMOUTIN_CONVPLCNAME, outininfo.SRMOUTIN_CONVNO);
  716. // if (convSignal.DB521_Request == false && convSignal.DB521_Tasknum <= 0)
  717. // {
  718. // var curOutTask = db.Queryable<WCS_TASK>().First(v => v.TASK_POSIDCUR == outininfo.SRMOUTIN_CONVNO);
  719. // if (curOutTask == null ||
  720. // ((curOutTask.TASK_WKSTATUS != (int)WkStatus.输送机执行) && (curOutTask.TASK_WKSTATUS != (int)WkStatus.堆垛机完成)))
  721. // {
  722. // //检测是否存在该出口的任务列表
  723. // List<WCS_TASK> list = new List<WCS_TASK>();
  724. // foreach (var task in tasks)
  725. // {
  726. // var route = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO).FirstOrDefault(v => v.ROUTE_STARTPOS == SrmNo);
  727. // if (route == null)
  728. // {
  729. // Log4netHelper.Logger_Error.ErrorFormat(string.Format("任务[{0}]目标地址[{1}]堆垛机[{2}]", task.TASK_NO, task.TASK_POSIDTO, SrmNo));
  730. // }
  731. // if (outininfo.SRMOUTIN_CONVNO == route.ROUTE_NEXTPOS)
  732. // {
  733. // if (task.TASK_WKSTATUS <= 1)
  734. // {
  735. // list.Add(task);
  736. // }
  737. // }
  738. // }
  739. // //有任务则调用虚方法并返回要执行的任务
  740. // var curouttask = QueryOutTask(db, list);
  741. // if (curOutTask != null)
  742. // {
  743. // wcs_task = curouttask;
  744. // break;
  745. // }
  746. // }
  747. // }
  748. // }
  749. // //无任务则移动到最后
  750. // SrmConvNoMoveToLast(outininfo.SRMOUTIN_CONVNO);
  751. // }
  752. // }
  753. // return wcs_task;
  754. //}
  755. protected bool InStock(SqlSugarClient db, WCS_TASK task)
  756. {
  757. bool result = false;
  758. if (task != null)
  759. {
  760. //检测任务当前位置存在于srm当前入口输送线列表中
  761. if (SrmOutInInfoSet.Any(v => v.SRMOUTIN_CONVNO == task.TASK_POSIDCUR && (v.SRMOUTIN_OUTINTYPE == "in" || v.SRMOUTIN_OUTINTYPE=="outIn")))
  762. {
  763. if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == PlcName)
  764. {
  765. //分配货位
  766. //bool assignresult = GetWareCell(task); //WareCell_Assign(db, task);
  767. //if (assignresult == false) return false;
  768. Log4netHelper.Logger_Error.ErrorFormat(string.Format("任务[{0}]未分配货位,堆垛机不能执行", task.TASK_NO));
  769. return false;
  770. }
  771. //task = db.Queryable<WCS_TASK>().First(v => v.TASK_NO == task.TASK_NO);
  772. //if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == SrmNo)
  773. //{
  774. // throw new Exception(string.Format("任务[{0}]未分配货位。", task.TASK_NO));
  775. //}
  776. //else
  777. //{
  778. // Log4netHelper.Logger_Info.InfoFormat("任务[{0}]货位分配成功", task.TASK_NO);
  779. //}
  780. var writeSignal = new WCSWriteToSrmSignal();
  781. writeSignal.Start_number = 0;
  782. writeSignal.Goodtype = 0;
  783. if (task.TASK_COMTYPE == 4)//移动
  784. {
  785. //var startCvToEnd = ConveyorHelper.SrmMoveCvSet.FirstOrDefault(v => v.StartConveyor == task.TASK_POSIDCUR);
  786. //writeSignal.RowPos1 = startCvToEnd.SrmStartRow;
  787. //writeSignal.Travelpos1 = startCvToEnd.SrmStartColumn;
  788. //writeSignal.Liftpos1 = startCvToEnd.SrmStartLayer;
  789. //writeSignal.Fork_start_pos1 = startCvToEnd.SrmStartDepth;
  790. //writeSignal.RowPos2 = startCvToEnd.SrmEndRow;
  791. //writeSignal.Travelpos2 = startCvToEnd.SrmEndColumn;
  792. //writeSignal.Liftpos2 = startCvToEnd.SrmEndLayer;
  793. //writeSignal.Fork_dest_pos2 = startCvToEnd.SrmEndDepth;
  794. }
  795. else
  796. {
  797. var route = Current.EquRouteSet.FirstOrDefault(v => v.ROUTE_STARTPOS == task.TASK_POSIDCUR);
  798. writeSignal.RowPos1 = (int)route.SRMROW;
  799. writeSignal.Travelpos1 = (int)route.SRMCOLUMN;
  800. writeSignal.Liftpos1 = (int)route.SRMLAYER;
  801. //writeSignal.Fork_start_pos1 = (int)route.DEPTH;
  802. //查询货位表巷道,深度
  803. //var location = db.Queryable<Base_Location>().First(v => v.Loc_No == task.TASK_POSIDTO);
  804. writeSignal.RowPos2 = task.ToRow;// location.Loc_Tunnel;
  805. writeSignal.Travelpos2 = task.ToCol;
  806. writeSignal.Liftpos2 = task.ToLayer;
  807. //writeSignal.Fork_dest_pos2 = task.ToDepth; //location.Loc_Depth;
  808. }
  809. //if (task.TASK_COMTYPE == 5)
  810. //{
  811. // var warecell = db.Queryable<BASE_WARECELL>().First(v => v.F_NO == task.TASK_POSIDTO);
  812. // int count = db.Queryable<BILL_INVCONTR>().Where(v => v.F_CONTRGRPNO == warecell.F_CNTRGRPNO).Count();
  813. // writeSignal.End_number = count;
  814. //}
  815. writeSignal.TaskID = task.TASK_NO;
  816. //执行任务
  817. SrmOutIn(writeSignal, task.TASK_POSIDCUR, task.TASK_POSIDTO);
  818. result = true;
  819. }
  820. }
  821. return result;
  822. }
  823. protected bool OutStock(SqlSugarClient db, WCS_TASK task)
  824. {
  825. bool result = false;
  826. if (task != null && task.FromDepth == 2 && task.TASK_POSIDCUR == task.TASK_POSIDFROM)
  827. {
  828. var tasktemps = db.Queryable<WCS_TASK>().Where(v => v.TASK_SRMNO == PlcName).ToList();
  829. var task_DepthOne = tasktemps.Where(v => Current.WareNameList.Contains(v.TASK_WHID)).ToList()
  830. .FirstOrDefault(v => v.FromNo == task.FromNo && v.FromCol == task.FromCol && v.FromLayer == task.FromLayer && v.FromDepth == 1 && v.TASK_WKSTATUS <= 1 && (v.TASK_COMTYPE == 2 || v.TASK_COMTYPE == 3));
  831. if (task_DepthOne == null)
  832. {
  833. if (string.IsNullOrWhiteSpace(task.TASK_POSIDMOVE))
  834. {
  835. //调用生成移库任务接口
  836. var moveTaskresult = Current.WmsInterface.I_WCS_GetMoveTask(new GetMoveTaskParam() { WMSTaskNum = task.TASK_WMSNO });
  837. if (moveTaskresult.ResType == 0)
  838. {
  839. LogMessageHelper.RecordLogMessage(string.Format("任务[{0}]调用移库接口报错:[{1}]", task.TASK_NO, moveTaskresult.ResMessage));
  840. return result;
  841. }
  842. else if (moveTaskresult.ResType == 2)
  843. {
  844. //创建移库任务并执行
  845. var moveTask = new WCS_TASK();
  846. moveTask.TASK_WMSNO = moveTaskresult.WMSTaskNum;
  847. moveTask.TASK_COMTYPE = 3;
  848. moveTask.TASK_SYSTYPE = "wcs";
  849. moveTask.TASK_POSIDFROM = moveTaskresult.MoveStartWareCell;
  850. moveTask.TASK_POSIDCUR = moveTask.TASK_POSIDFROM;
  851. moveTask.TASK_POSIDNEXT = moveTask.TASK_POSIDFROM;
  852. moveTask.TASK_POSIDTO = moveTaskresult.MoveEndWareCell;
  853. moveTask.TASK_POSIDMOVE = moveTask.TASK_POSIDTO;
  854. moveTask.TASK_PRIORITY = 0;
  855. moveTask.TASK_WKSTATUS = 0;
  856. moveTask.TASK_WHID = moveTaskresult.WareHouseName;
  857. moveTask.TASK_ADDUSERNO = "wcs";
  858. moveTask.TASK_ADDDATETIME = db.GetDate();
  859. moveTask.TASK_EDITUSERNO = "wcs";
  860. moveTask.TASK_EDITDATETIME = moveTask.TASK_ADDDATETIME;
  861. moveTask.TASK_NOTES = string.Empty;
  862. moveTask.TASK_SRMNO = PlcName;
  863. moveTask.TASK_BOXBARCODE = moveTaskresult.ContainerBarCode;
  864. moveTask.TASK_FromTunnelNum = moveTaskresult.FromTunnelNum;
  865. moveTask.TASK_EndTunnelNum = moveTaskresult.EndTunnelNum;
  866. int inserttask = db.Insertable(moveTask).ExecuteCommand();
  867. if (inserttask <= 0)
  868. {
  869. throw new Exception(string.Format("任务[{0}]生成移库添加移库任务失败.", task.TASK_NO));
  870. }
  871. //修改任务的移库字段
  872. int updatetask = db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_POSIDMOVE = moveTask.TASK_POSIDMOVE, TASK_PRIORITY = 100, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
  873. .Where(it => it.TASK_NO == task.TASK_NO)
  874. .ExecuteCommand();
  875. if (updatetask <= 0)
  876. {
  877. throw new Exception(string.Format("任务[{0}]生成移库时修改需要移库的任务失败.", task.TASK_NO));
  878. }
  879. task = db.Queryable<WCS_TASK>().First(v => v.TASK_WMSNO == moveTask.TASK_WMSNO);
  880. }
  881. else if (moveTaskresult.ResType == 3)
  882. {
  883. if (string.IsNullOrWhiteSpace(moveTaskresult.Memo1.Trim()))
  884. {
  885. LogMessageHelper.RecordLogMessage(string.Format("调用移库接口报错:堆垛机[{0}]优先执行的入库任务号不能为空。", PlcName));
  886. return result;
  887. }
  888. else
  889. {
  890. int task_no = Convert.ToInt32(moveTaskresult.Memo1.Trim());
  891. if (task_no <= 0)
  892. {
  893. LogMessageHelper.RecordLogMessage(string.Format("调用移库接口报错:堆垛机[{0}]优先执行的入库任务号不能为零。", PlcName));
  894. return result;
  895. }
  896. db.Updateable<WCS_TASK>(it => new WCS_TASK() { TASK_PRIORITY = 10, TASK_EDITDATETIME = DateTime.Now })
  897. .Where(it => it.TASK_NO == task_no)
  898. .ExecuteCommand();
  899. return result;
  900. }
  901. }
  902. }
  903. }
  904. else if (task_DepthOne.TASK_WKSTATUS <= 1)
  905. {
  906. task = task_DepthOne;
  907. }
  908. }
  909. if (task == null) return result;
  910. var writeSignal = new WCSWriteToSrmSignal();
  911. writeSignal.Start_number = 0;
  912. writeSignal.End_number = 0;
  913. writeSignal.Goodtype = 0;
  914. //查询货位表巷道,深度
  915. //var location = db.Queryable<Base_Location>().First(v => v.Loc_No == outtask.TASK_POSIDFROM);
  916. if(task.TASK_POSIDCUR == task.TASK_POSIDFROM)
  917. {
  918. //堆垛机出库
  919. writeSignal.RowPos1 = task.FromRow;//location.Loc_Tunnel;
  920. writeSignal.Travelpos1 = task.FromCol;//outtask.ToCol;
  921. writeSignal.Liftpos1 = task.FromLayer;//outtask.ToLayer;
  922. }
  923. else
  924. {
  925. //堆垛机搬运任务
  926. var routes = Current.EquRouteSet.Where(v => v.ROUTE_STARTPOS == task.TASK_POSIDCUR).ToList();
  927. var route = routes.FirstOrDefault(v => v.ROUTE_SONPOS == PlcName);
  928. writeSignal.RowPos1 = (int)route.SRMROW;//location.Loc_Tunnel;
  929. writeSignal.Travelpos1 = (int)route.SRMCOLUMN;//outtask.ToCol;
  930. writeSignal.Liftpos1 = (int)route.SRMLAYER;//outtask.ToLayer;
  931. }
  932. //writeSignal.Fork_start_pos1 = outtask.FromDepth;// location.Loc_Depth; location.Loc_EquimentNo
  933. if (task.TASK_COMTYPE == 2)
  934. {
  935. var routeSet = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO);
  936. var routes = routeSet.Where(v => v.ROUTE_STARTPOS == task.TASK_SRMNO).ToList();
  937. var route = QueryOutEquRouteItem(task, routes);
  938. writeSignal.RowPos2 = (int)route.SRMROW;
  939. writeSignal.Travelpos2 = (int)route.SRMCOLUMN;
  940. writeSignal.Liftpos2 = (int)route.SRMLAYER;
  941. //writeSignal.Fork_dest_pos2 = (int)route.DEPTH;
  942. writeSignal.TaskID = task.TASK_NO;
  943. //执行任务
  944. SrmOutIn(writeSignal, task.TASK_POSIDFROM, route.ROUTE_SONPOS);
  945. }
  946. else if (task.TASK_COMTYPE == 3)
  947. {
  948. if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == WCS_PLCItem.PLC_NAME)
  949. {
  950. bool assignresult = GetWareCell(task);
  951. if (assignresult == false) return result;
  952. }
  953. writeSignal.RowPos2 = task.ToRow;
  954. writeSignal.Travelpos2 = task.ToCol;
  955. writeSignal.Liftpos2 = task.ToLayer;
  956. //writeSignal.Fork_dest_pos2 = outtask.ToDepth;
  957. writeSignal.TaskID = task.TASK_NO;
  958. //执行任务
  959. SrmOutIn(writeSignal,task.TASK_POSIDFROM, task.TASK_POSIDTO);
  960. }
  961. result = true;
  962. return result;
  963. }
  964. protected virtual WCS_EQUIPMENTROUTE QueryOutEquRouteItem(WCS_TASK task, List<WCS_EQUIPMENTROUTE> routeSet)
  965. {
  966. return routeSet.Single();
  967. }
  968. /// <summary>
  969. /// 检测区域出口地址(弯轨堆垛机,多项道转换堆垛机)
  970. /// </summary>
  971. protected virtual bool CheckAreaOutAddress(WCS_TASK task, WCS_EQUIPMENTROUTE route)
  972. {
  973. return true;
  974. }
  975. protected bool Carry(SqlSugarClient db, WCS_TASK task)
  976. {
  977. bool result = false;
  978. var writeSignal = new WCSWriteToSrmSignal();
  979. writeSignal.Start_number = 0;
  980. writeSignal.End_number = 0;
  981. writeSignal.Goodtype = 0;
  982. var routeItem = Current.EquRouteSet.SingleOrDefault(v => v.ROUTE_STARTPOS == task.TASK_POSIDNEXT && v.ROUTE_SONPOS == PlcName);
  983. //查询货位表巷道,深度
  984. //var location = db.Queryable<Base_Location>().First(v => v.Loc_No == outtask.TASK_POSIDFROM);
  985. writeSignal.RowPos1 = (int)routeItem.SRMROW;//task.FromRow;//location.Loc_Tunnel;
  986. writeSignal.Travelpos1 = (int)routeItem.SRMCOLUMN; //task.FromCol;//outtask.ToCol;
  987. writeSignal.Liftpos1 = (int)routeItem.SRMLAYER;//task.FromLayer;//outtask.ToLayer;
  988. //writeSignal.Fork_start_pos1 = outtask.FromDepth;// location.Loc_Depth; location.Loc_EquimentNo
  989. var routeSet = EquRouteHelper.QueryRoute(task.TASK_SRMNO, task.TASK_POSIDTO);
  990. var route = routeSet.FirstOrDefault(v => v.ROUTE_STARTPOS == task.TASK_SRMNO);
  991. writeSignal.RowPos2 = (int)route.SRMROW;
  992. writeSignal.Travelpos2 = (int)route.SRMCOLUMN;
  993. writeSignal.Liftpos2 = (int)route.SRMLAYER;
  994. //writeSignal.Fork_dest_pos2 = (int)route.DEPTH;
  995. writeSignal.TaskID = task.TASK_NO;
  996. //执行任务
  997. SrmOutIn(writeSignal, task.TASK_POSIDNEXT, route.ROUTE_SONPOS);
  998. result = true;
  999. return result;
  1000. }
  1001. protected virtual WCS_TASK QueryOutTask(SqlSugarClient db, List<WCS_TASK> taskSet)
  1002. {
  1003. return taskSet.OrderBy(n => n.TASK_EDITDATETIME).ToList().FirstOrDefault();
  1004. }
  1005. private int _assignInWareCell = 0;
  1006. /// <summary>
  1007. /// 分配入库货位
  1008. /// </summary>
  1009. private void AssignInWareCell()
  1010. {
  1011. if (Interlocked.Exchange(ref _assignInWareCell, 1) == 0)
  1012. {
  1013. try
  1014. {
  1015. var taskSet = SugarBase.DB.Queryable<WCS_TASK>().Where(v => v.TASK_SRMNO == PlcName && v.TASK_WKSTATUS != 5 && v.TASK_WKSTATUS > 1).ToList().OrderByDescending(v => v.TASK_PRIORITY).ToList();
  1016. var taskSet_In = taskSet.Where(v => v.TASK_COMTYPE == 1).ToList();
  1017. foreach (var task in taskSet_In)
  1018. {
  1019. if (SrmOutInInfoSet.Any(v => v.SRMOUTIN_CONVNO == task.TASK_POSIDCUR && (v.SRMOUTIN_OUTINTYPE == "in" || v.SRMOUTIN_OUTINTYPE == "outIn")) || task.TASK_POSIDCUR=="1025")
  1020. {
  1021. if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == PlcName)
  1022. {
  1023. if (task.TASK_WKSTATUS != 7)
  1024. {
  1025. //入库任务分配货位
  1026. GetWareCell(task);
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. catch (Exception ex)
  1033. {
  1034. LogMessageHelper.RecordLogMessage(string.Format("分配入库货位异常:[{0}]", ex.Message), ex);
  1035. }
  1036. finally
  1037. {
  1038. Interlocked.Exchange(ref _assignInWareCell, 0);
  1039. }
  1040. }
  1041. }
  1042. #endregion;
  1043. #region 测试
  1044. private void SRMExecuteTask()
  1045. {
  1046. //var taskSet = Current.TaskSet.Where(v => v.TASK_SRMNO == SrmNo && v.TASK_WKSTATUS != 5).OrderByDescending(v => v.TASK_PRIORITY).ToList();
  1047. #region 准备堆垛机执行的入库任务
  1048. //var taskSet_In = taskSet.Where(v => v.TASK_COMTYPE == 1).ToList();
  1049. //foreach (var task in taskSet_In)
  1050. //{
  1051. // if(SrmOutInInfoSet.Any(v => v.SRMOUTIN_CONVNO == task.TASK_POSIDCUR && v.SRMOUTIN_OUTINTYPE == "in"))
  1052. // {
  1053. // if (string.IsNullOrWhiteSpace(task.TASK_POSIDTO) || task.TASK_POSIDTO == SrmNo)
  1054. // {
  1055. // //入库任务分配货位
  1056. // bool assignresult = GetWareCell(task);
  1057. // }
  1058. // }
  1059. //}
  1060. #endregion;
  1061. #region 准备堆垛机执行的出库任务
  1062. //var taskSet_Out = taskSet.Where(v => v.TASK_COMTYPE == 2 && v.TASK_WKSTATUS <= 1).ToList();
  1063. ////堆垛机出口列表
  1064. //var srmOutConvInfoSet = SrmOutInInfoSet.Where(v => v.SRMOUTIN_OUTINTYPE == "out").ToList();
  1065. //foreach (var outConv in srmOutConvInfoSet)
  1066. //{
  1067. // if (!taskSet.Any(v => v.TASK_COMTYPE == 2 && v.TASK_WKSTATUS == 11 && v.TASK_SRMOUTCONVNO == outConv.SRMOUTIN_CONVNO))
  1068. // {
  1069. // var outtaskSet = taskSet_Out.Where(v => v.TASK_SRMOUTCONVNO == outConv.SRMOUTIN_CONVNO).ToList();
  1070. // var outtasks = QueryOutTask(outtaskSet);
  1071. // foreach (var outtask in outtasks)
  1072. // {
  1073. // if (outtask.FromDepth == 2)
  1074. // {
  1075. // var temptask = taskSet.First(v => v.FromRow == outtask.FromRow && v.FromLayer == outtask.FromLayer && v.FromDepth == 1);
  1076. // if (temptask == null)
  1077. // {
  1078. // //调用生成移库任务接口
  1079. // break;
  1080. // }
  1081. // else if (temptask.TASK_WKSTATUS >= 1)
  1082. // {
  1083. // //1升位和2升位任务堆垛机出口不一致,
  1084. // if (temptask.TASK_SRMOUTCONVNO != outConv.SRMOUTIN_CONVNO)
  1085. // {
  1086. // continue;
  1087. // }
  1088. // //outtask = temptask;
  1089. // }
  1090. // }
  1091. // //修改任务状态
  1092. // break;
  1093. // }
  1094. // }
  1095. //}
  1096. #endregion;
  1097. }
  1098. //internal virtual List<WCS_TASK> QueryOutTask(List<WCS_TASK> taskSet)
  1099. //{
  1100. // return taskSet.OrderByDescending(v => v.TASK_PRIORITY).OrderBy(v => v.TASK_EDITDATETIME).ToList();
  1101. //}
  1102. #endregion;
  1103. }
  1104. //public class SrmList
  1105. //{
  1106. // /// <summary>
  1107. // /// Srm运行
  1108. // /// </summary>
  1109. // public static void SrmRun()
  1110. // {
  1111. // try
  1112. // {
  1113. // foreach (var srm in Current.SrmSet)
  1114. // {
  1115. // //if (srm.SrmNo == "srm11" || srm.SrmNo == "srm10")
  1116. // ThreadHelper.TaskThread(srm.ExecuteSrm);
  1117. // }
  1118. // }
  1119. // catch (Exception ex)
  1120. // {
  1121. // Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());
  1122. // }
  1123. // }
  1124. //}
  1125. public class WCSWriteToSrmSignal
  1126. {
  1127. //码垛起始货位原有数量
  1128. public int Start_number;
  1129. //码垛终点货位叉取数量
  1130. public int End_number;
  1131. //货物类型
  1132. public int Goodtype;
  1133. /// <summary>
  1134. /// 速度模式
  1135. /// </summary>
  1136. public int Runmode;
  1137. //任务起始行
  1138. public int RowPos1;
  1139. //任务行走起始列
  1140. public int Travelpos1;
  1141. //任务提升起始层
  1142. public int Liftpos1;
  1143. //任务起始深度(0:中位, 1:深度1, 2:深度2)
  1144. public int Fork_start_pos1;
  1145. //任务目标行
  1146. public int RowPos2;
  1147. //任务行走目标列
  1148. public int Travelpos2;
  1149. //任务提升目标层
  1150. public int Liftpos2;
  1151. //任务目标深度(0:中位, 1:深度1, 2:深度2)
  1152. public int Fork_dest_pos2;
  1153. //任务ID
  1154. public int TaskID;
  1155. }
  1156. }