终端一体化运控平台
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

913 wiersze
39 KiB

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