终端一体化运控平台
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.
 
 
 

869 lines
39 KiB

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