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.
 
 

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