终端一体化运控平台
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

482 řádky
18 KiB

  1. using BPA.Message.Enum;
  2. using BPASmartClient.Device;
  3. using BPASmartClient.EventBus;
  4. using BPASmartClient.GSIceCream;
  5. using BPASmartClient.Lebai;
  6. using BPASmartClient.Message;
  7. using BPASmartClient.Model;
  8. using BPASmartClient.Model.冰淇淋.Enum;
  9. using BPASmartClient.Model.单片机;
  10. using BPASmartClient.Model.单片机.Enum;
  11. using BPASmartClient.Peripheral;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading;
  17. using System.Threading.Tasks;
  18. using static BPASmartClient.EventBus.EventBus;
  19. namespace BPASmartClient.MorkT
  20. {
  21. public class Control_MorkT : BaseDevice
  22. {
  23. public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.MORKT; } }
  24. GLV_MorkT morkT = new GLV_MorkT();
  25. public override void DoMain()
  26. {
  27. ServerInit();
  28. DataParse();
  29. EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CoffeEndCookEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  30. {
  31. if (morkT.MakeCoffeeOrder != null)
  32. morkT.MakeCoffeeOrder.OrderStatus = 1;
  33. });
  34. MessageLog.GetInstance.Show("MORKT 设备初始化完成");
  35. }
  36. public override void ResetProgram()
  37. {
  38. morkT = null;
  39. morkT = new GLV_MorkT();
  40. }
  41. public override void MainTask()
  42. {
  43. MakeCoffeeProcess();
  44. if(!LebaiRobot.GetInstance.GetInput())//取餐口有空余位置
  45. {
  46. MakeIceCreamProcess();
  47. MakeCoffeeComplete();
  48. }
  49. }
  50. public override void ReadData()
  51. {
  52. morkT.lebai = LebaiRobot.GetInstance.GetValueAsync();
  53. LebaiRobot.GetInstance.GetRobotModeStatus();
  54. }
  55. public override void Stop()
  56. {
  57. }
  58. private void ServerInit()
  59. {
  60. //物料信息
  61. EventBus.EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  62. {
  63. if (@event == null) return;
  64. if (@event is MaterialDeliveryEvent material)
  65. {
  66. orderMaterialDelivery = material.orderMaterialDelivery;
  67. }
  68. });
  69. //配方数据信息
  70. EventBus.EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  71. {
  72. if (@event == null) return;
  73. if (@event is RecipeBomEvent recipe)
  74. {
  75. recipeBoms = recipe.recipeBoms;
  76. }
  77. });
  78. }
  79. /// <summary>
  80. /// 数据解析
  81. /// </summary>
  82. private void DataParse()
  83. {
  84. EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  85. {
  86. if (@event == null) return;
  87. if (@event is DoOrderEvent order)
  88. {
  89. if (order.MorkOrder.GoodBatchings == null) return;
  90. OrderCount++;
  91. DeviceProcessLogShow($"接收到{OrderCount}次订单");
  92. //构建所有商品物料信息
  93. morkT.batchings = PolymerBatching.BuildAll();
  94. //商品类型
  95. GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER;
  96. string loc_Goods = string.Empty;
  97. foreach (var item in order.MorkOrder.GoodBatchings)
  98. {
  99. var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  100. if (res != null)
  101. {
  102. //验证商品是咖啡还是冰淇淋
  103. if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER)
  104. {
  105. //获取当前物料所属商品类型
  106. currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc);
  107. }
  108. //获取主料和容器位置
  109. if (morkT.batchings[res.BatchingLoc].BatchingClass == BATCHING_CLASS.MAIN_MATERIAL) loc_Goods = res.BatchingLoc;
  110. switch (currentGoodsType)
  111. {
  112. case GOODS_TYPE.COFFEE:
  113. if (morkT.morkOrderPushesCoffee.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  114. {
  115. morkT.morkOrderPushesCoffee.Enqueue(new OrderLocInfo()
  116. {
  117. SuborderId = order.MorkOrder.SuborderId,
  118. BatchingId = res.BatchingId,
  119. Loc = loc_Goods,
  120. GoodsName = order.MorkOrder.GoodsName,
  121. SortNum = order.MorkOrder.SortNum
  122. }) ;
  123. }
  124. break;
  125. case GOODS_TYPE.ICECREAM:
  126. if (morkT.morkOrderPushesIceCream.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
  127. {
  128. morkT.morkOrderPushesIceCream.Enqueue(new OrderLocInfo()
  129. {
  130. SuborderId = order.MorkOrder.SuborderId,
  131. BatchingId = res.BatchingId,
  132. Loc = loc_Goods,
  133. GoodsName = order.MorkOrder.GoodsName,
  134. SortNum = order.MorkOrder.SortNum
  135. });
  136. }
  137. break;
  138. case GOODS_TYPE.NEITHER:
  139. DeviceProcessLogShow("未知的商品类型");
  140. break;
  141. }
  142. }
  143. }
  144. }
  145. });
  146. }
  147. /// <summary>
  148. /// 验证当前是做咖啡还是做冰淇淋
  149. /// </summary>
  150. /// <param name="batchingLoc">物料位置</param>
  151. private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc)
  152. {
  153. if (morkT.batchings.ContainsKey(batchingLoc))
  154. return morkT.batchings[batchingLoc].GoodsType;
  155. return GOODS_TYPE.NEITHER;
  156. }
  157. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  158. {
  159. EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
  160. }
  161. private void Wait(int value = 101)
  162. {
  163. while (!(morkT.lebai.Ok && morkT.lebai.Value == value))
  164. {
  165. Thread.Sleep(5);
  166. }
  167. }
  168. /// <summary>
  169. /// 是否可以开始制作咖啡
  170. /// </summary>
  171. /// <returns></returns>
  172. private bool CoffeeCanMake()
  173. {
  174. bool canMake = (IsHealth && morkT.morkOrderPushesCoffee.Count > 0 && !morkT.IsCoffeeMake) ? true : false;
  175. return canMake;
  176. }
  177. /// <summary>
  178. /// 制作咖啡流程
  179. /// </summary>
  180. private void MakeCoffeeProcess()
  181. {
  182. if (CoffeeCanMake())
  183. {
  184. if (morkT.morkOrderPushesCoffee.TryDequeue(out OrderLocInfo orderLoc))
  185. {
  186. DeviceProcessLogShow($"开始制作 [咖啡] 订单[{orderLoc.SortNum}]");
  187. GetAndCheeckCoffe(orderLoc);
  188. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接咖啡后回原点);//把咖啡杯放到咖啡机机的位置后回原点
  189. Wait();
  190. LebaiRobot.GetInstance.SetValue(1);
  191. new DRCoffee_MakeCoffeeEvent() { DrinkCode = (Model.咖啡机.Enum.DrCoffeeDrinksCode)int.Parse(orderLoc.Loc) }.Publish(); //接咖啡控制
  192. DeviceProcessLogShow($"发送咖啡机制作{orderLoc.Loc}!");
  193. morkT.IsCoffeeMake = true; morkT.MakeCoffeeOrder = orderLoc;
  194. }
  195. }
  196. }
  197. /// <summary>
  198. /// 咖啡机制作完咖啡,取走并放到取餐口,最后回原点
  199. /// </summary>
  200. private void MakeCoffeeComplete()
  201. {
  202. if (morkT.IsCoffeeMake && IsHealth)
  203. {
  204. if (morkT.MakeCoffeeOrder != null && morkT.MakeCoffeeOrder.OrderStatus == 1)
  205. {
  206. DeviceProcessLogShow($"将咖啡移动到取餐位 [咖啡] 订单[{morkT.MakeCoffeeOrder.SortNum}]");
  207. DoCoffeeQC(morkT.MakeCoffeeOrder);
  208. morkT.MakeCoffeeOrder = null;
  209. morkT.IsCoffeeMake = false;
  210. }
  211. }
  212. }
  213. /// <summary>
  214. /// 将咖啡杯从咖啡机 取走到 取餐口
  215. /// </summary>
  216. private void DoCoffeeQC(OrderLocInfo order)
  217. {
  218. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡出餐);
  219. Wait();
  220. LebaiRobot.GetInstance.SetValue(1);
  221. //订单状态改变:完成
  222. OrderChange(order.SuborderId, ORDER_STATUS.COMPLETED_COOK);
  223. DeviceProcessLogShow($"{order.GoodsName}等待取餐");
  224. //WaitTakeMealOrder.Enqueue(order);
  225. }
  226. /// <summary>
  227. /// 取咖啡杯&&咖啡杯检测 若检测失败机器人回原点
  228. /// </summary>
  229. /// <param name="order"></param>
  230. private void GetAndCheeckCoffe(OrderLocInfo order)
  231. {
  232. LebaiRobot.GetInstance.SetValue(0);
  233. OrderChange(order.SuborderId, ORDER_STATUS.COOKING);
  234. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡杯);
  235. Wait();
  236. new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
  237. Thread.Sleep(500);
  238. DeviceProcessLogShow("尝试取咖啡杯!");
  239. LebaiRobot.GetInstance.SetValue(1);
  240. int count = 2;
  241. p:
  242. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯检测);
  243. Wait();
  244. LebaiRobot.GetInstance.SetValue(1);
  245. if (!LebaiRobot.GetInstance.GetInput())
  246. {
  247. if (count >= 3)
  248. {
  249. //退出循环回到初始位置
  250. DeviceProcessLogShow($"执行{count}次取咖啡杯,仍为成功,订单默认废弃,机器人回到初始位置!");
  251. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯回原点);
  252. Wait();
  253. LebaiRobot.GetInstance.SetValue(1);
  254. return;
  255. }
  256. DeviceProcessLogShow("执行二次取咖啡杯");
  257. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取咖啡杯);
  258. Wait();
  259. new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
  260. LebaiRobot.GetInstance.SetValue(1);
  261. count++;
  262. goto p;
  263. }
  264. DeviceProcessLogShow("取咖啡杯完成");
  265. }
  266. /// <summary>
  267. /// 冰淇淋是否可以开始制作
  268. /// </summary>
  269. /// <returns></returns>
  270. private bool IceCreamCanMake()
  271. {
  272. bool canMake = (IsHealth && morkT.morkOrderPushesIceCream.Count > 0) ? true : false;
  273. return canMake;
  274. }
  275. /// <summary>
  276. /// 制作冰淇淋流程
  277. /// </summary>
  278. private void MakeIceCreamProcess()
  279. {
  280. if (IceCreamCanMake())
  281. {
  282. if (MorkIStatus.GetInstance().CurrentMode != MORKI_MODE.制冷模式) new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
  283. if (MorkIStatus.GetInstance().CXB >= 86 && morkT.morkOrderPushesIceCream.Count > 0)//成型比大于86才可以制作
  284. {
  285. if (LebaiRobot.GetInstance.GetInput(3))
  286. {
  287. if (morkT.IceIsOK) DeviceProcessLogShow("请检查冰淇淋出料口有无遮挡");
  288. morkT.IceIsOK = false;
  289. }
  290. else if (morkT.morkOrderPushesIceCream.TryDequeue(out OrderLocInfo order))
  291. {
  292. morkT.IceIsOK = true;
  293. DeviceProcessLogShow($"开始制作 [冰淇淋] 订单[{order.SortNum}]");
  294. DoIceCream(order);
  295. }
  296. }
  297. }
  298. }
  299. /// <summary>
  300. /// 做冰淇淋
  301. /// </summary>
  302. private void DoIceCream(OrderLocInfo order)
  303. {
  304. GetIceCreamCup();
  305. CheckICeCreaCup();
  306. GetIceCream(order);
  307. PutIceCream(order);
  308. }
  309. /// <summary>
  310. /// 取冰淇淋杯
  311. /// </summary>
  312. private void GetIceCreamCup()
  313. {
  314. LebaiRobot.GetInstance.SetValue(0);
  315. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取冰淇淋杯);
  316. Wait();
  317. new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
  318. Thread.Sleep(500);
  319. DeviceProcessLogShow("尝试取冰淇淋杯!");
  320. }
  321. /// <summary>
  322. /// 冰淇淋杯检测,失败后机器人回到原点
  323. /// </summary>
  324. private void CheckICeCreaCup()
  325. {
  326. int count = 2;
  327. LebaiRobot.GetInstance.SetValue(1);
  328. p:
  329. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯检测);
  330. Wait();
  331. LebaiRobot.GetInstance.SetValue(1);
  332. if (!LebaiRobot.GetInstance.GetInput())
  333. {
  334. if (count >= 3)
  335. {
  336. //退出循环回到初始位置
  337. DeviceProcessLogShow($"执行{count}次取冰淇淋杯,仍未成功,订单默认废弃,机器人回到初始位置!");
  338. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯回原点);
  339. Wait();
  340. LebaiRobot.GetInstance.SetValue(1);
  341. return;
  342. }
  343. DeviceProcessLogShow($"执行{count}次取冰淇淋杯!");
  344. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取冰淇淋杯);
  345. new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
  346. Wait();
  347. LebaiRobot.GetInstance.SetValue(1);
  348. count++;
  349. goto p;
  350. }
  351. DeviceProcessLogShow("冰淇淋杯检测完成");
  352. }
  353. /// <summary>
  354. /// 机器人取接冰淇淋
  355. /// </summary>
  356. /// <param name="order"></param>
  357. private void GetIceCream(OrderLocInfo order)
  358. {
  359. //制冷模式
  360. new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
  361. LebaiRobot.GetInstance.SetValue(0);
  362. OrderChange(order.SuborderId, ORDER_STATUS.COOKING);
  363. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接1号冰淇淋);
  364. Wait();
  365. bool doItResult = true;
  366. //出料
  367. new GSIceCream_DischargeEvent().Publish(delegate (object[] args)
  368. {
  369. doItResult = (bool)args[0];
  370. });
  371. if (doItResult)
  372. {
  373. IceCreamCookCheck();
  374. }
  375. else
  376. {
  377. int count_1 = 0;
  378. while (MorkIStatus.GetInstance().CXB <= 86)
  379. {
  380. Thread.Sleep(5);
  381. count_1++;
  382. if (count_1 >= 2000)
  383. break;
  384. }
  385. IceCreamCookCheck();
  386. }
  387. LebaiRobot.GetInstance.SetValue(1);
  388. }
  389. /// <summary>
  390. /// 把冰淇淋放到取餐位后回原点
  391. /// </summary>
  392. /// <param name="order"></param>
  393. private void PutIceCream(OrderLocInfo order)
  394. {
  395. while (LebaiRobot.GetInstance.GetInput())
  396. {
  397. Thread.Sleep(500);
  398. }
  399. LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_放冰淇淋位置);
  400. Wait();
  401. LebaiRobot.GetInstance.SetValue(1);
  402. //订单状态改变:完成
  403. OrderChange(order.SuborderId, ORDER_STATUS.COMPLETED_COOK);
  404. DeviceProcessLogShow($"{order.GoodsName}等待取餐");
  405. //WaitTakeMealOrder.Enqueue(order);
  406. }
  407. /// <summary>
  408. /// 冰淇淋机器制作冰淇淋
  409. /// </summary>
  410. public void IceCreamCookCheck()
  411. {
  412. int retry = 3;
  413. DateTime beginTime = DateTime.Now;
  414. while (!LebaiRobot.GetInstance.GetInput(3))
  415. {
  416. if (retry <= 0 && DateTime.Now.Subtract(beginTime).TotalSeconds >= 10)
  417. {
  418. DeviceProcessLogShow("超时未出料,重试次数用尽");
  419. break;
  420. }
  421. if (DateTime.Now.Subtract(beginTime).TotalSeconds > 5)
  422. {
  423. DeviceProcessLogShow("超时未出料,重新发送打料指令");
  424. new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.打料 }.Publish();
  425. beginTime = DateTime.Now;
  426. retry--;
  427. }
  428. Thread.Sleep(10);
  429. }
  430. DeviceProcessLogShow("开始等待6s");
  431. Thread.Sleep(5000);
  432. }
  433. }
  434. }