终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

908 lines
40 KiB

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