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.
 
 

389 lines
13 KiB

  1. using BPA.Message;
  2. using HBLConsole.Communication;
  3. using HBLConsole.Factory;
  4. using HBLConsole.Interface;
  5. using HBLConsole.Model;
  6. using HBLConsole.Service;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using BPA.Message.Enum;
  14. namespace HBLConsole.Business.Devices
  15. {
  16. public class MORKS : IBusiness
  17. {
  18. private volatile static MORKS _Instance;
  19. public static MORKS GetInstance => _Instance ?? (_Instance = new MORKS());
  20. private MORKS() { }
  21. GVL.MORKS mORKS = new GVL.MORKS();
  22. /// <summary>
  23. /// 写入配方数据到 PLC
  24. /// </summary>
  25. private void WriteRecipeBoms()
  26. {
  27. List<ushort> recipeBoms = new List<ushort>();
  28. foreach (var item in Json<BatchingInfoPar>.GetInstance.Base.recipeBoms.RecipeIds)
  29. {
  30. foreach (var rec in item.Recipes)
  31. {
  32. recipeBoms.Add((ushort)rec);
  33. }
  34. }
  35. if (ModbusTcpHelper.GetInstance.Write(1100, WriteType.HoldingRegisters, recipeBoms.ToArray()))
  36. {
  37. MessageLog.GetInstance.Show("成功写入配方数据");
  38. }
  39. }
  40. public void Init()
  41. {
  42. //Modbus TCP连接成功
  43. ActionManagerment.GetInstance.Register(new Action(() =>
  44. {
  45. WriteRecipeBoms();
  46. ReadPlcData();
  47. DataParse();
  48. Main();
  49. }), "ConnectOk");
  50. //获取物料信息
  51. SimpleFactory.GetInstance.GetBatchingInfo();
  52. //Modbus Tcp 连接
  53. ModbusTcpHelper.GetInstance.ModbusTcpConnect("127.0.0.1");
  54. }
  55. /// <summary>
  56. /// 数据读取
  57. /// </summary>
  58. private void ReadPlcData()
  59. {
  60. ThreadManagerment.GetInstance.StartLong(new Action(() =>
  61. {
  62. object result;
  63. result = ModbusTcpHelper.GetInstance.Read(1120, ReadType.Coils, 16);
  64. if (result != null)
  65. {
  66. if (result is bool[] bools)
  67. {
  68. if (bools.Length == 16)
  69. {
  70. mORKS.InitComplete = bools[0];
  71. mORKS.TakeBowlIdle = bools[1];
  72. mORKS.TemperatureReached = bools[2];
  73. mORKS.AllowFallNoodle = bools[3];
  74. mORKS.RbTakeNoodleComplete = bools[4];
  75. mORKS.RbFallNoodleComplete = bools[5];
  76. mORKS.RbOutMealComplete = bools[6];
  77. mORKS.RobotIdle = bools[7];
  78. mORKS.TakeMealDetect = bools[8];
  79. mORKS.MissingBowl = bools[9];
  80. mORKS.TurntableLowerLimit = bools[11];
  81. }
  82. }
  83. }
  84. //读取煮面栏状态
  85. result = ModbusTcpHelper.GetInstance.Read(1136, ReadType.Coils, 6);
  86. if (result != null)
  87. {
  88. if (result is bool[] bools)
  89. {
  90. if (bools.Length == 6)
  91. {
  92. for (int i = 0; i < 6; i++)
  93. {
  94. mORKS.NoodleCookerStatus[i] = bools[i];
  95. }
  96. }
  97. }
  98. }
  99. //读取煮面炉完成信号
  100. result = ModbusTcpHelper.GetInstance.Read(1144, ReadType.Coils, 6);
  101. if (result != null)
  102. {
  103. if (result is bool[] bools)
  104. {
  105. if (bools.Length == 6)
  106. {
  107. for (int i = 0; i < 6; i++)
  108. {
  109. mORKS.CookNoodlesComplete[i] = bools[i];
  110. }
  111. }
  112. }
  113. }
  114. Thread.Sleep(500);
  115. }), "Read PLC Data");
  116. }
  117. /// <summary>
  118. /// 数据解析
  119. /// </summary>
  120. private void DataParse()
  121. {
  122. ActionManagerment.GetInstance.Register(new Action<object>((o) =>
  123. {
  124. if (o is MorkOrderPush morkOrderPush)
  125. {
  126. foreach (var item in morkOrderPush.GoodBatchings)
  127. {
  128. var res = Json<BatchingInfoPar>.GetInstance.Base.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  129. if (res != null)
  130. {
  131. if (ushort.TryParse(res.BatchingLoc, out ushort loc))
  132. {
  133. if (loc >= 1 && loc <= 5)
  134. {
  135. mORKS.RBTakeNoodleTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
  136. }
  137. else if (loc >= 10 && loc <= 11)
  138. {
  139. mORKS.TakeBowlTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, RecipeNumber = (ushort)morkOrderPush.RecipeId });
  140. }
  141. }
  142. }
  143. }
  144. }
  145. }), "MorksParse");
  146. }
  147. bool AllowRun = false;
  148. string TakeBowlId = string.Empty;//取碗订单ID
  149. string IngredientsCompleteId = string.Empty;//配料完成订单ID
  150. string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, };
  151. bool RobotTaskInterlock = false;//机器人任务互锁信号
  152. string OutMealId = string.Empty;
  153. private void Main()
  154. {
  155. ThreadManagerment.GetInstance.StartLong(new Action(() =>
  156. {
  157. AllowRun = mORKS.InitComplete && mORKS.TemperatureReached;
  158. if (AllowRun)
  159. {
  160. TakeBowlTask();
  161. TakeNoodleTask();
  162. }
  163. OutNoodleTask();
  164. SingleDetect();
  165. Thread.Sleep(1);
  166. }), "Main Task");
  167. }
  168. /// <summary>
  169. /// 取碗控制
  170. /// </summary>
  171. private void TakeBowlTask()
  172. {
  173. //取碗控制
  174. if (RTrig.GetInstance("TakeBowl").Start(mORKS.TakeBowlIdle && mORKS.TakeBowlTask.Count > 0))
  175. {
  176. if (mORKS.TakeBowlTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo))
  177. {
  178. TakeBowlId = orderLocInfo.SuborderId;
  179. TakeBowlControl(orderLocInfo.Loc);
  180. SetRecipeNumber(orderLocInfo.RecipeNumber);
  181. SimpleFactory.GetInstance.OrderChanged(TakeBowlId, ORDER_STATUS.COOKING);
  182. MessageLog.GetInstance.Show($"订单【{TakeBowlId}】,位置:[{orderLocInfo.Loc}]");
  183. }
  184. }
  185. }
  186. /// <summary>
  187. /// 取面任务
  188. /// </summary>
  189. private void TakeNoodleTask()
  190. {
  191. //取面控制
  192. if (!RobotTaskInterlock)
  193. {
  194. if (RTrig.GetInstance("TakeNoodle").Start(mORKS.RobotIdle && mORKS.RBTakeNoodleTask.Count > 0))
  195. {
  196. if (mORKS.RBTakeNoodleTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo))
  197. {
  198. //设置转台位置
  199. SetTurntableLoc(orderLocInfo.Loc);
  200. //设置倒面位置
  201. int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置
  202. if (loc >= 0 && loc <= 5)
  203. {
  204. CookNodelId[loc] = orderLocInfo.SuborderId;
  205. SetFallNoodleLoc((ushort)(loc + 1));
  206. }
  207. //机器人开始取面
  208. RobotTakeNoodle();
  209. SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
  210. MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,转台:[{orderLocInfo.Loc}],煮面栏:[{loc}]");
  211. }
  212. }
  213. }
  214. }
  215. /// <summary>
  216. /// 出餐控制
  217. /// </summary>
  218. private void OutNoodleTask()
  219. {
  220. if (RobotTaskInterlock)
  221. {
  222. if (mORKS.AllowFallNoodle && mORKS.RobotIdle && !mORKS.TakeMealDetect)
  223. {
  224. int loc = Array.FindIndex(CookNodelId, p => p == IngredientsCompleteId);
  225. if (loc >= 0 && loc <= 5)
  226. {
  227. if (mORKS.CookNoodlesComplete[loc])
  228. {
  229. SetTakeNoodleLoc((ushort)(loc + 1));
  230. RobotOutMeal();
  231. CookNoodleStatusReset((ushort)(loc + 1));
  232. OutMealId = IngredientsCompleteId;
  233. IngredientsCompleteId = string.Empty;
  234. CookNodelId[loc] = string.Empty;
  235. }
  236. }
  237. }
  238. }
  239. }
  240. /// <summary>
  241. /// 信号检测
  242. /// </summary>
  243. private void SingleDetect()
  244. {
  245. if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle))
  246. {
  247. IngredientsCompleteId = TakeBowlId;
  248. TakeBowlId = string.Empty;
  249. }
  250. if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete))
  251. {
  252. SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_COOK);
  253. MessageLog.GetInstance.Show($"订单【{OutMealId}】制作完成");
  254. }
  255. if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2))
  256. {
  257. SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_TAKE);
  258. MessageLog.GetInstance.Show($"订单【{OutMealId}】取餐完成");
  259. OutMealId = string.Empty;
  260. }
  261. RobotTaskInterlock = mORKS.RobotIdle && mORKS.AllowFallNoodle && mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count >= 3;
  262. }
  263. /// <summary>
  264. /// 取面完成复位
  265. /// </summary>
  266. private void TakeNoodleCompleteReset()
  267. {
  268. ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false);
  269. }
  270. /// <summary>
  271. /// 指定煮面口状态复位
  272. /// </summary>
  273. /// <param name="num"></param>
  274. private void CookNoodleStatusReset(int num)
  275. {
  276. if (num >= 1 && num <= 6)
  277. {
  278. ushort addRess = (ushort)(1136 + num - 1);
  279. ModbusTcpHelper.GetInstance.Write(1136, WriteType.Coils, false);
  280. }
  281. }
  282. /// <summary>
  283. /// 写配方编号
  284. /// </summary>
  285. /// <param name="num"></param>
  286. private void SetRecipeNumber(ushort num)
  287. {
  288. ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num);
  289. }
  290. /// <summary>
  291. /// 设置转台位置
  292. /// </summary>
  293. /// <param name="loc"></param>
  294. private void SetTurntableLoc(ushort loc)
  295. {
  296. ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc);
  297. }
  298. /// <summary>
  299. /// 设置倒面位置
  300. /// </summary>
  301. /// <param name="loc"></param>
  302. private void SetFallNoodleLoc(ushort loc)
  303. {
  304. ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc);
  305. }
  306. /// <summary>
  307. /// 设置取面位置
  308. /// </summary>
  309. /// <param name="loc"></param>
  310. private void SetTakeNoodleLoc(ushort loc)
  311. {
  312. ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc);
  313. }
  314. /// <summary>
  315. /// 取碗控制
  316. /// </summary>
  317. /// <param name="loc"></param>
  318. private void TakeBowlControl(ushort loc)
  319. {
  320. if (loc == 10)
  321. {
  322. ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true);
  323. }
  324. else if (loc == 11)
  325. {
  326. ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true);
  327. }
  328. }
  329. /// <summary>
  330. /// 机器人取面
  331. /// </summary>
  332. private void RobotTakeNoodle()
  333. {
  334. ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true);
  335. }
  336. /// <summary>
  337. /// 机器人取餐
  338. /// </summary>
  339. private void RobotOutMeal()
  340. {
  341. ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true);
  342. }
  343. }
  344. }