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.
 
 

472 lines
17 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Linq;
  5. using System.Threading;
  6. using BPA.Message;
  7. using HBLConsole.Communication;
  8. using HBLConsole.Factory;
  9. using HBLConsole.GVL;
  10. using HBLConsole.Interface;
  11. using HBLConsole.Model;
  12. using HBLConsole.Service;
  13. using HBLDevice.Coffee;
  14. using HBLDevice.IceCream;
  15. using Robotc;
  16. using System.Collections.Concurrent;
  17. using System.Diagnostics;
  18. using BPA.Message.IOT;
  19. using HBLDevice.ICChip;
  20. using System.Threading.Tasks;
  21. namespace HBLConsole.MORKIC
  22. {
  23. /*
  24. * 冰淇淋咖啡机组合套装
  25. * 物料位置:
  26. * 1:冰淇料
  27. * 2:冰淇淋杯
  28. * 5:咖啡
  29. * 6:咖啡杯
  30. */
  31. public class Control_MORKIC : IControl
  32. {
  33. GVL_MORIC mORKD = new GVL_MORIC();
  34. //咖啡机主控程序
  35. private CoffeeMachine coffeeMachine;
  36. //单片机主控程序
  37. private ICChipMachine icchipMachine;
  38. //广绅单口冰淇淋机
  39. private IceCreamMachine iceCreamMachine;
  40. //物料存放位置
  41. private Dictionary<string, PolymerBatching> batchings = new Dictionary<string, PolymerBatching>();
  42. //容器位置
  43. private string holderLoc;
  44. //主料位置
  45. private string mainMaterialLoc;
  46. //子订单ID
  47. private string subOrderId;
  48. /// <summary>
  49. /// 获取乐百机器人的数据
  50. /// </summary>
  51. SignalResult lebai = new SignalResult();
  52. private bool enableFunny = false;
  53. private DateTime lastRecvdOrder = DateTime.Now;
  54. private bool working = false;
  55. public void ConnectOk()
  56. {
  57. }
  58. ConcurrentQueue<MorkOrderPush> morkOrderPushes = new ConcurrentQueue<MorkOrderPush>();
  59. public void Init()
  60. {
  61. ActionManage.GetInstance.Register(new Action<object>((s) =>
  62. {
  63. if (s is DrCoffeeDrinksCode cf)
  64. {
  65. mainMaterialLoc = ((int)cf).ToString();
  66. DoCoffee();
  67. }
  68. }), "SimCoffee");
  69. //构建所有商品物料信息
  70. batchings = PolymerBatching.BuildAll();
  71. EventBus.GetInstance().Subscribe<CoffeEndCook>(CoffeEndCookHandle);
  72. System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
  73. //一系列外围基础配置
  74. var com_Coffee = config.AppSettings.Settings["COM_Coffee"].Value;
  75. var baud_Coffee = config.AppSettings.Settings["BAUD_Coffee"].Value;
  76. var com_IceCream = config.AppSettings.Settings["COM_IceCream"].Value;
  77. var baud_IceCream = config.AppSettings.Settings["BAUD_IceCream"].Value;
  78. var iceCreamCXBThreshold = int.Parse(config.AppSettings.Settings["IceCream_CXB_Threshold"].Value);
  79. var com_ICChip = config.AppSettings.Settings["COM_ICChip"].Value;
  80. var baud_ICChip = config.AppSettings.Settings["BAUD_IChip"].Value;
  81. if (iceCreamCXBThreshold > 0)
  82. {
  83. //设置冰淇淋成型比
  84. MorkIStatus.GetInstance().CXB_Threshold = (byte)iceCreamCXBThreshold;
  85. }
  86. //咖啡机创建
  87. coffeeMachine = new CoffeeMachine(com_Coffee, (BaudRates)Enum.Parse(typeof(BaudRates), baud_Coffee));
  88. //单片机机创建
  89. icchipMachine = new ICChipMachine(com_ICChip, (BaudRates)Enum.Parse(typeof(BaudRates), baud_ICChip));
  90. //冰淇淋机创建
  91. iceCreamMachine = new IceCreamMachine(com_IceCream, (BaudRates)Enum.Parse(typeof(BaudRates), baud_IceCream));
  92. Main();
  93. ReadData();
  94. ThreadManage.GetInstance.StartLong(new Action(() =>
  95. {
  96. while (morkOrderPushes.Count > 0)
  97. {
  98. if (!LebaiHelper.GetInstance.GetInput())
  99. {
  100. while (enableFunny) { Thread.Sleep(10); }
  101. MessageLog.GetInstance.Show("当前非自嗨模式,允许开工");
  102. working = true;
  103. if (morkOrderPushes.TryDequeue(out MorkOrderPush order))
  104. {
  105. MessageLog.GetInstance.Show($"开始制作订单[{order.SortNum}]");
  106. //Thread.Sleep(5000);
  107. //SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK);
  108. //商品类型
  109. GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER;
  110. //子订单ID
  111. subOrderId = order.SuborderId;
  112. //遍历物料
  113. foreach (var item in order.GoodBatchings)
  114. {
  115. var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  116. if (res != null)
  117. {
  118. //验证商品是咖啡还是冰淇淋
  119. if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER)
  120. {
  121. //获取当前物料所属商品类型
  122. currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc);
  123. }
  124. //获取主料和容器位置
  125. switch (batchings[res.BatchingLoc].BatchingClass)
  126. {
  127. case BATCHING_CLASS.HOLDER:
  128. holderLoc = res.BatchingLoc;
  129. break;
  130. case BATCHING_CLASS.MAIN_MATERIAL:
  131. mainMaterialLoc = res.BatchingLoc;
  132. break;
  133. }
  134. }
  135. }
  136. //根据商品类型执行具体制作流程
  137. switch (currentGoodsType)
  138. {
  139. case GOODS_TYPE.COFFEE:
  140. DoCoffee();
  141. break;
  142. case GOODS_TYPE.ICECREAM:
  143. DoIceCream();
  144. break;
  145. case GOODS_TYPE.NEITHER:
  146. MessageLog.GetInstance.Show("未知的商品类型");
  147. break;
  148. }
  149. }
  150. working = false;
  151. lastRecvdOrder = DateTime.Now;
  152. }
  153. }
  154. Thread.Sleep(1000);
  155. }), "订单制作");
  156. }
  157. public void Main()
  158. {
  159. //咖啡机开启主线程
  160. coffeeMachine.Start();
  161. //单片机开启主线程
  162. icchipMachine.Start();
  163. //冰淇淋机开启主线程
  164. iceCreamMachine.Start();
  165. new ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
  166. //开始心跳刷新,根据咖啡机及冰淇淋机来判断
  167. ThreadManage.GetInstance.StartLong(new Action(() =>
  168. {
  169. GeneralConfig.Healthy =
  170. LebaiHelper.GetInstance.IsConnected &&
  171. MorkCStatus.GetInstance().CanDo &&
  172. ChipStatus.GetInstance().CanDo;
  173. //GeneralConfig.Healthy = true;
  174. Thread.Sleep(100);
  175. }), "MORK-IC心跳刷新");
  176. ThreadManage.GetInstance.Start(new Action(() =>
  177. {
  178. while (!LebaiHelper.GetInstance.IsConnected)
  179. {
  180. Thread.Sleep(10);
  181. }
  182. //LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_欢迎);
  183. }), "MORK-IC欢迎");
  184. }
  185. public void DataParse<T>(T order)
  186. {
  187. if (order is MorkOrderPush morkOrderPush)
  188. {
  189. morkOrderPushes.Enqueue(morkOrderPush);
  190. }
  191. }
  192. /// <summary>
  193. /// 验证当前是做咖啡还是做冰淇淋
  194. /// </summary>
  195. /// <param name="batchingLoc">物料位置</param>
  196. private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc)
  197. {
  198. if (batchings.ContainsKey(batchingLoc))
  199. return batchings[batchingLoc].GoodsType;
  200. return GOODS_TYPE.NEITHER;
  201. }
  202. private AutoResetEvent are = new AutoResetEvent(false);
  203. private void Wait(int value = 101)
  204. {
  205. while (!(lebai.Ok && lebai.Value == value))
  206. {
  207. Thread.Sleep(5);
  208. }
  209. }
  210. /// <summary>
  211. /// 做咖啡
  212. /// </summary>
  213. private void DoCoffee()
  214. {
  215. #region 且时且多入场设备程序
  216. int checkeNum = 0;
  217. are.Reset();
  218. LebaiHelper.GetInstance.SetValue(0);
  219. SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
  220. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_取咖啡杯);
  221. Wait();
  222. new TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
  223. Thread.Sleep(500);
  224. MessageLog.GetInstance.Show("咖啡杯取杯完成");
  225. LebaiHelper.GetInstance.SetValue(1);
  226. p:
  227. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_咖啡杯检测);
  228. Wait();
  229. LebaiHelper.GetInstance.SetValue(1);
  230. if (!LebaiHelper.GetInstance.GetTcpInput())
  231. {
  232. MessageLog.GetInstance.Show("执行二次取咖啡杯");
  233. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_二次取咖啡杯);
  234. Wait();
  235. new TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
  236. LebaiHelper.GetInstance.SetValue(1);
  237. goto p;
  238. }
  239. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_接咖啡);
  240. Wait();
  241. new MakeCoffeeEvent() { DrinkCode = (DrCoffeeDrinksCode)int.Parse(mainMaterialLoc) }.Publish(); //接咖啡控制
  242. are.WaitOne(1000 * 180);
  243. Thread.Sleep(3000);
  244. LebaiHelper.GetInstance.SetValue(1);
  245. while (LebaiHelper.GetInstance.GetInput())
  246. {
  247. Thread.Sleep(500);
  248. }
  249. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_放咖啡位置);
  250. Wait();
  251. LebaiHelper.GetInstance.SetValue(1);
  252. //订单状态改变:完成
  253. SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE);
  254. #endregion
  255. }
  256. /// <summary>
  257. /// 做冰淇淋
  258. /// </summary>
  259. private void DoIceCream()
  260. {
  261. if (LebaiHelper.GetInstance.GetInput(3))
  262. {
  263. MessageLog.GetInstance.Show("请擦拭冰淇淋机出口");
  264. return;
  265. }
  266. #region 且时且多入场设备程序
  267. int checkeNum = 0;
  268. are.Reset();
  269. LebaiHelper.GetInstance.SetValue(0);
  270. // SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
  271. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_取冰淇淋杯);
  272. Wait();
  273. new TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
  274. Thread.Sleep(500);
  275. MessageLog.GetInstance.Show("冰淇淋杯取杯完成");
  276. LebaiHelper.GetInstance.SetValue(1);
  277. p:
  278. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_冰淇淋杯检测);
  279. //Thread.Sleep(2000);
  280. //if (lebai.Value != 101)
  281. // LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_冰淇淋杯检测);
  282. Wait();
  283. LebaiHelper.GetInstance.SetValue(1);
  284. if (!LebaiHelper.GetInstance.GetTcpInput())
  285. {
  286. MessageLog.GetInstance.Show("执行二次取冰淇淋杯");
  287. //LebaiHelper.GetInstance.SetValue(1);
  288. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_二次取冰淇淋杯);
  289. //Thread.Sleep(2000);
  290. //if (lebai.Value != 101)
  291. // LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_二次取冰淇淋杯);
  292. new TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
  293. Wait();
  294. LebaiHelper.GetInstance.SetValue(1);
  295. goto p;
  296. }
  297. MessageLog.GetInstance.Show("冰淇淋杯检测完成");
  298. #region 通讯冰淇淋机
  299. //制冷模式
  300. new ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
  301. LebaiHelper.GetInstance.SetValue(0);
  302. SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
  303. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_接1号冰淇淋);
  304. Wait();
  305. bool doItResult = true;
  306. //出料
  307. new DischargeEvent().Publish(delegate (object[] args)
  308. {
  309. doItResult = (bool)args[0];
  310. });
  311. if (doItResult)
  312. {
  313. IceCreamCookCheck();
  314. }
  315. else
  316. {
  317. while (MorkIStatus.GetInstance().CXB <= 86)
  318. {
  319. }
  320. IceCreamCookCheck();
  321. }
  322. LebaiHelper.GetInstance.SetValue(1);
  323. #endregion
  324. while (LebaiHelper.GetInstance.GetInput())
  325. {
  326. Thread.Sleep(500);
  327. }
  328. LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_放冰淇淋位置);
  329. Wait();
  330. LebaiHelper.GetInstance.SetValue(1);
  331. //订单状态改变:完成
  332. SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE);
  333. #endregion
  334. }
  335. /// <summary>
  336. /// 冰淇淋制作
  337. /// </summary>
  338. public void IceCreamCookCheck()
  339. {
  340. int retry = 3;
  341. DateTime beginTime = DateTime.Now;
  342. while (!LebaiHelper.GetInstance.GetInput(3))
  343. {
  344. if (retry <= 0 && DateTime.Now.Subtract(beginTime).TotalSeconds >= 10)
  345. {
  346. MessageLog.GetInstance.Show("超时未出料,重试次数用尽");
  347. break;
  348. }
  349. if (DateTime.Now.Subtract(beginTime).TotalSeconds > 5)
  350. {
  351. MessageLog.GetInstance.Show("超时未出料,重新发送打料指令");
  352. new ModeSetEvent() { Mode = MORKI_MODE.打料 }.Publish();
  353. beginTime = DateTime.Now;
  354. retry--;
  355. }
  356. Thread.Sleep(10);
  357. }
  358. MessageLog.GetInstance.Show("开始等待6s");
  359. Thread.Sleep(5000);
  360. }
  361. private void CoffeEndCookHandle(IEvent @event, EventBus.EventCallBackHandle callBack)
  362. {
  363. are.Set();
  364. }
  365. public void ReadData()
  366. {
  367. ThreadManage.GetInstance.StartLong(new Action(() =>
  368. {
  369. lebai = LebaiHelper.GetInstance.GetValueAsync();
  370. LebaiHelper.GetInstance.GetRobotModeStatus();
  371. //LebaiHelper.GetInstance.GetInput();
  372. Thread.Sleep(100);
  373. }), "乐百机器人数据读取", true);
  374. }
  375. public void SimOrder<T>(T simOrder)
  376. {
  377. }
  378. /// <summary>
  379. /// IOT 广播消息命令
  380. /// </summary>
  381. public void IotBroadcast<T>(T broadcast)
  382. {
  383. if (broadcast != null && broadcast is IOTCommandModel iOTCommand)
  384. {
  385. switch (iOTCommand.CommandName)
  386. {
  387. case 0://控制类
  388. if (iOTCommand.CommandValue != null)
  389. {
  390. if (iOTCommand.CommandValue.ContainsKey("SimOrder"))
  391. {
  392. SimOrder(new SimOrderData { NoodleLoc = 1, BowlLoc = 10 });
  393. }
  394. }
  395. break;
  396. case 1://设置属性
  397. break;
  398. case 2://通知消息
  399. break;
  400. default:
  401. break;
  402. }
  403. }
  404. }
  405. }
  406. }