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

480 lines
18 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Collections.Concurrent;
  7. using System.Diagnostics;
  8. using System.Threading.Tasks;
  9. using BPASmartClient.Device;
  10. using BPA.Message.Enum;
  11. using BPA.Message;
  12. using BPA.Helper;
  13. using BPASmartClient.Model.咖啡机.Enum;
  14. using BPASmartClient.Model;
  15. using BPASmartClient.Model.乐白机器人;
  16. using BPASmartClient.Model.单片机;
  17. using BPASmartClient.Model.PLC;
  18. using BPASmartClient.DRCoffee;
  19. using BPASmartClient.LebaiRobot;
  20. using System.Text.RegularExpressions;
  21. using static BPA.Helper.EventBus;
  22. namespace BPASmartClient.MorkT_Container
  23. {
  24. public class Control_MorkT_Container : BaseDevice
  25. {
  26. private Dictionary<string, PolymerBatching> batchings = new Dictionary<string, PolymerBatching>();
  27. //容器位置
  28. private string holderLoc;
  29. //主料位置
  30. private string mainMaterialLoc;
  31. public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.MORKT; } }
  32. GVL_MorkT morkTLebaiJC =new GVL_MorkT();
  33. public override void DoMain()
  34. {
  35. if (Json<KeepDataBase>.Data.IsVerify)
  36. {
  37. IsHealth = true;
  38. }
  39. IsHealth = true;
  40. serverInit();
  41. DataParse();
  42. ActionManage.GetInstance.Register(new Action<object>((o) => { SimOrder(o); }), "SimOrder");//模拟订单委托注册
  43. }
  44. private void serverInit()
  45. {
  46. EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  47. {
  48. if (@event == null) return;
  49. if (@event is MaterialDeliveryEvent material)
  50. {
  51. orderMaterialDelivery = material.orderMaterialDelivery;
  52. }
  53. });
  54. }
  55. private void DataParse()
  56. {
  57. EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  58. {
  59. if (@event == null) return;
  60. if (@event is DoOrderEvent order)
  61. {
  62. if (order.MorkOrder.GoodBatchings == null) return;
  63. OrderCount++;
  64. DeviceProcessLogShow($"接收到{OrderCount}次订单");
  65. batchings = PolymerBatching.BuildAll();
  66. //商品类型
  67. GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER;
  68. foreach (var item in order.MorkOrder.GoodBatchings)
  69. {
  70. var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  71. if (res != null)
  72. {
  73. //验证商品是做的某种饮料
  74. if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER)
  75. {
  76. //获取当前物料所属商品类型
  77. currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc);
  78. }
  79. switch (batchings[res.BatchingLoc].BatchingClass)
  80. {
  81. case BATCHING_CLASS.HOLDER:
  82. holderLoc = res.BatchingLoc;
  83. break;
  84. case BATCHING_CLASS.MAIN_MATERIAL:
  85. mainMaterialLoc = res.BatchingLoc;
  86. break;
  87. }
  88. //根据商品类型执行具体制作流程
  89. switch (currentGoodsType)
  90. {
  91. case GOODS_TYPE.COFFEE:
  92. if (morkTLebaiJC.morkOrderPushesCoffee.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  93. {
  94. morkTLebaiJC.morkOrderPushesCoffee.Enqueue(new OrderLocInfo()
  95. {
  96. SuborderId = order.MorkOrder.SuborderId,
  97. BatchingId = res.BatchingId,
  98. Loc = ushort.Parse( mainMaterialLoc),
  99. GoodName = order.MorkOrder.GoodsName,
  100. });
  101. }
  102. break;
  103. case GOODS_TYPE.NEITHER:
  104. DeviceProcessLogShow("未知的商品类型");
  105. break;
  106. }
  107. }
  108. }
  109. }
  110. });
  111. }
  112. /// <summary>
  113. /// 将空杯放好到接饮料的地方的标志位
  114. /// </summary>
  115. private bool bFirstTrig_Coffee = false;
  116. /// <summary>
  117. /// 延迟的超时时间
  118. /// </summary>
  119. DateTime delayTimeOut_Coffee;
  120. public override void MainTask()
  121. {
  122. if (morkTLebaiJC.morkOrderPushesCoffee.Count > 0 && morkTLebaiJC.IsHaveCoffeeCup)
  123. {
  124. EventBus.GetInstance().Subscribe<DRCoffee_CoffeEndCookEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  125. {
  126. if (morkTLebaiJC.IsHaveCoffeeCup && morkTLebaiJC.MakeCoffeeEnd != true)
  127. {
  128. morkTLebaiJC.MakeCoffeeEnd = true;
  129. bFirstTrig_Coffee = false;
  130. }
  131. });
  132. if (morkTLebaiJC.IsHaveCoffeeCup && morkTLebaiJC.MakeCoffeeEnd != true)
  133. {
  134. if (!bFirstTrig_Coffee)
  135. {
  136. bFirstTrig_Coffee = true;
  137. delayTimeOut_Coffee = DateTime.Now;
  138. }
  139. else if (DateTime.Now.Subtract(delayTimeOut_Coffee).TotalSeconds > 180 && bFirstTrig_Coffee == true)
  140. {
  141. DeviceProcessLogShow("接咖啡超时,接咖啡结束,等待取咖啡");
  142. bFirstTrig_Coffee = false;
  143. morkTLebaiJC.MakeCoffeeEnd = true;
  144. }
  145. }
  146. }
  147. DoCoffee();
  148. }
  149. /// <summary>
  150. /// 订单状态改变
  151. /// </summary>
  152. /// <param name="subid"></param>
  153. /// <param name="oRDER_STATUS"></param>
  154. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  155. {
  156. EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
  157. }
  158. /// <summary>
  159. /// 验证商品是做的某种饮料
  160. /// </summary>
  161. /// <param name="batchingLoc">物料位置</param>
  162. private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc)
  163. {
  164. if (batchings.ContainsKey(batchingLoc))
  165. return batchings[batchingLoc].GoodsType;
  166. return GOODS_TYPE.NEITHER;
  167. }
  168. /// <summary>
  169. /// 乐白的场景结束等待
  170. /// </summary>
  171. /// <param name="value"></param>
  172. private void Wait(int value = 101)
  173. {
  174. while (!((bool)peripheralStatus["RobotOK"] && (int)peripheralStatus["RobotValue"] == value))
  175. {
  176. Thread.Sleep(5);
  177. }
  178. EventBus.GetInstance().Publish(new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }, (o) => { });
  179. }
  180. /// <summary>
  181. /// 乐白的场景
  182. /// </summary>
  183. /// <param name="sen"></param>
  184. private void Sence(int sen)
  185. {
  186. new LebaiRobot_LebaiSenceEvent { DeviceId = DeviceId, LebaiSence = sen }.Publish();
  187. }
  188. /// <summary>
  189. /// 乐白的数字量输出
  190. /// </summary>
  191. /// <param name="value"></param>
  192. /// <param name="pin"></param>
  193. private void Output(bool value,int pin)
  194. {
  195. new LebaiRobot_SetOutPutEvent { DeviceId = DeviceId, Pin = pin,Value=value }.Publish();
  196. }
  197. bool outCupCheck = false;//放纸杯位置有无判断
  198. /// <summary>
  199. /// 判断是否有咖啡订单
  200. /// </summary>
  201. /// <returns></returns>
  202. private bool IsMakeCoffee()
  203. {
  204. bool bMake = (IsHealth && morkTLebaiJC.morkOrderPushesCoffee.Count > 0 && !morkTLebaiJC.IsHaveCoffeeCup) ? true : false;
  205. return bMake;
  206. }
  207. /// <summary>
  208. /// 做咖啡流程
  209. /// </summary>
  210. private void DoCoffee()
  211. {
  212. if (IsMakeCoffee())
  213. {
  214. PickUpCoffee();//接咖啡
  215. morkTLebaiJC.IsHaveCoffeeCup = true;
  216. }
  217. else if(morkTLebaiJC.MakeCoffeeEnd)
  218. {
  219. try
  220. {
  221. PutCoffeeCup();
  222. morkTLebaiJC.MakeCoffeeEnd = false;
  223. morkTLebaiJC.IsHaveCoffeeCup = false;
  224. morkTLebaiJC.morkOrderPushesCoffee.TryDequeue(out OrderLocInfo orderLoc);
  225. }
  226. catch (Exception ex)
  227. {
  228. MessageLog.GetInstance.ShowEx(ex.ToString());
  229. }
  230. }
  231. }
  232. #region 做咖啡流程
  233. /// <summary>
  234. /// 接咖啡
  235. /// </summary>
  236. private void PickUpCoffee()
  237. {
  238. if (!morkTLebaiJC.IsHaveCoffeeCup)
  239. {
  240. outCupCheck = false;
  241. OrderChange(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
  242. EventBus.GetInstance().Publish(new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }, (o) => { });
  243. int resultTakeCup = takeCup();
  244. if (resultTakeCup == 1)
  245. {
  246. Sence(GVL_MorkT.攀华_接咖啡);
  247. Wait();
  248. new DRCoffee_MakeCoffeeEvent() { DeviceId=DeviceId, DrinkCode = (DrCoffeeDrinksCode)(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).Loc)}.Publish();
  249. }
  250. else
  251. {
  252. DeviceProcessLogShow("取杯失败 回到初始位,请及时处理!!");
  253. /*new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish();
  254. Sence(GVL_MorkT.攀华_初始位);
  255. Wait();*/
  256. }
  257. }
  258. }
  259. /// <summary>
  260. /// 咖啡杯接好,放咖啡杯
  261. /// </summary>
  262. private void PutCoffeeCup()
  263. {
  264. while (morkTLebaiJC.RobotGetInput0)//判断放杯位置是否有物品
  265. {
  266. if (!outCupCheck)
  267. DeviceProcessLogShow("成品处有纸杯存在,请取走!!");
  268. outCupCheck = true;
  269. }
  270. outCupCheck = false;
  271. Sence(GVL_MorkT.攀华_放杯);
  272. Wait();
  273. if (!morkTLebaiJC.RobotGetInput0)
  274. {
  275. DeviceProcessLogShow("咖啡杯未安全放置在放杯位");
  276. }
  277. Sence(GVL_MorkT.攀华_初始位);
  278. Wait();
  279. while (morkTLebaiJC.RobotGetTcpInput)
  280. {
  281. DeviceProcessLogShow("咖啡杯仍在夹爪上");
  282. }
  283. OrderChange(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE);
  284. DeviceProcessLogShow($"-------------{Regex.Replace(morkTLebaiJC.morkOrderPushesCoffee.ElementAt(0).GoodName, @"[\r\n]", "")}制作完成------------");
  285. }
  286. #endregion
  287. /// <summary>
  288. /// 取杯的次数
  289. /// </summary>
  290. private int nCnt;
  291. /// <summary>
  292. /// 取杯流程
  293. /// </summary>
  294. /// <returns>0:无意义,1:取杯成功 2:取杯失败</returns>
  295. private int takeCup()
  296. {
  297. try
  298. {
  299. nCnt = 0;
  300. Sence(GVL_MorkT.攀华_初始位);
  301. Wait();
  302. Sence(GVL_MorkT.攀华_取杯);
  303. Wait();
  304. Sence(GVL_MorkT.攀华_落杯);
  305. Wait();//落杯使用机器人控制
  306. /*new LebaiRobot_SetOutPutEvent { DeviceId = DeviceId, Value = true, Pin = 1 }.Publish();//落杯器电机转动
  307. while (true)
  308. {
  309. if (GetStatus<bool>("LeibaiGetInput2"))
  310. {
  311. break;
  312. }
  313. }
  314. while (true)
  315. {
  316. if (!GetStatus<bool>("LeibaiGetInput2"))
  317. {
  318. break;
  319. }
  320. }
  321. new LebaiRobot_SetOutPutEvent { DeviceId = DeviceId, Value = true, Pin = 0 }.Publish();//落杯器电机转动*/
  322. nCnt++;
  323. Thread.Sleep(2000);
  324. while (!morkTLebaiJC.RobotGetTcpInput) //读取传感器的值
  325. {
  326. if (nCnt > 3)
  327. {
  328. nCnt = 0;
  329. DeviceProcessLogShow("三次取杯失败,回原点");
  330. Sence(GVL_MorkT.攀华_安全位);
  331. Wait();
  332. new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish();
  333. Sence(GVL_MorkT.攀华_初始位);
  334. Wait();
  335. new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish();
  336. return 2;
  337. }
  338. else
  339. {
  340. nCnt++;
  341. Sence(GVL_MorkT.攀华_二次取杯);
  342. Wait();
  343. EventBus.GetInstance().Publish(new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }, (o) => { });
  344. Sence(GVL_MorkT.攀华_落杯);
  345. Wait();
  346. EventBus.GetInstance().Publish(new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }, (o) => { });
  347. }
  348. Thread.Sleep(100);
  349. }
  350. return 1;
  351. }
  352. catch (Exception ex)
  353. {
  354. DeviceProcessLogShow(ex.ToString());
  355. }
  356. return 2;
  357. }
  358. public void SimOrder<T>(T simOrder)
  359. {
  360. }
  361. #region 流程控制
  362. private void GetStatus(string key, Action<object> action)
  363. {
  364. if (peripheralStatus.ContainsKey(key))
  365. {
  366. if (peripheralStatus[key] != null)
  367. {
  368. action?.Invoke(peripheralStatus[key]);
  369. }
  370. }
  371. }
  372. public override void ReadData()
  373. {
  374. #region 乐白机器人状态
  375. GetStatus("RobotIsConnected", new Action<object>((o) =>
  376. {
  377. if (o is bool b)
  378. {
  379. morkTLebaiJC.RobotIsConnected = b;
  380. }
  381. }));
  382. GetStatus("RobotMode", new Action<object>((o) =>
  383. {
  384. if (o is ELebaiRModel eLebaiRModel)
  385. {
  386. morkTLebaiJC.RobotMode = eLebaiRModel;
  387. }
  388. }));
  389. GetStatus("LeibaiGetTcpInput", new Action<object>((o) =>
  390. {
  391. if (o is bool b)
  392. {
  393. morkTLebaiJC.RobotGetTcpInput = b;
  394. }
  395. }));
  396. GetStatus("LeibaiGetInput1", new Action<object>((o) =>
  397. {
  398. if (o is bool b)
  399. {
  400. morkTLebaiJC.RobotGetInput0 = b;
  401. }
  402. }));
  403. GetStatus("LeibaiGetInput2", new Action<object>((o) =>
  404. {
  405. if (o is bool b)
  406. {
  407. morkTLebaiJC.RobotGetInput1 = b;
  408. }
  409. }));
  410. GetStatus("LeibaiGetInput3", new Action<object>((o) =>
  411. {
  412. if (o is bool b)
  413. {
  414. morkTLebaiJC.RobotGetInput2 = b;
  415. }
  416. }));
  417. GetStatus("LeibaiGetInput4", new Action<object>((o) =>
  418. {
  419. if (o is bool b)
  420. {
  421. morkTLebaiJC.RobotGetInput3 = b;
  422. }
  423. }));
  424. #endregion
  425. }
  426. #endregion
  427. public override void Stop()
  428. {
  429. }
  430. public override void ResetProgram()
  431. {
  432. }
  433. public override void SimOrder()
  434. {
  435. EventBus.GetInstance().Subscribe<MorkTSimOrder>(0, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  436. {
  437. string guid = Guid.NewGuid().ToString();
  438. if (@event != null && @event is MorkTSimOrder msm)
  439. {
  440. DeviceProcessLogShow("----开始模拟订单----");
  441. if (msm.OrderNum == 1)
  442. {
  443. morkTLebaiJC.morkOrderPushesCoffee.Enqueue(new OrderLocInfo() { Loc =(ushort)msm.DrinkCode, SuborderId = guid, GoodName="模拟咖啡订单" });
  444. }
  445. }
  446. });
  447. }
  448. }
  449. }