终端一体化运控平台
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

1419 lignes
57 KiB

  1. using BPA.Message;
  2. using BPA.Message.Enum;
  3. using BPASmartClient.Device;
  4. using BPASmartClient.EventBus;
  5. using BPASmartClient.Helper;
  6. using BPASmartClient.Message;
  7. using BPASmartClient.Model;
  8. using BPASmartClient.Model.PLC;
  9. using BPA.Models;
  10. using static BPASmartClient.EventBus.EventBus;
  11. using BPASmartClient.Model.小炒机;
  12. using BPASmartClient.MorkF.Model;
  13. using System.Text;
  14. using System.Collections.Concurrent;
  15. namespace BPASmartClient.MorkF
  16. {
  17. public class Control_MorkF : BaseDevice
  18. {
  19. /// <summary>
  20. /// while循环最大sleep次数
  21. /// </summary>
  22. private const int sleepCount = 20;
  23. /// <summary>
  24. /// while循环每次sleep时间
  25. /// </summary>
  26. private const int sleepTime = 500;
  27. /// <summary>
  28. /// 初始化炒锅数量
  29. /// </summary>
  30. private int count = 2;
  31. //当前炒锅,默认为1号炒锅
  32. private int fryIndex = 0;
  33. public override DeviceClientType DeviceType => DeviceClientType.MORKCS;
  34. public AutoResetEvent minorReset = new AutoResetEvent(false);
  35. public AutoResetEvent mainReset = new AutoResetEvent(false);
  36. Dictionary<int,GVL_MorkF> morkFs = new Dictionary<int, GVL_MorkF>();//全局对象声明
  37. /// <summary>
  38. /// 小炒菜单集合
  39. /// </summary>
  40. public static List<StirFryGoods> LocalstirFryGoods = new List<StirFryGoods>();
  41. /// <summary>
  42. /// 待炒小炒队列
  43. /// </summary>
  44. private ConcurrentQueue<OrderLocInfo> StirFryGoodsQuenes = new ConcurrentQueue<OrderLocInfo>();
  45. private const String striConst = "炒锅{0}炒制{1}线程";
  46. /// <summary>
  47. /// 当前炒制菜品
  48. /// </summary>
  49. private OrderLocInfo nowStirFryGood = null;
  50. List<int> resultorder = new List<int>();//调试变量
  51. /// <summary>
  52. /// 入口
  53. /// </summary>
  54. public override void DoMain()
  55. {
  56. WriteControl("VD836", 0);
  57. WriteControl("VD840", 0);
  58. Thread.Sleep(400);
  59. WriteControl("M0.0", true);
  60. for (int i = 0;i< count;i++)
  61. {
  62. morkFs.Add(i, new GVL_MorkF());
  63. DataParse(i);//数据解析
  64. }
  65. CommandRegist();//调试
  66. ServerInit();
  67. DeviceProcessLogShow("MORKF 设备初始化完成");
  68. ReadData();
  69. }
  70. #region 调试代码
  71. public void CommandRegist()
  72. {
  73. #region 设备控制
  74. ActionManage.GetInstance.Register(PLCInite, "InitCommand");
  75. ActionManage.GetInstance.Register(StartOrder, "StartOrder");
  76. ActionManage.GetInstance.Register(StartLocalOrder, "StartLocalOrder");
  77. ActionManage.GetInstance.Register(StopLocalOrder, "StopLocalOrder");
  78. #endregion
  79. #region 菜品库
  80. ActionManage.GetInstance.Register(FoodLibInit, "FoodLibInit");
  81. ActionManage.GetInstance.Register(Electromagnetism, "Electromagnetism");
  82. ActionManage.GetInstance.Register(GetDistance_1, "GetDistance_1");
  83. ActionManage.GetInstance.Register(GetDistance_2, "GetDistance_2");
  84. ActionManage.GetInstance.Register(GetDistance_3, "GetDistance_3");
  85. ActionManage.GetInstance.Register(PawTurnFront, "PawTurnFront");
  86. ActionManage.GetInstance.Register(PawTurnBack, "PawTurnBack");
  87. ActionManage.GetInstance.Register(SetArmPosition, "SetArmPosition");
  88. #endregion
  89. //ActionManage.GetInstance.Register(PLCInite, "InitCommand");
  90. #region 配料控制
  91. ActionManage.GetInstance.Register(new Action<object>((o) =>
  92. {
  93. ThreadManage.GetInstance().Start(new Action(() =>
  94. {
  95. OutSeasoning(o, fryIndex);
  96. }), "OutMaterials");
  97. }), "OutMaterials");
  98. //ActionManage.GetInstance.Register(OutSeasoning, "OutMaterials");
  99. #endregion
  100. #region 炒锅1
  101. ActionManage.GetInstance.Register(new Action(() =>
  102. {
  103. ThreadManage.GetInstance().Start(new Action(() =>
  104. {
  105. Plc1Reset(fryIndex);
  106. }), "Plc1Reset");
  107. }) , "Plc1Reset");
  108. ActionManage.GetInstance.Register(new Action(() =>
  109. {
  110. ThreadManage.GetInstance().Start(new Action(() =>
  111. {
  112. AddOil();
  113. }), "AddOil");
  114. }), "AddOil");
  115. ActionManage.GetInstance.Register(new Action(() =>
  116. {
  117. ThreadManage.GetInstance().Start(new Action(() =>
  118. {
  119. StartFire(fryIndex);
  120. }), "StartFire");
  121. }), "StartFire");
  122. ActionManage.GetInstance.Register(new Action(() =>
  123. {
  124. ThreadManage.GetInstance().Start(new Action(() =>
  125. {
  126. StopFire(fryIndex);
  127. }), "StopFire");
  128. }), "StopFire");
  129. ActionManage.GetInstance.Register(new Action(() =>
  130. {
  131. ThreadManage.GetInstance().Start(new Action(() =>
  132. {
  133. StartStir(fryIndex);
  134. }), "StartStir");
  135. }), "StartStir");
  136. ActionManage.GetInstance.Register(new Action(() =>
  137. {
  138. ThreadManage.GetInstance().Start(new Action(() =>
  139. {
  140. StopStir(fryIndex);
  141. }), "StopStir");
  142. }), "StopStir");
  143. ActionManage.GetInstance.Register(new Action(() =>
  144. {
  145. ThreadManage.GetInstance().Start(new Action(() =>
  146. {
  147. OutFood(fryIndex);
  148. }), "OutFood");
  149. }), "OutFood");
  150. ActionManage.GetInstance.Register(new Action(() =>
  151. {
  152. ThreadManage.GetInstance().Start(new Action(() =>
  153. {
  154. StirArmGoOrigin(fryIndex);
  155. }), "StirArmGoOrigin");
  156. }), "StirArmGoOrigin");
  157. ActionManage.GetInstance.Register(new Action(() =>
  158. {
  159. ThreadManage.GetInstance().Start(new Action(() =>
  160. {
  161. StirArmGoWork(fryIndex);
  162. }), "StirArmGoWork");
  163. }), "StirArmGoWork");
  164. ActionManage.GetInstance.Register(new Action(() =>
  165. {
  166. ThreadManage.GetInstance().Start(new Action(() =>
  167. {
  168. HBOTGoWork(fryIndex);
  169. }), "HBOTGoWork");
  170. }), "HBOTGoWork");
  171. ActionManage.GetInstance.Register(new Action(() =>
  172. {
  173. ThreadManage.GetInstance().Start(new Action(() =>
  174. {
  175. OutMeal(fryIndex);
  176. }), "OutMeal");
  177. }), "OutMeal");
  178. ActionManage.GetInstance.Register(new Action<object>((o) =>
  179. {
  180. ThreadManage.GetInstance().Start(new Action(() =>
  181. {
  182. SetFire(o,fryIndex);
  183. }), "SetFire");
  184. }), "SetFire");
  185. ActionManage.GetInstance.Register(new Action<object>((o) =>
  186. {
  187. ThreadManage.GetInstance().Start(new Action(() =>
  188. {
  189. SetFry(o);
  190. }), "SetFry");
  191. }), "SetFry");
  192. ActionManage.GetInstance.Register(new Action<object>((o) =>
  193. {
  194. ThreadManage.GetInstance().Start(new Action(() =>
  195. {
  196. SetStir(o,fryIndex);
  197. }), "SetStir");
  198. }), "SetStir");
  199. #endregion
  200. }
  201. #region 菜品库
  202. /// <summary>
  203. /// 菜品库数据写入
  204. /// </summary>
  205. /// <param name="address"></param>
  206. /// <param name="value"></param>
  207. private void MaterailLibrary_Write(string address,object value)
  208. {
  209. WriteControlExact(address, value, 1);
  210. }
  211. /// <summary>
  212. /// 菜品库初始化
  213. /// </summary>
  214. public void FoodLibInit()
  215. {
  216. MaterailLibrary_Write("", true);
  217. }
  218. /// <summary>
  219. /// 电磁阀启停
  220. /// </summary>
  221. /// <param name="o"></param>
  222. public void Electromagnetism(object o)
  223. {
  224. if (o == null) return;
  225. if (o is List<bool> bs && bs.Count == 1)
  226. {
  227. MaterailLibrary_Write("", bs[0]);
  228. }
  229. }
  230. public void GetDistance_1()
  231. {
  232. MaterailLibrary_Write("", true);
  233. }
  234. public void GetDistance_2()
  235. {
  236. MaterailLibrary_Write("", true);
  237. }
  238. public void GetDistance_3()
  239. {
  240. MaterailLibrary_Write("", true);
  241. }
  242. public void PawTurnFront()
  243. {
  244. MaterailLibrary_Write("", true);
  245. }
  246. public void PawTurnBack()
  247. {
  248. MaterailLibrary_Write("", true);
  249. }
  250. /// <summary>
  251. /// 设定机械臂的位置
  252. /// </summary>
  253. /// <param name="X"></param>
  254. /// <param name="y"></param>
  255. public void SetArmPosition(int X, int y)
  256. {
  257. MaterailLibrary_Write("", true);
  258. }
  259. #endregion
  260. /// <summary>
  261. /// 出调料
  262. /// </summary>
  263. /// <param name="o"></param>
  264. public void OutSeasoning(object o,int num)
  265. {
  266. if (o == null) return;
  267. if (o is List<int> ints && ints.Count == 2&&morkFs.ContainsKey(num))
  268. {
  269. FirePot1_Write(morkFs[num].PassWayValue[ints[0]], (ushort)ints[1],num);//写入通道值
  270. Thread.Sleep(400);
  271. FirePot1_Write(morkFs[num].StartPassWay[ints[0]], true, num);//开启通道
  272. Thread.Sleep(400);
  273. FirePot1_Write(morkFs[num].StartPassWay[ints[0]], false, num);//开启通道
  274. }
  275. }
  276. /// <summary>
  277. /// 出多个调料
  278. /// </summary>
  279. public void OutSeasonings(List<SeasoningList> seasoningLists,int num)
  280. {
  281. //防止越界
  282. if(!morkFs.ContainsKey(num))
  283. {
  284. return;
  285. }
  286. foreach (SeasoningList seasoning in seasoningLists)
  287. {
  288. FirePot1_Write(morkFs[num].PassWayValue[seasoning.Loc], (ushort)seasoning.Qty, num);
  289. Thread.Sleep(300);
  290. }
  291. foreach (SeasoningList seasoning in seasoningLists)
  292. {
  293. FirePot1_Write(morkFs[num].StartPassWay[seasoning.Loc], true, num);
  294. Thread.Sleep(300);
  295. }
  296. foreach (SeasoningList seasoning in seasoningLists)
  297. {
  298. FirePot1_Write(morkFs[num].StartPassWay[seasoning.Loc], false, num);
  299. Thread.Sleep(300);
  300. }
  301. foreach (SeasoningList seasoning in seasoningLists)
  302. {
  303. FirePot1_Write(morkFs[num].StartPassWay[seasoning.Loc], false, num);
  304. Thread.Sleep(300);
  305. }
  306. }
  307. #region 炒锅1
  308. private void FirePot1_Write(string address,object value,int num)
  309. {
  310. WriteControlExact(address, value, num);
  311. }
  312. /// <summary>
  313. /// 复位
  314. /// </summary>
  315. public void Plc1Reset(int num)
  316. {
  317. ThreadManage.GetInstance().Start(new Action(() =>
  318. {
  319. StopFire(num);
  320. Thread.Sleep(200);
  321. StopStir(num);
  322. Thread.Sleep(200);
  323. FirePot1_Write("LB5", false, num);
  324. Thread.Sleep(200);
  325. FirePot1_Write("LB3", false, num);
  326. Thread.Sleep(200);
  327. FirePot1_Write("LB6", false, num);
  328. Thread.Sleep(200);
  329. FirePot1_Write("LB7", false, num);
  330. Thread.Sleep(200);
  331. FirePot1_Write("LB4", false, num);
  332. Thread.Sleep(200);
  333. FirePot1_Write("LB53", false, num);
  334. if(morkFs.ContainsKey(num))
  335. {
  336. foreach (var item in morkFs[num].StartPassWay.Values)
  337. {
  338. Thread.Sleep(200);
  339. FirePot1_Write(item, false, num);
  340. }
  341. }
  342. }),"炒锅1初始化");
  343. }
  344. //加油
  345. public void AddOil()
  346. {
  347. }
  348. //加热启动
  349. public void StartFire(int num)
  350. {
  351. FirePot1_Write("LB1", true, num);
  352. Thread.Sleep(200);
  353. }
  354. //加热停止
  355. public void StopFire(int num)
  356. {
  357. FirePot1_Write("LB1", false, num);
  358. Thread.Sleep(200);
  359. }
  360. //搅拌启动
  361. public void StartStir(int num)
  362. {
  363. FirePot1_Write("LB2", true, num);
  364. Thread.Sleep(200);
  365. }
  366. //搅拌启停止
  367. public void StopStir(int num)
  368. {
  369. FirePot1_Write("LB2", false, num);
  370. Thread.Sleep(200);
  371. }
  372. //倒菜
  373. public void OutFood(int num)
  374. {
  375. if(!morkFs.ContainsKey(num))
  376. {
  377. return;
  378. }
  379. FirePot1_Write("LB3", true, num);
  380. MessageLog.GetInstance.Show("倒菜启动");
  381. Thread.Sleep(400);
  382. for (int i = 0; i < sleepCount && !morkFs[num].FryPot1_MaterialIntoPot; i++)
  383. {
  384. Thread.Sleep(sleepTime);
  385. if (i >= sleepCount - 1)
  386. {
  387. MessageLog.GetInstance.Show($"炒锅{num}倒菜超时");
  388. }
  389. }
  390. FirePot1_Write("LB3", false, num);
  391. Thread.Sleep(200);
  392. MessageLog.GetInstance.Show("倒菜完成");
  393. }
  394. //搅拌臂去原点位
  395. public void StirArmGoOrigin(int num)
  396. {
  397. if (!morkFs.ContainsKey(num))
  398. {
  399. return;
  400. }
  401. FirePot1_Write("LB5", true, num);
  402. MessageLog.GetInstance.Show("搅拌臂去原点位");
  403. for (int i = 0; i < sleepCount && !morkFs[num].ArmOnOrigin; i++)
  404. {
  405. Thread.Sleep(sleepTime);
  406. if (i >= sleepCount - 1)
  407. {
  408. MessageLog.GetInstance.Show($"炒锅{num}搅拌臂去原点位超时");
  409. }
  410. }
  411. //while (!morkFs[num].ArmOnOrigin)
  412. //{
  413. // Thread.Sleep(200);
  414. //}
  415. FirePot1_Write("LB5", false, num);
  416. Thread.Sleep(200);
  417. MessageLog.GetInstance.Show("搅拌臂到达原点位");
  418. }
  419. //搅拌臂去炒制位
  420. public void StirArmGoWork(int num)
  421. {
  422. if (!morkFs.ContainsKey(num))
  423. {
  424. return;
  425. }
  426. if (!morkFs[num].ArmOnWorking/* && morkFs[num].PotOnOrigin*/)
  427. {
  428. FirePot1_Write("LB6", true, num);
  429. MessageLog.GetInstance.Show("搅拌臂去工作位");
  430. for (int i = 0; i < sleepCount && !morkFs[num].ArmOnWorking; i++)
  431. {
  432. Thread.Sleep(sleepTime);
  433. if (i >= sleepCount - 1)
  434. {
  435. MessageLog.GetInstance.Show($"炒锅{num}搅拌臂去炒制位超时");
  436. }
  437. }
  438. //while (!morkFs[num].ArmOnWorking)
  439. //{
  440. // Thread.Sleep(200);
  441. //}
  442. FirePot1_Write("LB6", false, num);
  443. Thread.Sleep(200);
  444. MessageLog.GetInstance.Show("搅拌臂到达工作位");
  445. }
  446. }
  447. //HBOT放盒子到位
  448. public void HBOTGoWork(int num)
  449. {
  450. FirePot1_Write("LB7", true, num);
  451. Thread.Sleep(400);
  452. FirePot1_Write("LB7", false, num);
  453. }
  454. //出餐启动
  455. public void OutMeal(int num)
  456. {
  457. if (!morkFs[num].ArmOnOrigin /*&& morkFs[num].PotOnOrigin*/)
  458. {
  459. MessageLog.GetInstance.Show("搅拌臂不在原点位,无法完成出餐");
  460. return;
  461. }
  462. FirePot1_Write("LB4", true, num);
  463. Thread.Sleep(200);
  464. FirePot1_Write("LB4", false, num);
  465. }
  466. //加热挡位设定
  467. public void SetFire(object o, int num)
  468. {
  469. if (o == null) return;
  470. if (o is List<int> ints && ints.Count == 1)
  471. {
  472. FirePot1_Write("LW14", (ushort)ints[0],num);
  473. Thread.Sleep(200);
  474. }
  475. }
  476. public void SetFry(object o)
  477. {
  478. if (o == null) return;
  479. if (o is List<int> ints && ints.Count == 1)
  480. {
  481. fryIndex = ints[0] - 1;
  482. }
  483. }
  484. /// <summary>
  485. /// 搅拌挡位设定
  486. /// </summary>
  487. /// <param name="o"></param>
  488. public void SetStir(object o, int num)
  489. {
  490. if (o == null) return;
  491. if (o is List<int> ints && ints.Count == 1)
  492. {
  493. FirePot1_Write("LW15", (ushort)ints[0],num);
  494. Thread.Sleep(200);
  495. }
  496. }
  497. #endregion
  498. /// <summary>
  499. /// 本地菜单下单
  500. /// </summary>
  501. private void StartOrder(object o)
  502. {
  503. if(o==null) return;
  504. if(o is int goodId)
  505. {
  506. var res = LocalstirFryGoods?.FirstOrDefault(p => p.GoodsKey == goodId);//匹配订单对应制作流程
  507. if (res != null)
  508. {
  509. /* morkF.listStirBom.Add(res.StirFryBomInfo);*///添加订单制作流程
  510. if (StirFryGoodsQuenes.Count > 0) return;
  511. StirFryGoodsQuenes.Enqueue(new OrderLocInfo()
  512. {
  513. SuborderId = Guid.NewGuid().ToString(),
  514. StirPotActions = res.StirPotActions,
  515. GoodName = "本地菜品"
  516. });
  517. MessageLog.GetInstance.Show($"添加本地订单{res.GoodsKey}");
  518. }
  519. }
  520. }
  521. private void StartLocalOrder()
  522. {
  523. if (StirFryGoodsQuenes.Count > 0) return;//只能一个一个做
  524. if (Json<LocalPotStep>.Data.LocalstirFryGoods.StirPotActions.Count>0)
  525. {
  526. StirFryGoodsQuenes.Enqueue(new OrderLocInfo()
  527. {
  528. SuborderId = Guid.NewGuid().ToString(),
  529. StirPotActions = Json<LocalPotStep>.Data.LocalstirFryGoods.StirPotActions,
  530. GoodName = "本地菜品"
  531. });
  532. MessageLog.GetInstance.Show($"添加本地模拟的订单{Json<LocalPotStep>.Data.LocalstirFryGoods.GoodsKey}");
  533. }
  534. }
  535. private void StopLocalOrder()
  536. {
  537. //判断当前是否有炒制菜品
  538. if (nowStirFryGood == null) return;
  539. ThreadManage.GetInstance().StopTask(String.Format(striConst, fryIndex.ToString(), nowStirFryGood.GoodName), new Action(() => { Plc1Reset(fryIndex); }));
  540. }
  541. #endregion
  542. public override void ResetProgram()
  543. {
  544. morkFs.Clear();
  545. morkFs = new Dictionary<int, GVL_MorkF>();
  546. for (int i = 0; i < count; i++)
  547. {
  548. morkFs.Add(i, new GVL_MorkF());
  549. }
  550. }
  551. /// <summary>
  552. /// PLC数据读取
  553. /// </summary>
  554. public override void ReadData()
  555. {
  556. for (int i = 0; i < morkFs.Count; i++)
  557. {
  558. GetStatus("LB50", new Action<object>((objects) =>
  559. {
  560. if (!morkFs.ContainsKey(i))
  561. {
  562. return;
  563. }
  564. if(objects is bool[] bools)
  565. {
  566. morkFs[i].FryPot1_InitialComplete = bools[0];
  567. morkFs[i].FryPot1_HOBTPut = bools[1];
  568. morkFs[i].FryPot1_HOBTGet = bools[2];
  569. morkFs[i].FryPot1_MaterialIntoPot = bools[3];
  570. morkFs[i].OutFoodCompelete = bools[4];
  571. morkFs[i].CanOutFood = bools[5];
  572. morkFs[i].GetFoodCompelete = bools[6];
  573. morkFs[i].CanOutPotWashingWater = bools[7];
  574. morkFs[i].ArmOnOrigin = bools[8];
  575. morkFs[i].ArmOnWorking = bools[9];
  576. morkFs[i].PotOnOrigin = bools[10];
  577. }
  578. }), i);
  579. }
  580. for (int j = 0; j < morkFs.Count; j++)
  581. {
  582. GetStatus("LB74", new Action<object>((objects) =>
  583. {
  584. if (!morkFs.ContainsKey(j))
  585. {
  586. return;
  587. }
  588. if (objects is bool[] bools)
  589. {
  590. for (int i = 0; i < 14; i++)
  591. {
  592. morkFs[j].PassWay1_Compelete[i] = bools[i];
  593. }
  594. }
  595. }), j);
  596. }
  597. for (int i = 0; i < morkFs.Count; i++)
  598. {
  599. if (!morkFs.ContainsKey(i))
  600. {
  601. return;
  602. }
  603. GetStatus("LB90", new Action<object>((objects) =>
  604. {
  605. if (objects is bool[] bools)
  606. {
  607. morkFs[i].AutoMode = bools[0];
  608. }
  609. }), i);
  610. }
  611. for (int j = 0; j < morkFs.Count; j++)
  612. {
  613. GetStatus("VD808", new Action<object>((objects) =>
  614. {
  615. if (!morkFs.ContainsKey(j))
  616. {
  617. return;
  618. }
  619. if (objects is object[] bools)
  620. {
  621. for (int i = 0; i < 1; i++)
  622. {
  623. var a = bools[i];
  624. }
  625. }
  626. }), j);
  627. GetStatus("VD814", new Action<object>((objects) =>
  628. {
  629. if (!morkFs.ContainsKey(j))
  630. {
  631. return;
  632. }
  633. if (objects is object[] bools)
  634. {
  635. for (int i = 0; i < 1; i++)
  636. {
  637. var a = bools[i];
  638. }
  639. }
  640. }), j);
  641. GetStatus("VD816", new Action<object>((objects) =>
  642. {
  643. if (!morkFs.ContainsKey(j))
  644. {
  645. return;
  646. }
  647. if (objects is object[] bools)
  648. {
  649. for (int i = 0; i < 1; i++)
  650. {
  651. var a = bools[i];
  652. }
  653. }
  654. }), j);
  655. }
  656. }
  657. private void ServerInit()
  658. {
  659. //物料信息
  660. EventBus.EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  661. {
  662. if (@event == null) return;
  663. if (@event is MaterialDeliveryEvent material)
  664. {
  665. orderMaterialDelivery = material.orderMaterialDelivery;
  666. }
  667. });
  668. //配方数据信息
  669. EventBus.EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  670. {
  671. if (@event == null) return;
  672. if (@event is RecipeBomEvent recipe)
  673. {
  674. recipeBoms = recipe.recipeBoms;
  675. }
  676. });
  677. //小炒流程信息
  678. EventBus.EventBus.GetInstance().Subscribe<StirFryGoodsEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callback)
  679. {
  680. if (@event == null) return;
  681. if (@event is StirFryGoodsEvent stirFry)
  682. {
  683. if (stirFry.stirFrymessage.stirFryGoods.Count > 0)
  684. {
  685. foreach (var item in stirFry.stirFrymessage.stirFryGoods)
  686. {
  687. LocalstirFryGoods.Add(new StirFryGoods
  688. {
  689. GoodsKey = item.GoodsKey,
  690. StirPotActions = OrderSort(item.StirPotActions),
  691. });
  692. }
  693. }
  694. MessageLog.GetInstance.Show("接收到小炒流程信息");
  695. //流程解析
  696. foreach (var item in LocalstirFryGoods)
  697. {
  698. MessageLog.GetInstance.Show($"添加菜谱{item.GoodsKey}");
  699. // morkF.listStirBom.Add(item.StirFryBomInfo);//添加订单制作流程
  700. string MenuStep = "菜单步骤:";
  701. foreach (var items in item.StirPotActions)
  702. {
  703. switch (items.Actions)
  704. {
  705. case nameof(StirFryPotActionEnum.加热开启):
  706. MenuStep += items.Actions + ",";
  707. break;
  708. case nameof(StirFryPotActionEnum.设置加热挡位1):
  709. MenuStep += items.Actions + ",";
  710. break;
  711. case nameof(StirFryPotActionEnum.设置加热挡位2):
  712. MenuStep += items.Actions + ",";
  713. break;
  714. case nameof(StirFryPotActionEnum.设置加热挡位3):
  715. MenuStep += items.Actions + ",";
  716. break;
  717. case nameof(StirFryPotActionEnum.设置加热挡位4):
  718. MenuStep += items.Actions + ",";
  719. break;
  720. case nameof(StirFryPotActionEnum.设置加热挡位5):
  721. MenuStep += items.Actions + ",";
  722. break;
  723. case nameof(StirFryPotActionEnum.设置加热挡位6):
  724. MenuStep += items.Actions + ",";
  725. break;
  726. case nameof(StirFryPotActionEnum.设置加热挡位7):
  727. MenuStep += items.Actions + ",";
  728. break;
  729. case nameof(StirFryPotActionEnum.设置加热挡位8):
  730. MenuStep += items.Actions + ",";
  731. break;
  732. case nameof(StirFryPotActionEnum.设置加热挡位9):
  733. MenuStep += items.Actions + ",";
  734. break;
  735. case nameof(StirFryPotActionEnum.设置加热挡位10):
  736. MenuStep += items.Actions + ",";
  737. break;
  738. case nameof(StirFryPotActionEnum.停止加热):
  739. MenuStep += items.Actions + ",";
  740. break;
  741. case nameof(StirFryPotActionEnum.加调料):
  742. MenuStep += items.Actions + ",";
  743. break;
  744. case nameof(StirFryPotActionEnum.取原料):
  745. MenuStep += items.Actions + ",";
  746. break;
  747. case nameof(StirFryPotActionEnum.开启搅拌):
  748. MenuStep += items.Actions + ",";
  749. break;
  750. case nameof(StirFryPotActionEnum.设置搅拌挡位1):
  751. MenuStep += items.Actions + ",";
  752. break;
  753. case nameof(StirFryPotActionEnum.设置搅拌挡位2):
  754. MenuStep += items.Actions + ",";
  755. break;
  756. case nameof(StirFryPotActionEnum.设置搅拌挡位3):
  757. MenuStep += items.Actions + ",";
  758. break;
  759. case nameof(StirFryPotActionEnum.关闭搅拌):
  760. MenuStep += items.Actions + ",";
  761. break;
  762. case nameof(StirFryPotActionEnum.出餐启动):
  763. MenuStep += items.Actions + ",";
  764. break;
  765. case nameof(StirFryPotActionEnum.道菜启动):
  766. MenuStep += items.Actions + ",";
  767. break;
  768. case nameof(StirFryPotActionEnum.炒制菜品):
  769. MenuStep += items.Actions + ",";
  770. break;
  771. case nameof(StirFryPotActionEnum.搅拌臂原点位):
  772. MenuStep += items.Actions + ",";
  773. break;
  774. case nameof(StirFryPotActionEnum.搅拌臂炒制位):
  775. MenuStep += items.Actions + ",";
  776. break;
  777. case nameof(StirFryPotActionEnum.洗锅):
  778. MenuStep += items.Actions + ",";
  779. break;
  780. default:
  781. break;
  782. }
  783. }
  784. MessageLog.GetInstance.Show(MenuStep);
  785. }
  786. }
  787. });
  788. }
  789. private List<PotActions> OrderSort(List<PotActions> potActions)
  790. {
  791. if (potActions.Count > 1)
  792. {
  793. potActions.Sort(
  794. delegate (PotActions st1, PotActions st2)
  795. {
  796. //降序排列
  797. //return st2.FryTime.CompareTo(st1.FryTime);
  798. //升序版(颠倒 st1 和 st2 即可)
  799. return st1.FryTime.CompareTo(st2.FryTime);
  800. });
  801. }
  802. return potActions;
  803. }
  804. /// <summary>
  805. /// 订单状态发布
  806. /// </summary>
  807. /// <param name="subid"></param>
  808. /// <param name="oRDER_STATUS"></param>
  809. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  810. {
  811. EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid });
  812. }
  813. /// <summary>
  814. /// 数据解析
  815. /// </summary>
  816. private void DataParse(int num)
  817. {
  818. if (!morkFs.ContainsKey(num))
  819. {
  820. return;
  821. }
  822. EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  823. {
  824. if (@event == null) return;
  825. if (@event is DoOrderEvent order)
  826. {
  827. if (order.MorkOrder.GoodBatchings == null) return;
  828. OrderCount++;
  829. DeviceProcessLogShow($"接收到{OrderCount}次订单");
  830. Enum.GetNames(typeof(StirFryPotActionEnum));
  831. var res = LocalstirFryGoods?.FirstOrDefault(p => p.GoodsKey == order.MorkOrder.RecipeId);//匹配订单对应制作流程
  832. if (res != null)
  833. {
  834. /* morkF.listStirBom.Add(res.StirFryBomInfo);*///添加订单制作流程
  835. //添加到带炒小炒队列
  836. if (StirFryGoodsQuenes.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  837. {
  838. lock (lock_MainProcessExcute)
  839. {
  840. StirFryGoodsQuenes.Enqueue(new OrderLocInfo()
  841. {
  842. SuborderId = order.MorkOrder.SuborderId,
  843. StirPotActions = res.StirPotActions,
  844. GoodName = order.MorkOrder.GoodsName
  845. });
  846. }
  847. }
  848. }
  849. }
  850. });
  851. }
  852. /// <summary>
  853. /// 主任务
  854. /// </summary>
  855. public override void MainTask()
  856. {
  857. MainProcessExcute();
  858. //MinorProcessExcute();
  859. //SingleProcess();
  860. }
  861. private object lock_MainProcessExcute = new object();
  862. /// <summary>
  863. /// 炒锅主流程
  864. /// </summary>
  865. private void MainProcessExcute()
  866. {
  867. //判断是否有订单信息
  868. if(StirFryGoodsQuenes.Count > 0)
  869. {
  870. //遍历炒锅,找到合适、空闲的炒锅
  871. for(int i = 0;i<morkFs.Count;i++)
  872. {
  873. if (/*morkFs[i].AutoMode && morkFs[i].FryPot1_InitialComplete&&*/
  874. !morkFs[i].FryWorking)//炒锅在自动状态&&初始化完成&&是否在炒菜中
  875. {
  876. lock(lock_MainProcessExcute)
  877. {
  878. //待炒小炒队列出队列
  879. if (StirFryGoodsQuenes.TryDequeue(out var res))
  880. {
  881. //设置当前炒制菜品
  882. nowStirFryGood = res;
  883. //炒锅工作状态置为正在工作中
  884. morkFs[i].FryWorking = true;
  885. //空闲炒锅入队列
  886. morkFs[i].StirFryGoodsQuenes.Enqueue(res);
  887. MessageLog.GetInstance.Show($"炒锅{i}开始炒制菜品{res.GoodName}");
  888. //开启线程进行炒制
  889. ThreadManage.GetInstance().Start(new Action(() =>
  890. {
  891. try
  892. {
  893. foreach (var potActions in res.StirPotActions)
  894. {
  895. if (ThreadManage.GetInstance().IsCanncel(String.Format(striConst, i.ToString(), nowStirFryGood.GoodName)))
  896. {
  897. break;
  898. }
  899. switch (potActions.Actions)
  900. {
  901. case nameof(StirFryPotActionEnum.加热开启):
  902. StartFire(i);
  903. MessageLog.GetInstance.Show(potActions.Actions);
  904. break;
  905. case nameof(StirFryPotActionEnum.设置加热挡位1):
  906. SetFire(new List<int> { 1 }, i);
  907. MessageLog.GetInstance.Show(potActions.Actions);
  908. break;
  909. case nameof(StirFryPotActionEnum.设置加热挡位2):
  910. SetFire(new List<int> { 2 }, i);
  911. MessageLog.GetInstance.Show(potActions.Actions);
  912. break;
  913. case nameof(StirFryPotActionEnum.设置加热挡位3):
  914. SetFire(new List<int> { 3 }, i);
  915. MessageLog.GetInstance.Show(potActions.Actions);
  916. break;
  917. case nameof(StirFryPotActionEnum.设置加热挡位4):
  918. SetFire(new List<int> { 4 }, i);
  919. MessageLog.GetInstance.Show(potActions.Actions);
  920. break;
  921. case nameof(StirFryPotActionEnum.设置加热挡位5):
  922. SetFire(new List<int> { 5 }, i);
  923. MessageLog.GetInstance.Show(potActions.Actions);
  924. break;
  925. case nameof(StirFryPotActionEnum.设置加热挡位6):
  926. SetFire(new List<int> { 6 }, i);
  927. MessageLog.GetInstance.Show(potActions.Actions);
  928. break;
  929. case nameof(StirFryPotActionEnum.设置加热挡位7):
  930. SetFire(new List<int> { 7 }, i);
  931. MessageLog.GetInstance.Show(potActions.Actions);
  932. break;
  933. case nameof(StirFryPotActionEnum.设置加热挡位8):
  934. SetFire(new List<int> { 8 }, i);
  935. MessageLog.GetInstance.Show(potActions.Actions);
  936. break;
  937. case nameof(StirFryPotActionEnum.设置加热挡位9):
  938. SetFire(new List<int> { 9 }, i);
  939. MessageLog.GetInstance.Show(potActions.Actions);
  940. break;
  941. case nameof(StirFryPotActionEnum.设置加热挡位10):
  942. SetFire(new List<int> { 10 }, i);
  943. MessageLog.GetInstance.Show(potActions.Actions);
  944. break;
  945. case nameof(StirFryPotActionEnum.停止加热):
  946. StopFire(i);
  947. MessageLog.GetInstance.Show(potActions.Actions);
  948. break;
  949. case nameof(StirFryPotActionEnum.加调料):
  950. OutSeasonings(potActions.SeasoningLists, i);
  951. MessageLog.GetInstance.Show(potActions.Actions);
  952. break;
  953. case nameof(StirFryPotActionEnum.取原料):
  954. MessageLog.GetInstance.Show(potActions.Actions);
  955. break;
  956. case nameof(StirFryPotActionEnum.开启搅拌):
  957. StartStir(i);
  958. MessageLog.GetInstance.Show(potActions.Actions);
  959. break;
  960. case nameof(StirFryPotActionEnum.设置搅拌挡位1):
  961. SetStir(new List<int> { 1 }, i);
  962. MessageLog.GetInstance.Show(potActions.Actions);
  963. break;
  964. case nameof(StirFryPotActionEnum.设置搅拌挡位2):
  965. SetStir(new List<int> { 2 }, i);
  966. MessageLog.GetInstance.Show(potActions.Actions);
  967. break;
  968. case nameof(StirFryPotActionEnum.设置搅拌挡位3):
  969. SetStir(new List<int> { 3 }, i);
  970. MessageLog.GetInstance.Show(potActions.Actions);
  971. break;
  972. case nameof(StirFryPotActionEnum.关闭搅拌):
  973. StopStir(i);
  974. MessageLog.GetInstance.Show(potActions.Actions);
  975. break;
  976. case nameof(StirFryPotActionEnum.出餐启动):
  977. MessageLog.GetInstance.Show(potActions.Actions);
  978. break;
  979. case nameof(StirFryPotActionEnum.道菜启动):
  980. OutFood(i);
  981. break;
  982. case nameof(StirFryPotActionEnum.炒制菜品):
  983. Thread.Sleep(potActions.During * 1000);
  984. break;
  985. case nameof(StirFryPotActionEnum.搅拌臂原点位):
  986. StirArmGoOrigin(i);
  987. MessageLog.GetInstance.Show(potActions.Actions);
  988. break;
  989. case nameof(StirFryPotActionEnum.搅拌臂炒制位):
  990. StirArmGoWork(i);
  991. MessageLog.GetInstance.Show(potActions.Actions);
  992. break;
  993. case nameof(StirFryPotActionEnum.洗锅):
  994. MessageLog.GetInstance.Show(potActions.Actions);
  995. break;
  996. default:
  997. break;
  998. }
  999. }
  1000. Plc1Reset(i);//复位
  1001. Thread.Sleep(3000);
  1002. //回原点位
  1003. StirArmGoOrigin(i);
  1004. for (int i = 0; i < sleepCount && !morkFs[i].ArmOnOrigin; i++)
  1005. {
  1006. Thread.Sleep(sleepTime);
  1007. if (i >= sleepCount - 1)
  1008. {
  1009. MessageLog.GetInstance.Show($"炒锅{i}炒制过程完成后,搅拌臂去原点位超时");
  1010. }
  1011. }
  1012. //while (!morkFs[i].ArmOnOrigin)
  1013. //{
  1014. // Thread.Sleep(100);
  1015. //}
  1016. //出餐
  1017. //OutMeal(i);
  1018. MessageLog.GetInstance.Show($"菜品{res.GoodName}完成");
  1019. }
  1020. catch (Exception ex)
  1021. {
  1022. ThreadManage.GetInstance().StopTask($"炒锅{i}{res.GoodName}炒制线程");
  1023. MessageLog.GetInstance.Show($"炒锅{i}炒制菜品{res.GoodName}出错,错误信息:" + ex.Message);
  1024. }
  1025. finally
  1026. {
  1027. nowStirFryGood = null;
  1028. //炒完后出队列
  1029. morkFs[i].StirFryGoodsQuenes.TryDequeue(out var orderQueue);
  1030. morkFs[i].FryWorking = false;
  1031. }
  1032. }), String.Format(striConst, i.ToString(), nowStirFryGood.GoodName)/*$"炒锅{i}炒制{res.GoodName}线程"*/);
  1033. }
  1034. }
  1035. break;
  1036. }
  1037. }
  1038. }
  1039. }
  1040. //辅流程执行
  1041. //private void MinorProcessExcute()
  1042. //{
  1043. // if (!morkF.MinorProcessExcuteLock)
  1044. // {
  1045. // morkF.MinorProcessExcuteLock = true;
  1046. // Task.Run(() =>
  1047. // {
  1048. // if (morkF.MinorProcessFlag && morkF.TakeMaterialQueue.Count > 0 && morkF.listStirBom.Count > 0 )
  1049. // {
  1050. // morkF.MinorProessStatus = true;
  1051. // morkF.MainProcessStatus = false;
  1052. // StirFryBom bom = morkF.listStirBom.ElementAt(0);
  1053. // morkF.listStirBom.RemoveAt(0);
  1054. // foreach (var res in bom.StirFryActions)
  1055. // {
  1056. // DeviceProcessLogShow($"执行流程{res.Time}");
  1057. // //机器人线程
  1058. // Task taskRobot = Task.Run(new Action(() =>
  1059. // {
  1060. // foreach (var temp in res.RobotActions)
  1061. // {
  1062. // switch (temp)
  1063. // {
  1064. // }
  1065. // }
  1066. // }));
  1067. // //炒锅线程操作
  1068. // Task taskPot = Task.Run(new Action(() =>
  1069. // {
  1070. // foreach (var temp in res.PotActions)
  1071. // {
  1072. // switch (temp)
  1073. // {
  1074. // case StirFryPotAction.NONE:
  1075. // break;
  1076. // }
  1077. // }
  1078. // }));
  1079. // Task.WhenAll(taskRobot, taskPot).Wait();//等待所有线程结束
  1080. // Task.Delay(res.During * 1000).Wait();//当前流程延迟
  1081. // if (morkF.MainProcessWait)
  1082. // {
  1083. // if (morkF.MainHasTakeMaterial)
  1084. // {
  1085. // }
  1086. // else
  1087. // {
  1088. // //关闭灶加热
  1089. // //阻塞辅流程
  1090. // minorReset.WaitOne();
  1091. // //morkF.MinorProessStatus = true;
  1092. // //morkF.MainProcessStatus = false;
  1093. // }
  1094. // }
  1095. // }
  1096. // morkF.MinorOutMealComplete = true;
  1097. // }
  1098. // else
  1099. // {
  1100. // morkF.MinorProcessExcuteLock = false;//解除辅流程自锁
  1101. // }
  1102. // });
  1103. // }
  1104. //}
  1105. /// <summary>
  1106. /// 信号处理
  1107. /// </summary>
  1108. private void SingleProcess()
  1109. {
  1110. //if (!morkF.AutoMode)
  1111. //{
  1112. // if (morkF.IsAuto)
  1113. // {
  1114. // Plc1Reset();
  1115. // morkF.IsAuto = false;
  1116. // }
  1117. //}
  1118. //else morkF.IsAuto = true;
  1119. }
  1120. /// <summary>
  1121. /// 获取炒锅PLC的所有状态
  1122. /// </summary>
  1123. /// <param name="key"></param>
  1124. /// <param name="action"></param>
  1125. /// <param name="num">炒锅编号</param>
  1126. private void GetStatus(string key, Action<object> action,int num)
  1127. {
  1128. if(dicPort2peripheralStatus.ContainsKey(num))
  1129. {
  1130. if (dicPort2peripheralStatus[num].ContainsKey(key))
  1131. {
  1132. action((object)dicPort2peripheralStatus[num][key]);//获取PLC指定地址的状态值
  1133. }
  1134. }
  1135. }
  1136. ///// <summary>
  1137. ///// 写数据
  1138. ///// </summary>
  1139. ///// <param name="address"></param>
  1140. ///// <param name="value"></param>
  1141. //private void WriteData(string address, object value)
  1142. //{
  1143. // EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value });
  1144. //}
  1145. /// <summary>
  1146. /// 炒锅初始化
  1147. /// </summary>
  1148. public void PLCInite()
  1149. {
  1150. for(int i = 0;i<morkFs.Count;i++)
  1151. {
  1152. FirePot1_Write("LB0", true, i);
  1153. for (int j = 0; j < sleepCount && !morkFs[i].FryPot1_InitialComplete; j++)
  1154. {
  1155. Thread.Sleep(sleepTime);
  1156. if(j>=sleepCount-1)
  1157. {
  1158. MessageLog.GetInstance.Show($"炒锅{j}初始化超时");
  1159. }
  1160. }
  1161. //while (!morkFs[i].FryPot1_InitialComplete)
  1162. //{
  1163. // Thread.Sleep(500);
  1164. //}
  1165. FirePot1_Write("LB0", false, i);
  1166. }
  1167. }
  1168. /// <summary>
  1169. public override void Stop()
  1170. {
  1171. }
  1172. public override void SimOrder()
  1173. {
  1174. ActionManage.GetInstance.Register(morkSim, "模拟小炒锅1订单");
  1175. }
  1176. private void morkSim(object o)
  1177. {
  1178. //if (o == null) return;
  1179. //if(o is List<int> ins)
  1180. //{
  1181. // ThreadManage.GetInstance().Start(new Action(() =>
  1182. // {
  1183. // if (morkF.FryPot1_InitialComplete && morkF.AutoMode)//初始化完成&&自动模式&& 锅在原点位置
  1184. // {
  1185. // if (!morkF.ArmOnWorking)//搅拌臂是否在工作位
  1186. // {
  1187. // StirArmGoWork();
  1188. // while (!morkF.ArmOnWorking)
  1189. // {
  1190. // Thread.Sleep(500);
  1191. // }
  1192. // OutSeasoning(new List<int> { 1, 100 });//加油500g
  1193. // while (!morkF.PassWay1_1Compelete)
  1194. // {
  1195. // Thread.Sleep(1000);
  1196. // }
  1197. // WriteControlExact(morkF.StartPassWay[ 1], false);//开启通道关闭
  1198. // Thread.Sleep(500);
  1199. // SetFire(new List<int> { ins[1] });//加热三档
  1200. // StartFire();//开始加热
  1201. // Thread.Sleep(500);
  1202. // SetStir(new List<int> { ins[2] });//搅拌二挡
  1203. // Thread.Sleep(500);
  1204. // StartStir();//开始搅拌
  1205. // Thread.Sleep(ins[0]*1000);//加热10s
  1206. // OutSeasoning(new List<int> { 11, 30 });//加调料1 50g
  1207. // Thread.Sleep(400);
  1208. // OutSeasoning(new List<int> { 12, 30 });//加调料2 30g
  1209. // while (!morkF.PassWay1_11Compelete&& !morkF.PassWay1_12Compelete)
  1210. // {
  1211. // Thread.Sleep(1000);
  1212. // }
  1213. // WriteControlExact(morkF.StartPassWay[11], false);//开启通道关闭
  1214. // Thread.Sleep(500);
  1215. // WriteControlExact(morkF.StartPassWay[12], false);//开启通道信号关闭
  1216. // Thread.Sleep(500);
  1217. // OutFood();//倒菜品1
  1218. // while (!morkF.FryPot1_MaterialIntoPot)//菜品1倒菜完成
  1219. // {
  1220. // Thread.Sleep(500);
  1221. // }
  1222. // WriteControlExact("LB53", false);
  1223. // Thread.Sleep(500);
  1224. // SetFire(new List<int> { ins[4] });//菜品1加热档
  1225. // Thread.Sleep(500);
  1226. // SetStir(new List<int>() { ins[5] });//菜品1搅拌挡
  1227. // Thread.Sleep(ins[3]*1000);//菜品1炒制时间
  1228. // OutSeasoning(new List<int> {3, 8 });//加调料3 20g
  1229. // while (!morkF.PassWay1_3Compelete)
  1230. // {
  1231. // Thread.Sleep(1000);
  1232. // }
  1233. // WriteControlExact(morkF.StartPassWay[3], false);//开启通道信号关闭
  1234. // Thread.Sleep(500);
  1235. // OutFood();//倒菜菜品2
  1236. // while (!morkF.FryPot1_MaterialIntoPot)//菜品2倒菜完成
  1237. // {
  1238. // Thread.Sleep(500);
  1239. // }
  1240. // WriteControlExact("LB53", false);
  1241. // Thread.Sleep(500);
  1242. // SetFire(new List<int> { ins[7] });//菜品2加热档
  1243. // Thread.Sleep(500);
  1244. // SetStir(new List<int>() { ins[8] });//菜品2搅拌挡
  1245. // Thread.Sleep(ins[6] * 1000);//菜品2炒制时间
  1246. // StopStir();//停止搅拌
  1247. // Thread.Sleep(500);
  1248. // StopFire();//停止加热
  1249. // Thread.Sleep(2000);
  1250. // StirArmGoOrigin();//搅拌臂回原点位
  1251. // }
  1252. // }
  1253. // }), "模拟炒锅1订单");
  1254. //}
  1255. }
  1256. }
  1257. }