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.
 
 

432 lines
16 KiB

  1. using System;
  2. using HBLConsole.Interface;
  3. using HBLConsole.Service;
  4. using HBLConsole.Communication;
  5. using BPA.Message;
  6. using HBLConsole.Model;
  7. using System.Linq;
  8. using System.Threading;
  9. using HBLConsole.Factory;
  10. using BPA.Message.Enum;
  11. using BPA.Message.IOT;
  12. using System.Collections.Generic;
  13. namespace HBLConsole.MORKD
  14. {
  15. public class Control_MORKD : IControl
  16. {
  17. #region 单例模式
  18. private static Control_MORKD _instance;
  19. public static Control_MORKD Instance
  20. {
  21. get
  22. {
  23. if (_instance == null)
  24. _instance = new Control_MORKD();
  25. return _instance;
  26. }
  27. }
  28. public Control_MORKD()
  29. {
  30. }
  31. #endregion
  32. public GVL_MORKD mORKD { get; set; } = new GVL_MORKD();
  33. public void ConnectOk()
  34. {
  35. Main();
  36. ReadData();
  37. }
  38. public object GetT()
  39. {
  40. return mORKD;
  41. }
  42. public void DataParse<T>(T order)
  43. {
  44. if (order is MorkOrderPush morkOrderPush)
  45. {
  46. foreach (var item in morkOrderPush.GoodBatchings)
  47. {
  48. var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  49. if (res != null)
  50. {
  51. if (ushort.TryParse(res.BatchingLoc, out ushort loc))
  52. {
  53. if (loc >= 1 && loc <= 5)
  54. {
  55. mORKD.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, BatchingId = res.BatchingId });
  56. }
  57. else if (loc >= 6 && loc <= 10)
  58. {
  59. mORKD.TakeSoupTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
  60. }
  61. else if (loc >= 11 && loc <= 12)
  62. {
  63. mORKD.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
  64. }
  65. }
  66. }
  67. }
  68. }
  69. }
  70. public void Init()
  71. {
  72. ActionOperate.GetInstance.Register(new Action(() => { mORKD.InitControl(); }), "InitCommand");
  73. }
  74. public void Main()
  75. {
  76. ThreadOperate.GetInstance.StartLong(new Action(() =>
  77. {
  78. mORKD.AllowRun = mORKD.InitComplete && !mORKD.TemperatureReached;
  79. TakeBowlTask();
  80. TakeNoodleTask();
  81. OutNoodleTask();
  82. SingleDetect();
  83. TurntableControl();
  84. OutSoupTask();
  85. TakeSoupTask();
  86. Thread.Sleep(100);
  87. }), "MainTask");
  88. }
  89. public void ReadData()
  90. {
  91. ModbusTcpHelper.GetInstance.Readbool(1120, 29, new Action<bool[]>((bools) =>
  92. {
  93. mORKD.InitComplete = bools[0];
  94. mORKD.TurntableInPlace = bools[1];
  95. mORKD.RBTakeNoodleComplete = bools[2];
  96. for (int i = 0; i < 2; i++)
  97. {
  98. mORKD.AxisIdle[i] = bools[3 + i];
  99. mORKD.AxisAllowInvertedNoodle[i] = bools[5 + i];
  100. mORKD.AxisAllowInvertedSoup[i] = bools[7 + i];
  101. mORKD.SoupHeatComplete[i] = bools[9 + i];
  102. mORKD.BreakMechanismIdle[i] = bools[25 + i];
  103. }
  104. for (int i = 0; i < 6; i++)
  105. {
  106. mORKD.CookNoodleBasketIdle[i] = bools[11 + i];
  107. mORKD.CookNoodleComplete[i] = bools[17 + i];
  108. }
  109. mORKD.TakeNoodleRobotIdle = bools[23];
  110. mORKD.TakeSoupRobotIdle = bools[24];
  111. mORKD.TakeSoupComplete = bools[27];
  112. mORKD.PutNoodleTakeMealComplete = bools[28];
  113. }));
  114. ModbusTcpHelper.GetInstance.Readbool(1200, 11, new Action<bool[]>((bools) =>
  115. {
  116. mORKD.TurntableLowerLimit = bools[0];
  117. mORKD.TurntableUpLimit = bools[1];
  118. for (int i = 0; i < 5; i++)
  119. {
  120. mORKD.SoupMaterialShortage[i] = bools[2 + i];
  121. }
  122. for (int i = 0; i < 3; i++)
  123. {
  124. mORKD.OutMealDetect[i] = bools[7 + i];
  125. }
  126. mORKD.TemperatureReached = bools[10];
  127. }));
  128. }
  129. public void SimOrder<T>(T simOrder)
  130. {
  131. if (simOrder != null)
  132. {
  133. if (simOrder is List<ushort> locs)
  134. {
  135. string subId = Guid.NewGuid().ToString();
  136. foreach (var item in locs)
  137. {
  138. if (item >= 1 && item <= 5)
  139. {
  140. mORKD.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = item, SuborderId = subId });
  141. MessageLog.GetInstance.Show($"添加订单:面条位置【{item}】");
  142. }
  143. if (item >= 6 && item <= 10)
  144. {
  145. mORKD.TakeSoupTask.Enqueue(new OrderLocInfo() { Loc = item, SuborderId = subId });
  146. MessageLog.GetInstance.Show($"添加订单:浇头位置【{item}】");
  147. }
  148. if (item >= 11 && item <= 12)
  149. {
  150. mORKD.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = item, SuborderId = subId });
  151. MessageLog.GetInstance.Show($"添加订单:碗位置【{item}】");
  152. }
  153. }
  154. }
  155. }
  156. }
  157. /// <summary>
  158. /// IOT 广播消息命令
  159. /// </summary>
  160. public void IotBroadcast<T>(T broadcast)
  161. {
  162. if (broadcast != null && broadcast is IOTCommandModel iOTCommand)
  163. {
  164. switch (iOTCommand.CommandName)
  165. {
  166. case 0://控制类
  167. if (iOTCommand.CommandValue != null)
  168. {
  169. if (iOTCommand.CommandValue.ContainsKey("SimOrder"))
  170. {
  171. SimOrder(new SimOrderData { NoodleLoc = 1, BowlLoc = 10 });
  172. }
  173. }
  174. break;
  175. case 1://设置属性
  176. break;
  177. case 2://通知消息
  178. break;
  179. default:
  180. break;
  181. }
  182. }
  183. }
  184. /// <summary>
  185. /// 取碗控制
  186. /// </summary>
  187. private void TakeBowlTask()
  188. {
  189. mORKD.AxisIdleIndex = mORKD.AxisIdle.GetIndex(true);
  190. mORKD.AxisIdleLockIndex = mORKD.AxisIdleLock.GetIndex(false);
  191. if (mORKD.AxisIdleLockIndex == mORKD.AxisIdleIndex)
  192. {
  193. if (mORKD.AxisIdleIndex >= 0 && mORKD.AxisIdleIndex <= 1)
  194. {
  195. if (mORKD.AllowRun && mORKD.TakeBowlTask.Count > 0)
  196. {
  197. if (mORKD.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo))
  198. {
  199. mORKD.AxisAllowInvertedNoodleID[mORKD.AxisIdleIndex] = orderLocInfo.SuborderId;
  200. mORKD.DropBowlStart((ushort)mORKD.AxisIdleIndex, orderLocInfo.Loc);
  201. mORKD.AxisIdleLock[mORKD.AxisIdleLockIndex] = true;
  202. MessageLog.GetInstance.Show($"执行取碗控制,位置:[{orderLocInfo.Loc}]");
  203. }
  204. }
  205. }
  206. }
  207. }
  208. /// <summary>
  209. /// 转台控制
  210. /// </summary>
  211. private void TurntableControl()
  212. {
  213. if (mORKD.InitComplete && !mORKD.TurntableInterlock && !mORKD.AllowTakeNoodle && mORKD.RBTakeNoodleTask.Count > 0)
  214. {
  215. var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKD.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
  216. if (result != null)
  217. {
  218. foreach (var item in result)
  219. {
  220. if (ushort.TryParse(item.BatchingLoc, out ushort loc))
  221. {
  222. if (!mORKD.TurntableLocLists.Contains(loc))
  223. {
  224. mORKD.TurntableStart(loc);
  225. return;
  226. }
  227. }
  228. }
  229. }
  230. }
  231. //转台到位检测
  232. if (RTrig.GetInstance("TurntableInPlace").Start(mORKD.TurntableInPlace))
  233. {
  234. if (mORKD.TurntableInterlock)
  235. {
  236. if (mORKD.TurntableLowerLimit)
  237. {
  238. mORKD.TurntableLocLists.Clear();
  239. mORKD.AllowTakeNoodle = true;
  240. }
  241. else
  242. {
  243. mORKD.TurntableInterlock = false;
  244. mORKD.AllowTakeNoodle = false;
  245. }
  246. }
  247. }
  248. }
  249. /// <summary>
  250. /// 取面任务
  251. /// </summary>
  252. private void TakeNoodleTask()
  253. {
  254. //取面控制
  255. if (mORKD.AllowRun && mORKD.TakeNoodleRobotIdle && !mORKD.RobotTaskInterlock && mORKD.AllowTakeNoodle)
  256. {
  257. if (mORKD.TurntableInPlace && !mORKD.OutNoodleing && mORKD.RBTakeNoodleTask.Count > 0)
  258. {
  259. int loc = mORKD.CookNoodleBasketIdle.GetIndex(false);//查找煮面炉空闲位置
  260. if (loc >= 0 && loc <= 5)
  261. {
  262. if (mORKD.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo))
  263. {
  264. mORKD.RBTakeNoodleStart((ushort)(loc + 1), orderLocInfo.Loc);
  265. mORKD.CookNodelId[loc] = orderLocInfo.SuborderId;
  266. SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  267. MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,煮面栏:[{loc + 1}]");
  268. mORKD.TakeNoodleInterlock = true;
  269. }
  270. }
  271. }
  272. }
  273. //机器人取面完成信号检测
  274. if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKD.RBTakeNoodleComplete))
  275. {
  276. mORKD.TakeNoodleInterlock = false;
  277. mORKD.AllowTakeNoodle = false;
  278. MessageLog.GetInstance.Show("转台取面完成");
  279. mORKD.TakeNoodleCompleteReset();
  280. }
  281. }
  282. /// <summary>
  283. /// 出餐控制
  284. /// </summary>
  285. private void OutNoodleTask()
  286. {
  287. for (ushort i = 0; i < 6; i++)
  288. {
  289. if (RTrig.GetInstance($"CookNoodleCompleteTask{i}").Start(mORKD.CookNoodleComplete[i]))
  290. {
  291. mORKD.CookNoodleCompleteTask.Enqueue(i);
  292. }
  293. }
  294. if (mORKD.RobotTaskInterlock && !mORKD.TakeNoodleInterlock && mORKD.TakeNoodleRobotIdle)
  295. {
  296. if (mORKD.CookNoodleCompleteTask.Count > 0)
  297. {
  298. string id = mORKD.CookNodelId[mORKD.CookNoodleCompleteTask.ElementAt(0)];
  299. int index = mORKD.AxisAllowInvertedNoodleID.GetIndex(id);
  300. if (index >= 0 && index <= 1)
  301. {
  302. if (mORKD.AxisAllowInvertedNoodle[index])
  303. {
  304. if (mORKD.CookNoodleCompleteTask.TryDequeue(out ushort loc))
  305. {
  306. mORKD.OutNoodleing = true;
  307. mORKD.RBOutNoodleStart((ushort)(loc + 1), (ushort)(index + 1));
  308. mORKD.AxisIdleLock[index] = false;
  309. mORKD.AxisAllowInvertedSoupID[index] = mORKD.AxisAllowInvertedNoodleID[index];
  310. mORKD.AxisAllowInvertedNoodleID[index] = string.Empty;
  311. MessageLog.GetInstance.Show($"从{loc + 1}号位置取面");
  312. MessageLog.GetInstance.Show($"倒入{index + 1}号碗位置");
  313. }
  314. }
  315. }
  316. }
  317. }
  318. int mlCount = mORKD.CookNoodleBasketIdle.Where(p => p == true).ToList().Count;
  319. mORKD.RobotTaskInterlock = mORKD.CookNoodleCompleteTask.Count > 0 && (mlCount >= 2 || mORKD.RBTakeNoodleTask.Count == 0);
  320. }
  321. /// <summary>
  322. /// 取浇头控制
  323. /// </summary>
  324. private void TakeSoupTask()
  325. {
  326. int index = mORKD.BreakMechanismIdle.GetIndex(true);
  327. if (index >= 0 && index <= 1)
  328. {
  329. if (mORKD.TakeSoupTask.Count > 0 && !mORKD.AllowTakeSoup && mORKD.TakeSoupRobotIdle && mORKD.AllowRun)
  330. {
  331. if (mORKD.TakeSoupTask.TryDequeue(out OrderLocInfo orderLocInfo))
  332. {
  333. mORKD.SoupHeatCompleteID[index] = orderLocInfo.SuborderId;
  334. mORKD.RBTakeSoupStart(orderLocInfo.Loc, (ushort)(index + 1));
  335. SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  336. }
  337. }
  338. }
  339. if (RTrig.GetInstance("TakeSoupComplete").Start(mORKD.TakeSoupComplete))
  340. {
  341. mORKD.AllowTakeSoup = false;
  342. MessageLog.GetInstance.Show("取浇头完成");
  343. mORKD.TakeSoupCompleteReset();
  344. }
  345. }
  346. /// <summary>
  347. /// 浇头加热完成出浇头控制
  348. /// </summary>
  349. private void OutSoupTask()
  350. {
  351. if (!mORKD.AllowTakeSoup && !mORKD.AllowPutSoup && mORKD.TakeSoupRobotIdle)
  352. {
  353. mORKD.PutNoodleLoc = mORKD.OutMealDetect.GetIndex(false);
  354. if (mORKD.PutNoodleLoc >= 0 && mORKD.PutNoodleLoc <= 2)
  355. {
  356. for (int i = 0; i < 2; i++)
  357. {
  358. if (mORKD.SoupHeatComplete[i] && mORKD.SoupHeatCompleteID[i].Length > 0)
  359. {
  360. for (int m = 0; m < 2; m++)
  361. {
  362. if (mORKD.AxisAllowInvertedSoup[m] && mORKD.AxisAllowInvertedSoupID[m].Length > 0)
  363. {
  364. if (mORKD.SoupHeatCompleteID[i] == mORKD.AxisAllowInvertedSoupID[m])
  365. {
  366. mORKD.HeatCompleteTakeSoupStart((ushort)(i + 1), (ushort)(m + 1), (ushort)(mORKD.PutNoodleLoc + 1));
  367. mORKD.OutMealId[mORKD.PutNoodleLoc] = mORKD.AxisAllowInvertedSoupID[m];
  368. mORKD.AxisAllowInvertedSoupID[m] = string.Empty;
  369. mORKD.SoupHeatCompleteID[i] = string.Empty;
  370. }
  371. }
  372. }
  373. }
  374. }
  375. }
  376. }
  377. if (RTrig.GetInstance("PutNoodleTakeMealComplete").Start(mORKD.PutNoodleTakeMealComplete))
  378. {
  379. mORKD.AllowPutSoup = false;
  380. SimpleFactory.GetInstance.OrderChanged(mORKD.OutMealId[mORKD.PutNoodleLoc], ORDER_STATUS.COMPLETED_COOK);
  381. mORKD.PutNoodleTakeMealCompleteReset();
  382. }
  383. }
  384. /// <summary>
  385. /// 信号检测
  386. /// </summary>
  387. private void SingleDetect()
  388. {
  389. }
  390. }
  391. }