终端一体化运控平台
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

945 行
43 KiB

  1. using BPASmartClient.CustomResource;
  2. using static BPA.Helper.EventBus;
  3. using System.Collections.Concurrent;
  4. //using BPA.Helper;
  5. namespace BPASmartClient.MorkSUpgradedVer
  6. {
  7. public class Control_MorkSUpgradedVer : BaseDevice
  8. {
  9. public override DeviceClientType DeviceType => DeviceClientType.MORKS;
  10. private GVL_MorkSUpgradedVer mORKS = new GVL_MorkSUpgradedVer();
  11. private Alarm alarm = new Alarm();
  12. public override void DoMain()
  13. {
  14. MonitorViewModel.DeviceId = DeviceId;
  15. ServerInit();
  16. DataParse();
  17. Json<MorksPar>.Read();
  18. Json<OrderStatistics>.Read();
  19. if (Json<MorksPar>.Data.parSets == null)
  20. Json<MorksPar>.Data.parSets = new ObservableCollection<ParSet>();
  21. if (Json<MorksPar>.Data.parSets.Count < 6)
  22. {
  23. Json<MorksPar>.Data.parSets.Clear();
  24. for (int i = 0; i < 6; i++)
  25. {
  26. Json<MorksPar>.Data.parSets.Add(new ParSet()
  27. {
  28. CheckBoxContext = $"煮面口{i + 1}屏蔽",
  29. Minute = 1,
  30. Second = 0,
  31. IsShield = false,
  32. TextBlockContext = $"煮面口{i + 1}时间设定"
  33. });
  34. }
  35. }
  36. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  37. {
  38. if (o.Length > 0)
  39. {
  40. Random rd = new Random();
  41. TaskManage.GetInstance.StartLong(new Action(() =>
  42. {
  43. int NoodleLoc = (int)o[0] == 0 ? rd.Next(1, 6) : (int)o[0];
  44. int BowlLoc = (int)o[1] == 0 ? rd.Next(10, 12) : (int)o[1];
  45. string guid = Guid.NewGuid().ToString();
  46. mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = (ushort)NoodleLoc, SuborderId = guid });
  47. MessageLog.GetInstance.Show($"添加订单:面条位置【{NoodleLoc}】");
  48. mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = (ushort)BowlLoc, SuborderId = guid });
  49. MessageLog.GetInstance.Show($"添加订单:碗位置【{BowlLoc}】");
  50. Thread.Sleep(60000);
  51. }), "ForOrder");
  52. }
  53. }), "EnableForOrder");
  54. ActionManage.GetInstance.Register(new Action<object>((o) =>
  55. {
  56. if (o != null && o is WritePar writePar)
  57. WriteData(writePar.Address, writePar.Value);
  58. }), "WriteVW");
  59. ActionManage.GetInstance.Register(new Action<object>((o) =>
  60. {
  61. if (o != null && o is WritePar writePar)
  62. WriteData(writePar.Address, writePar.Value);
  63. }), "WriteBools");
  64. ActionManage.GetInstance.Register(new Action(() => { DeviceInit(); }), "InitDevice");
  65. }
  66. public override void ResetProgram()
  67. {
  68. mORKS = null;
  69. mORKS = new GVL_MorkSUpgradedVer();
  70. }
  71. public override void Stop()
  72. {
  73. }
  74. private void ServerInit()
  75. {
  76. //物料信息
  77. EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  78. {
  79. if (@event == null)
  80. return;
  81. if (@event is MaterialDeliveryEvent material)
  82. {
  83. orderMaterialDelivery = material.orderMaterialDelivery;
  84. }
  85. });
  86. //配方数据信息
  87. EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  88. {
  89. if (@event == null)
  90. return;
  91. if (@event is RecipeBomEvent recipe)
  92. {
  93. recipeBoms = recipe.recipeBoms;
  94. }
  95. });
  96. OrderNotifyInit();
  97. }
  98. #region 接口通知任务处理
  99. ConcurrentQueue<OrderStatusModel> osm = new ConcurrentQueue<OrderStatusModel>();
  100. private void OrderNotifyInit()
  101. {
  102. TaskManage.GetInstance.StartLong(() =>
  103. {
  104. while (osm.Count > 0)
  105. {
  106. TempOrderChange(osm.ElementAt(0).SubOrderId, osm.ElementAt(0).Status, () =>
  107. {
  108. osm.TryDequeue(out OrderStatusModel tempOSM);
  109. DeviceProcessLogShow($"订单:【{tempOSM.SubOrderId}】, 状态:【{tempOSM.Status}】, API状态修改成功");
  110. });
  111. }
  112. Thread.Sleep(100);
  113. }, $"订单状态更新接口{DeviceId}", true);
  114. }
  115. private void TempOrderChange(string subid, ORDER_STATUS oRDER_STATUS, Action complete)
  116. {
  117. var res = mORKS.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);
  118. string goodName = string.Empty;
  119. string SortNum = string.Empty;
  120. if (res != null)
  121. {
  122. goodName = res.MorkOrder.GoodsName;
  123. SortNum = res.MorkOrder.SortNum.ToString();
  124. }
  125. if (!string.IsNullOrEmpty(goodName) && !string.IsNullOrEmpty(SortNum))
  126. {
  127. EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { SortNum = SortNum, GoodName = goodName, Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }, e => { complete?.Invoke(); });
  128. var index = DataServer.GetInstance.morkS.MakeOrder.FindIndex(p => p.SortNum == SortNum);
  129. //如果订单信息已经存在,则修改状态,否则新增。
  130. if (index >= 0 && index < DataServer.GetInstance.morkS.MakeOrder.Count)
  131. {
  132. if (oRDER_STATUS == ORDER_STATUS.COMPLETED_COOK)
  133. {
  134. DataServer.GetInstance.morkS.MakeOrder.RemoveAt(index);
  135. DataServer.GetInstance.morkS.MakeOrderOver.Add(new OrderMakeModel()
  136. {
  137. Status = oRDER_STATUS,
  138. GoodName = goodName,
  139. SortNum = SortNum,
  140. StopTime = DateTime.Now.ToString("HH:mm:ss")
  141. });
  142. }
  143. else if (oRDER_STATUS == ORDER_STATUS.COMPLETED_TAKE)
  144. {
  145. var temp = DataServer.GetInstance.morkS.MakeOrderOver.FirstOrDefault(p => p.SortNum == SortNum);
  146. if (temp != null) DataServer.GetInstance.morkS.MakeOrderOver.Remove(temp);
  147. }
  148. else DataServer.GetInstance.morkS.MakeOrder.ElementAt(index).Status = oRDER_STATUS;
  149. }
  150. else
  151. {
  152. DataServer.GetInstance.morkS.MakeOrder.Add(new OrderMakeModel()
  153. {
  154. Status = oRDER_STATUS,
  155. GoodName = goodName,
  156. SortNum = SortNum,
  157. StartTime = DateTime.Now.ToString("HH:mm:ss")
  158. });
  159. }
  160. }
  161. }
  162. #endregion
  163. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  164. {
  165. osm.Enqueue(new OrderStatusModel() { SubOrderId = subid, Status = oRDER_STATUS });
  166. return;
  167. var res = mORKS.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);
  168. string goodName = string.Empty;
  169. string SortNum = string.Empty;
  170. if (res != null)
  171. {
  172. goodName = res.MorkOrder.GoodsName;
  173. SortNum = res.MorkOrder.SortNum.ToString();
  174. }
  175. //if (mORKS.doe.ContainsKey(subid))
  176. //{
  177. // goodName = mORKS.doe[subid].MorkOrder.GoodsName;
  178. // SortNum = mORKS.doe[subid].MorkOrder.SortNum.ToString();
  179. if (!string.IsNullOrEmpty(goodName) && !string.IsNullOrEmpty(SortNum))
  180. {
  181. EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { SortNum = SortNum, GoodName = goodName, Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
  182. var index = DataServer.GetInstance.morkS.MakeOrder.FindIndex(p => p.SortNum == SortNum);
  183. //如果订单信息已经存在,则修改状态,否则新增。
  184. if (index >= 0 && index < DataServer.GetInstance.morkS.MakeOrder.Count)
  185. {
  186. if (oRDER_STATUS == ORDER_STATUS.COMPLETED_COOK)
  187. {
  188. DataServer.GetInstance.morkS.MakeOrder.RemoveAt(index);
  189. DataServer.GetInstance.morkS.MakeOrderOver.Add(new OrderMakeModel()
  190. {
  191. Status = oRDER_STATUS,
  192. GoodName = goodName,
  193. SortNum = SortNum,
  194. StopTime = DateTime.Now.ToString("HH:mm:ss")
  195. });
  196. }
  197. else if (oRDER_STATUS == ORDER_STATUS.COMPLETED_TAKE)
  198. {
  199. var temp = DataServer.GetInstance.morkS.MakeOrderOver.FirstOrDefault(p => p.SortNum == SortNum);
  200. if (temp != null)
  201. DataServer.GetInstance.morkS.MakeOrderOver.Remove(temp);
  202. }
  203. else
  204. {
  205. DataServer.GetInstance.morkS.MakeOrder.ElementAt(index).Status = oRDER_STATUS;
  206. }
  207. }
  208. else
  209. {
  210. DataServer.GetInstance.morkS.MakeOrder.Add(new OrderMakeModel()
  211. {
  212. Status = oRDER_STATUS,
  213. GoodName = goodName,
  214. SortNum = SortNum,
  215. StartTime = DateTime.Now.ToString("HH:mm:ss")
  216. });
  217. }
  218. //mORKS.doe.Remove(subid, out _);
  219. }
  220. //}
  221. //var res = mORKS.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);
  222. //string goodName = string.Empty;
  223. //string SortNum = string.Empty;
  224. //if (res != null)
  225. //{
  226. // goodName = res.MorkOrder.GoodsName;
  227. // SortNum = res.MorkOrder.SortNum.ToString();
  228. //}
  229. //EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { SortNum = SortNum, GoodName = goodName, Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
  230. //var index = DataServer.GetInstance.morkS.MakeOrder.FindIndex(p => p.SortNum == SortNum);
  231. //if (index >= 0 && index < DataServer.GetInstance.morkS.MakeOrder.Count)
  232. //{
  233. // if (oRDER_STATUS == ORDER_STATUS.COMPLETED_COOK)
  234. // {
  235. // DataServer.GetInstance.morkS.MakeOrder.RemoveAt(index);
  236. // DataServer.GetInstance.morkS.MakeOrderOver.Add(new OrderMakeModel()
  237. // {
  238. // Status = oRDER_STATUS,
  239. // GoodName = goodName,
  240. // SortNum = SortNum,
  241. // StopTime = DateTime.Now.ToString("HH:mm:ss")
  242. // });
  243. // }
  244. // else if (oRDER_STATUS == ORDER_STATUS.COMPLETED_TAKE)
  245. // {
  246. // var temp = DataServer.GetInstance.morkS.MakeOrderOver.FirstOrDefault(p => p.SortNum == SortNum);
  247. // if (temp != null) DataServer.GetInstance.morkS.MakeOrderOver.Remove(temp);
  248. // }
  249. // else
  250. // {
  251. // DataServer.GetInstance.morkS.MakeOrder.ElementAt(index).Status = oRDER_STATUS;
  252. // }
  253. //}
  254. //else
  255. //{
  256. // DataServer.GetInstance.morkS.MakeOrder.Add(new OrderMakeModel()
  257. // {
  258. // Status = oRDER_STATUS,
  259. // GoodName = goodName,
  260. // SortNum = SortNum,
  261. // StartTime = DateTime.Now.ToString("HH:mm:ss")
  262. // });
  263. //}
  264. }
  265. private void GetStatus(string key, Action<object> action)
  266. {
  267. if (peripheralStatus.ContainsKey(key))
  268. {
  269. if (peripheralStatus[key] != null)
  270. {
  271. action?.Invoke(peripheralStatus[key]);
  272. }
  273. }
  274. }
  275. public override void ReadData()
  276. {
  277. DataServer.GetInstance.morkS.Alarm.Clear();
  278. alarms.ForEach(item =>
  279. {
  280. DataServer.GetInstance.morkS.Alarm.Add(new AlarmModel()
  281. {
  282. AlarmTime = $"{item.Date} {item.Time}",
  283. AlarmMs = item.Info
  284. });
  285. });
  286. GetStatus("M0.1", new Action<object>((obj) =>
  287. {
  288. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7)
  289. {
  290. Initing = !bools[0];
  291. mORKS.InitComplete = bools[0];
  292. mORKS.MoveScrewRodInitCom = bools[1];
  293. mORKS.SacrificialVesselInitCom = bools[2];
  294. mORKS.CylinderInitCom = bools[3];
  295. mORKS.NoodleCookerInitCom = bools[4];
  296. mORKS.RobotInitCom = bools[5];
  297. mORKS.SiloInitCom = bools[6];
  298. alarm.DeviceNoInit = !mORKS.InitComplete;
  299. alarm.MoveScrewRodNoInit = !mORKS.MoveScrewRodInitCom;
  300. alarm.SacrificialVesselNoInit = !mORKS.SacrificialVesselInitCom;
  301. alarm.CylinderNoInit = !mORKS.CylinderInitCom;
  302. alarm.NoodleCookerNoInit = !mORKS.NoodleCookerInitCom;
  303. alarm.RobotNoInit = !mORKS.RobotInitCom;
  304. alarm.SiloNoInit = !mORKS.SiloInitCom;
  305. }
  306. }));
  307. GetStatus("M10.0", new Action<object>((obj) =>
  308. {
  309. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 2)
  310. {
  311. mORKS.AllowInvertedFace = bools[0];
  312. mORKS.DiningComplete = bools[1];
  313. }
  314. }));
  315. GetStatus("M10.4", new Action<object>((obj) =>
  316. {
  317. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1)
  318. {
  319. mORKS.DropBowlMechanismStatus = bools[0];
  320. }
  321. }));
  322. GetStatus("M12.2", new Action<object>((obj) =>
  323. {
  324. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1)
  325. {
  326. mORKS.FixedFlag = bools[0];
  327. }
  328. }));
  329. GetStatus("M13.5", new Action<object>((obj) =>
  330. {
  331. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1)
  332. {
  333. mORKS.SiloInPlace = bools[0];
  334. }
  335. }));
  336. GetStatus("M16.7", new Action<object>((obj) =>
  337. {
  338. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1)
  339. {
  340. mORKS.RobotTakeNoodleCom = bools[0];
  341. }
  342. }));
  343. GetStatus("M17.4", new Action<object>((obj) =>
  344. {
  345. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 1)
  346. {
  347. mORKS.RobotStatus = bools[0];
  348. }
  349. }));
  350. GetStatus("M18.0", new Action<object>((obj) =>
  351. {
  352. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 5)
  353. {
  354. mORKS.SmallBowlYesOrNoCheck = bools[0];
  355. mORKS.LargeBowYesOrNoCheck = bools[1];
  356. mORKS.TurntableLowPosition = bools[2];
  357. mORKS.TurntableHighPosition = bools[3];
  358. alarm.Supply2_LossBowl = !mORKS.SmallBowlYesOrNoCheck;
  359. alarm.Supply1_LossBowl = !mORKS.LargeBowYesOrNoCheck;
  360. }
  361. }));
  362. GetStatus("VW17", new Action<object>((obj) =>
  363. {
  364. if (obj is ushort[] ushorts && ushorts.Length > 0 && ushorts.Length <= 1)
  365. {
  366. var tt = ushorts.ToBytes(true).ToUshorts();
  367. for (byte i = 0; i < 6; i++)
  368. {
  369. if (RTrig.GetInstance($"CookNoodleCom{i + 1}").Start(tt[0].GetBitValue((byte)(i + 1))))
  370. {
  371. if (!string.IsNullOrEmpty(mORKS.CookNodelId[i]))
  372. mORKS.CookNoodleCom[i] = true;
  373. }
  374. }
  375. //mORKS.CookNoodleCom[0] = tt[0].GetBitValue(1);
  376. //mORKS.CookNoodleCom[1] = tt[0].GetBitValue(2);
  377. //mORKS.CookNoodleCom[2] = tt[0].GetBitValue(3);
  378. //mORKS.CookNoodleCom[3] = tt[0].GetBitValue(4);
  379. //mORKS.CookNoodleCom[4] = tt[0].GetBitValue(5);
  380. //mORKS.CookNoodleCom[5] = tt[0].GetBitValue(6);
  381. mORKS.Heating = ushorts[0].GetBitValue(15);
  382. mORKS.TemperatureReaches = ushorts[0].GetBitValue(16);
  383. alarm.MachineLowTemperature = !mORKS.TemperatureReaches;
  384. }
  385. }));
  386. GetStatus("VW770", new Action<object>((obj) =>
  387. {
  388. if (obj is ushort[] ushorts && ushorts.Length > 0 && ushorts.Length <= 1)
  389. {
  390. mORKS.CurrentFeedbackLoc = ushorts[0];
  391. }
  392. }));
  393. mORKS.TakeBowlTaskCount = mORKS.TakeBowlTask.Count;
  394. mORKS.RBTakeNoodleTaskCount = mORKS.RBTakeNoodleTask.Count;
  395. for (int i = 0; i < Json<MorksPar>.Data.parSets.Count; i++)
  396. {
  397. mORKS.nsm.ElementAt(i).IsShield = Json<MorksPar>.Data.parSets.ElementAt(i).IsShield;
  398. mORKS.nsm.ElementAt(i).NoodleCookerStatus = mORKS.NoodleCookerStatus[i];
  399. }
  400. }
  401. /// <summary>数据解析</summary>
  402. private void DataParse()
  403. {
  404. EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  405. {
  406. if (@event == null)
  407. return;
  408. if (@event is DoOrderEvent order)
  409. {
  410. mORKS.doOrderEvents.Add(order);
  411. //mORKS.doe.TryAdd(order.MorkOrder.SuborderId, order);
  412. if (order.MorkOrder.GoodBatchings == null)
  413. return;
  414. if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId))
  415. return;
  416. OrderCount++;
  417. if (DateTime.Now.Subtract(Json<OrderStatistics>.Data.StatisticsTime).Days != 0)
  418. Json<OrderStatistics>.Data.Count = 0;
  419. Json<OrderStatistics>.Data.StatisticsTime = DateTime.Now;
  420. Json<OrderStatistics>.Data.Count++;
  421. Json<OrderStatistics>.Save();
  422. OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
  423. DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}");
  424. mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId);
  425. foreach (var item in order.MorkOrder.GoodBatchings)
  426. {
  427. var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  428. if (res != null)
  429. {
  430. if (ushort.TryParse(res.BatchingLoc, out ushort loc))
  431. {
  432. if (loc >= 1 && loc <= 5)
  433. {
  434. if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  435. mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo()
  436. {
  437. GoodName = order.MorkOrder.GoodsName,
  438. Loc = ushort.Parse(res.BatchingLoc),
  439. SuborderId = order.MorkOrder.SuborderId,
  440. SortNum = order.MorkOrder.SortNum,
  441. BatchingId = res.BatchingId
  442. });
  443. }
  444. else if (loc >= 10 && loc <= 11)
  445. {
  446. int index = 0;
  447. if (recipeBoms != null)
  448. {
  449. index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId);
  450. index++;
  451. }
  452. if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  453. mORKS.TakeBowlTask.Enqueue(new OrderLocInfo()
  454. {
  455. BatchingId = res.BatchingId,
  456. GoodName = order.MorkOrder.GoodsName,
  457. Loc = ushort.Parse(res.BatchingLoc),
  458. SuborderId = order.MorkOrder.SuborderId,
  459. SortNum = order.MorkOrder.SortNum,
  460. RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0
  461. });
  462. }
  463. }
  464. }
  465. }
  466. }
  467. });
  468. }
  469. public override void MainTask()
  470. {
  471. mORKS.AllowRun = mORKS.InitComplete;
  472. if (Json<KeepDataBase>.Data.IsVerify)
  473. IsHealth = mORKS.InitComplete;
  474. else
  475. IsHealth = true;
  476. TakeBowlTask();
  477. TakeNoodleTask();
  478. OutNoodleTask();
  479. SingleDetect();
  480. TurntableControl();
  481. }
  482. private void BowlControl(OrderLocInfo orderLocInfo)
  483. {
  484. if (orderLocInfo.Loc >= 10 && orderLocInfo.Loc <= 11)
  485. {
  486. //mORKS.TakeBowlId = orderLocInfo.SuborderId;
  487. mORKS.TakeBowName = orderLocInfo.GoodName;
  488. mORKS.TakeBowSortNum = orderLocInfo.SortNum;
  489. TakeBowlControl(orderLocInfo.Loc);
  490. //OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING);
  491. OrderChange(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  492. //DeviceProcessLogShow($"订单【{mORKS.TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]");
  493. //2023-8-5修改修改取碗打印日志。
  494. //DeviceProcessLogShow($"订单【{orderLocInfo.SuborderId}】执行取碗控制,位置:[{orderLocInfo.Loc}]");
  495. DeviceProcessLogShow($"执行取碗控制,位置:[{orderLocInfo.Loc}]");
  496. mORKS.TakeBowlInterlock = true;
  497. }
  498. }
  499. /// <summary>取碗控制</summary>
  500. private void TakeBowlTask()
  501. {
  502. if (mORKS.AllowRun && mORKS.TakeBowlTask.Count > 0 && !mORKS.DropBowlMechanismStatus && !mORKS.TakeBowlInterlock)
  503. {
  504. ushort BowLoc = 0;
  505. var res = orderMaterialDelivery?.BatchingInfo?.Where(p => p.BatchingId == mORKS.TakeBowlTask.ElementAt(0).BatchingId).ToList();
  506. if (res == null || res?.Count == 0)
  507. {
  508. if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo))
  509. BowlControl(orderLocInfo);
  510. }
  511. else
  512. {
  513. foreach (var item in res)
  514. {
  515. if (ushort.TryParse(item.BatchingLoc, out ushort loc))
  516. {
  517. if (loc == 10 && mORKS.SmallBowlYesOrNoCheck)
  518. {
  519. BowLoc = loc;
  520. break;
  521. }
  522. else if (loc == 11 && mORKS.LargeBowYesOrNoCheck)
  523. {
  524. BowLoc = loc;
  525. break;
  526. }
  527. }
  528. }
  529. if (BowLoc >= 10 && BowLoc <= 11)
  530. {
  531. if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo))
  532. {
  533. orderLocInfo.Loc = BowLoc;
  534. BowlControl(orderLocInfo);
  535. }
  536. }
  537. }
  538. }
  539. }
  540. /// <summary>转台控制</summary>
  541. private void TurntableControl()
  542. {
  543. if (Global.EnableLocalSimOrder)
  544. {
  545. //不做轮询,直接取面,模拟订单使用
  546. if (mORKS.SiloInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
  547. {
  548. if (mORKS.TurntableLowPosition)
  549. {
  550. TurntableStart(mORKS.RBTakeNoodleTask.ElementAt(0).Loc);
  551. mORKS.TurntableLocLists.Clear();
  552. mORKS.AllowTakeNoodle = true;
  553. DeviceProcessLogShow($"控制机器人去转台【{mORKS.RBTakeNoodleTask.ElementAt(0).Loc}】号位置取面");
  554. }
  555. }
  556. }
  557. else
  558. {
  559. //正常轮询
  560. if (Delay.GetInstance("到位检测延时").Start(mORKS.SiloInPlace, 2))
  561. {
  562. if (mORKS.SiloInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
  563. {
  564. var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
  565. if (result != null)
  566. {
  567. var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.CurrentFeedbackLoc.ToString());
  568. if (mORKS.TurntableLowPosition && res != null)
  569. {
  570. TurntableStart(mORKS.CurrentFeedbackLoc);
  571. mORKS.TurntableLocLists.Clear();
  572. mORKS.AllowTakeNoodle = true;
  573. DeviceProcessLogShow($"控制机器人去转台【{mORKS.CurrentFeedbackLoc}】号位置取面");
  574. }
  575. else
  576. {
  577. if (!mORKS.TurntableInterlock)
  578. {
  579. foreach (var item in result)
  580. {
  581. if (ushort.TryParse(item.BatchingLoc, out ushort loc))
  582. {
  583. if (mORKS.CurrentFeedbackLoc != loc && !mORKS.TurntableLocLists.Contains(loc))
  584. {
  585. if (!mORKS.TurntableLowPosition)
  586. {
  587. DeviceProcessLogShow($"执行了转台启动互锁信号复位");
  588. }
  589. TurntableStart(loc);
  590. DeviceProcessLogShow($"没有物料检测的启动转台控制,转台位置:[{loc}]");
  591. break;
  592. }
  593. else if (mORKS.CurrentFeedbackLoc == loc && !mORKS.TurntableLocLists.Contains(loc))
  594. mORKS.TurntableLocLists.Add(loc);
  595. }
  596. }
  597. }
  598. }
  599. }
  600. else
  601. DeviceProcessLogShow("未找到可用的物料信息");
  602. }
  603. }
  604. }
  605. //补料中检测
  606. if (RTrig.GetInstance("mORKS.Feeding").Start(mORKS.Feeding))
  607. {
  608. mORKS.AllowTakeNoodle = false;
  609. mORKS.TakeNoodleInterlock = false;
  610. }
  611. //转台到位检测
  612. if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.SiloInPlace && mORKS.CurrentLoc == mORKS.CurrentFeedbackLoc))
  613. {
  614. mORKS.TurntableInterlock = false;
  615. DeviceProcessLogShow("转台到位检测");
  616. }
  617. //补料完成检测
  618. if (RTrig.GetInstance("FeedComplete").Start(mORKS.FeedComplete))
  619. {
  620. if (!mORKS.AllowTakeNoodle && mORKS.TurntableLocLists.Count > 0)
  621. {
  622. mORKS.TurntableLocLists.Clear();
  623. mORKS.TurntableInterlock = false;
  624. DeviceProcessLogShow("补料完成检测");
  625. }
  626. }
  627. }
  628. /// <summary>取面任务</summary>
  629. private void TakeNoodleTask()
  630. {
  631. //取面控制
  632. if (mORKS.AllowRun && mORKS.RobotStatus && !mORKS.Feeding && !mORKS.RobotTaskInterlock && mORKS.AllowTakeNoodle && mORKS.SiloInPlace && !mORKS.TakeNoodleInterlock && mORKS.RBTakeNoodleTask.Count > 0)
  633. {
  634. if (mORKS.CurrentLoc == mORKS.CurrentFeedbackLoc)
  635. {
  636. //int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置
  637. int loc = mORKS.nsm.ToList().FindIndex(p => p.NoodleCookerStatus == false && p.IsShield == false);//查找煮面炉空闲位置
  638. if (loc >= 0 && loc <= 5)
  639. {
  640. //if (!Json<MorksPar>.Data.parSets.ElementAt(loc).IsShield)//检查该煮面篮是否被屏蔽
  641. //{
  642. if (mORKS.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo))
  643. {
  644. //写入煮面时间
  645. //List<ushort> values = new List<ushort>();
  646. //values.Add(Json<MorksPar>.Data.parSets.ElementAt(loc).Minute);
  647. //values.Add(Json<MorksPar>.Data.parSets.ElementAt(loc).Second);
  648. //WriteData($"VW{324 + (loc * 4)}", values.ToArray());
  649. if (mORKS.CurrentFeedbackLoc >= 1 && mORKS.CurrentFeedbackLoc <= 5)
  650. {
  651. var x = Json<MorksPar>.Data.DishLibraryParSets.FirstOrDefault(p => p.TextBlockContext == mORKS.CurrentFeedbackLoc.ToString());
  652. if (x != null)
  653. {
  654. List<ushort> values = new List<ushort>();
  655. values.Add(x.Minute);
  656. values.Add(x.Second);
  657. WriteData($"VW{324 + (loc * 4)}", values.ToArray());
  658. DeviceProcessLogShow($"转盘位置[{mORKS.CurrentFeedbackLoc}]:写入煮面时间{x.Minute}分{x.Second}秒。");
  659. }
  660. }
  661. mORKS.CurrentLoc = 0;
  662. mORKS.CookNodelId[loc] = orderLocInfo.SuborderId;
  663. mORKS.NoodleCookerStatus[loc] = true;
  664. SetFallNoodleLoc((ushort)(loc + 1));
  665. //机器人开始取面
  666. OrderChange(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  667. DeviceProcessLogShow($"订单【{orderLocInfo.SuborderId}】,机器人倒面至【{loc + 1}】号煮面栏");
  668. mORKS.TakeNoodleInterlock = true;
  669. }
  670. }
  671. }
  672. }
  673. }
  674. /// <summary>出餐控制</summary>
  675. private void OutNoodleTask()
  676. {
  677. if (mORKS.AllowInvertedFace && mORKS.RobotTaskInterlock && !mORKS.RobotOutDinnigLock && !mORKS.TakeNoodleInterlock && mORKS.RobotStatus)
  678. {
  679. #region 修改之前的代码
  680. //int loc = Array.FindIndex(mORKS.CookNodelId, p => p == mORKS.IngredientsCompleteId && p.Length > 0);
  681. //if (loc >= 0 && loc <= 5)
  682. //{
  683. // if (mORKS.CookNoodleCom[loc])
  684. // {
  685. // SetTakeNoodleLoc((ushort)(loc + 1));
  686. // mORKS.NoodleCookerStatus[loc] = false;
  687. // WriteData($"VW260", (ushort)0);//设置出汤时间
  688. // OrderChange(mORKS.IngredientsCompleteId, ORDER_STATUS.COMPLETED_COOK);
  689. // DeviceProcessLogShow($"订单【{mORKS.IngredientsCompleteId}】制作完成");
  690. // mORKS.CookCompleteFlatBit = true;
  691. // mORKS.OutMealId = mORKS.IngredientsCompleteId;
  692. // mORKS.OutMealName = mORKS.IngredientsCompleteName;
  693. // mORKS.OutMealSortNum = mORKS.IngredientsCompleteSortNum;
  694. // mORKS.IngredientsCompleteId = string.Empty;
  695. // mORKS.CookNodelId[loc] = string.Empty;
  696. // DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKS.OutMealId}");
  697. // mORKS.CookNoodleCom[loc] = false;
  698. // }
  699. //}
  700. #endregion 修改之前的代码
  701. for (int loc = 0; loc < mORKS.CookNodelId.Length; loc++)
  702. {
  703. if (mORKS.CookNoodleCom[loc] && !mORKS.RobotOutDinnigLock)
  704. {
  705. SetTakeNoodleLoc((ushort)(loc + 1));
  706. mORKS.NoodleCookerStatus[loc] = false;
  707. WriteData($"VW260", (ushort)0);//设置出汤时间
  708. OrderChange(mORKS.CookNodelId[loc], ORDER_STATUS.COMPLETED_COOK);
  709. DeviceProcessLogShow($"订单【{mORKS.CookNodelId[loc]}】制作完成");
  710. mORKS.CookCompleteFlatBit = true;
  711. mORKS.OutMealId = mORKS.CookNodelId[loc];
  712. mORKS.OutMealName = mORKS.IngredientsCompleteName;
  713. mORKS.OutMealSortNum = mORKS.IngredientsCompleteSortNum;
  714. mORKS.IngredientsCompleteId = string.Empty;
  715. mORKS.CookNodelId[loc] = string.Empty;
  716. DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKS.OutMealId}");
  717. mORKS.CookNoodleCom[loc] = false;
  718. mORKS.RobotOutDinnigLock = true;
  719. }
  720. }
  721. }
  722. }
  723. /// <summary>信号检测</summary>
  724. private void SingleDetect()
  725. {
  726. //允许倒面信号检测
  727. if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowInvertedFace))
  728. {
  729. //mORKS.IngredientsCompleteId = mORKS.TakeBowlId;
  730. mORKS.IngredientsCompleteName = mORKS.TakeBowName;
  731. mORKS.IngredientsCompleteSortNum = mORKS.TakeBowSortNum;
  732. mORKS.TakeBowSortNum = 0;
  733. mORKS.TakeBowlId = string.Empty;
  734. mORKS.TakeBowName = string.Empty;
  735. //DeviceProcessLogShow($"碗到位,允许到面,{mORKS.IngredientsCompleteId}");
  736. DeviceProcessLogShow($"碗到位,允许倒面。");
  737. mORKS.TakeBowlInterlock = false;
  738. mORKS.RobotOutDinnigLock = false;
  739. }
  740. //取餐完成逻辑处理
  741. if (RTrig.GetInstance("CompleteChange1").Start(mORKS.DiningComplete) && mORKS.CookCompleteFlatBit == true)
  742. {
  743. OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE);
  744. DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成");
  745. WriteData("M10.1", false);
  746. var orderEvent = mORKS.doOrderEvents.FirstOrDefault(order => order.MorkOrder.SuborderId == mORKS.OutMealId);
  747. mORKS.OutMealSortNum = orderEvent?.MorkOrder.SortNum ?? 0;
  748. DeviceProcessLogShow($"出餐订单序号【{mORKS.OutMealSortNum}】");
  749. VoiceAPI.Speak(mORKS.OutMealSortNum.ToString());
  750. //DeviceProcessLogShow($"叫号系统通知主题【MORKS/VoiceCall/{DeviceId}】");
  751. //Plugin.GetInstance().GetPlugin<MQTTMgr>().Publish($"MORKS/VoiceCall/{DeviceId}", mORKS.OutMealSortNum.ToString());
  752. mORKS.CookCompleteFlatBit = false;
  753. mORKS.OutMealId = string.Empty;
  754. mORKS.OutMealName = string.Empty;
  755. mORKS.OutMealSortNum = 0;
  756. }
  757. //机器人取面完成信号检测
  758. if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKS.RobotTakeNoodleCom))
  759. {
  760. mORKS.TakeNoodleInterlock = false;
  761. mORKS.AllowTakeNoodle = false;
  762. mORKS.TurntableInterlock = false;
  763. DeviceProcessLogShow("检测到机器人取面完成信号");
  764. }
  765. int OutMealRequstCount = mORKS.CookNoodleCom.Where(p => p == true).ToList().Count;
  766. //int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count - Json<MorksPar>.Data.parSets.Where(x => x.IsShield == true).ToList().Count;
  767. int mlCount = mORKS.nsm.Where(p => p.NoodleCookerStatus == true && p.IsShield == false).ToList().Count;
  768. int index = Array.FindIndex(mORKS.CookNodelId, p => p == mORKS.IngredientsCompleteId);
  769. bool isok = index >= 0 && index < mORKS.CookNoodleCom.Length && mORKS.CookNoodleCom[index];
  770. mORKS.PriorityJudgment = Delay.GetInstance("取餐优先级判断").Start(mORKS.TurntableLocLists.Count > 0 && !mORKS.TurntableLowPosition, 4);
  771. //mORKS.RobotTaskInterlock = OutMealRequstCount > 0 && mORKS.AllowInvertedFace && (mlCount >= 2 || mORKS.RBTakeNoodleTask.Count == 0 || mORKS.PriorityJudgment);
  772. //mORKS.RobotTaskInterlock = isok && mORKS.AllowInvertedFace && (mlCount >= 2 || mORKS.RBTakeNoodleTask.Count == 0 || mORKS.PriorityJudgment);
  773. //2023-8-5注释修改,并联出餐请求,出餐优先。
  774. //mORKS.RobotTaskInterlock = mORKS.AllowInvertedFace && (mlCount >= 6 || mORKS.RBTakeNoodleTask.Count == 0 || mORKS.PriorityJudgment);
  775. mORKS.RobotTaskInterlock = mORKS.AllowInvertedFace && (OutMealRequstCount >= 1 /*|| mlCount >= 6*/ || mORKS.RBTakeNoodleTask.Count == 0 || mORKS.PriorityJudgment);
  776. }
  777. /// <summary>语音提醒取餐</summary>
  778. /// <param name="meal"></param>
  779. private void WaitMeaLSpeak(string meal)
  780. {
  781. //VoiceAPI.m_SystemPlayWav(@"Vioce\电子提示音.wav");
  782. //Thread.Sleep(1000);
  783. //if (meal != null) mORKS.speech.Speak(meal);
  784. //VoiceAPI.m_SystemPlayWav(@"Vioce\取餐通知.wav");
  785. }
  786. #region PLC 控制函数
  787. private void WriteData(string address, object value)
  788. {
  789. EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value });
  790. }
  791. /// <summary>设备初始化</summary>
  792. public async void DeviceInit()
  793. {
  794. WriteData("M0.0", true);
  795. await Task.Delay(1000);
  796. WriteData("M0.0", false);
  797. }
  798. /// <summary>取碗控制</summary>
  799. /// <param name="loc"></param>
  800. private void TakeBowlControl(ushort loc)
  801. {
  802. if (loc == 10)//一次性碗
  803. {
  804. WriteData("M9.1", true);
  805. }
  806. else if (loc == 11)//大碗
  807. {
  808. WriteData("M9.0", true);
  809. }
  810. }
  811. /// <summary>启动转台</summary>
  812. /// <param name="loc"></param>
  813. private void TurntableStart(ushort loc)
  814. {
  815. if (loc >= 1 && loc <= 5)
  816. {
  817. mORKS.CurrentLoc = loc;
  818. mORKS.TurntableInterlock = true;
  819. mORKS.TurntableLocLists.Add(loc);
  820. WriteData($"M13.{loc - 1}", true);
  821. }
  822. }
  823. /// <summary>设置倒面位置</summary>
  824. /// <param name="loc"></param>
  825. private void SetFallNoodleLoc(ushort loc)
  826. {
  827. if (loc >= 1 && loc <= 6)
  828. WriteData($"M14.{loc - 1}", true);
  829. }
  830. /// <summary>设置出餐位置</summary>
  831. /// <param name="loc"></param>
  832. private void SetTakeNoodleLoc(ushort loc)
  833. {
  834. if (loc >= 1 && loc <= 6)
  835. WriteData($"M15.{loc - 1}", true);
  836. }
  837. public override void SimOrder()
  838. {
  839. EventBus.GetInstance().Subscribe<MorksSimorderModel>(0, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  840. {
  841. if (@event != null && @event is MorksSimorderModel msm)
  842. {
  843. string guid = Guid.NewGuid().ToString();
  844. if (msm.NoodleLoc >= 1 && msm.NoodleLoc <= 5)
  845. {
  846. mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = (ushort)msm.NoodleLoc, SuborderId = guid });
  847. MessageLog.GetInstance.Show($"添加订单:面条位置【{(ushort)msm.NoodleLoc}】");
  848. }
  849. if (msm.Bowloc >= 10 && msm.Bowloc <= 11)
  850. {
  851. mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = (ushort)msm.Bowloc, SuborderId = guid });
  852. MessageLog.GetInstance.Show($"添加订单:碗位置【{(ushort)msm.Bowloc}】");
  853. }
  854. }
  855. });
  856. }
  857. #endregion PLC 控制函数
  858. }
  859. }