终端一体化运控平台
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.
 
 
 

487 rivejä
21 KiB

  1. using BPA.Helper;
  2. using BPA.Message.Enum;
  3. using BPA.Models;
  4. using BPASmartClient.Device;
  5. using BPASmartClient.Modbus;
  6. using BPASmartClient.Model;
  7. using BPASmartClient.Model.PLC;
  8. using BPASmartClient.Model.订单;
  9. using BPASmartClient.Model.调酒机;
  10. using BPASmartClient.MorkMW.Model;
  11. using Newtonsoft.Json;
  12. using Org.BouncyCastle.Bcpg.OpenPgp;
  13. using System;
  14. using System.Collections.Concurrent;
  15. using System.Collections.Generic;
  16. using System.Collections.ObjectModel;
  17. using System.Linq;
  18. using System.Net.Http.Json;
  19. using System.Reflection;
  20. using System.Threading;
  21. using System.Windows.Documents;
  22. using static BPA.Helper.EventBus;
  23. namespace BPASmartClient.MorkMW
  24. {
  25. public class Control_MorkMW : BaseDevice
  26. {
  27. int id = 0;
  28. ModbusTcp modbus;
  29. public override DeviceClientType DeviceType => DeviceClientType.MORKMW;
  30. GVL_MorkMW morkMW = new GVL_MorkMW();
  31. public override void DoMain()
  32. {
  33. Json<KeepDataBase>.Read();
  34. VaribleMonitorDis();
  35. ConnectKlpRobot("192.168.0.100", 8001);
  36. ServerInit();
  37. DataParse();
  38. TaskManage.GetInstance.StartLong(new Action(() => { VariableMonitor(); Thread.Sleep(5); }), "机器人变量状态监控线程", true);
  39. }
  40. private void VaribleMonitorDis()
  41. {
  42. PropertyInfo[] pros = morkMW.GetType().GetProperties();
  43. foreach (var item in pros)
  44. {
  45. var res = item.GetCustomAttribute<VariblesAttribute>();
  46. if (res != null)
  47. {
  48. GVL_MorkMW.varibleInfos.Add(new VaribleModel { Id = id + 1, VaribleName = res.VarName, RobotAddress = res.RobotAddress, ModbusAddress = res.ModbusTcpAddress, Notes = res.Notes });
  49. id++;
  50. }
  51. }
  52. }
  53. private void ServerInit()
  54. {
  55. //配方数据信息
  56. EventBus.GetInstance().Subscribe<MorkMWGoodsEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  57. {
  58. if (@event == null) return;
  59. if (@event is MorkMWGoodsEvent recipe)
  60. {
  61. listMorkMWGoods = recipe.morkMWPushMessage?.MorkMWGoods;
  62. DeviceProcessLogShow($"接收到调酒机【{listMorkMWGoods?.Count}】个商品配方数据");
  63. }
  64. });
  65. }
  66. public override void MainTask()
  67. {
  68. if (Json<KeepDataBase>.Data.IsVerify)
  69. IsHealth = modbus.Connected;
  70. else
  71. IsHealth = true;//心跳上报
  72. ToGetWink();
  73. ToMixWink();
  74. ToPourWink();
  75. SignalDetect();
  76. }
  77. /// <summary>
  78. /// 接酒过程
  79. /// </summary>
  80. public void ToGetWink()
  81. {
  82. if (!GVL_MorkMW.AllowLocalSimOrder)
  83. {
  84. if (morkMW.RobotIdle && orderLocInfos.Count > 0 && !morkMW.TaskLock && !morkMW.PourWinkComplete && morkMW.CupSignal && modbus.Connected)
  85. {
  86. DeviceProcessLogShow("订单开始制作");
  87. morkMW.TaskLock = true;
  88. if (orderLocInfos.TryDequeue(out BPASmartClient.MorkMW.Model.OrderLocInfo res))
  89. {
  90. morkMW.CurrentSuborderId = res.SuborderId;
  91. OrderChange(res.SuborderId, ORDER_STATUS.COOKING);
  92. foreach (var item in res.mixWink)
  93. {
  94. switch (item.Loc)
  95. {
  96. // case 7: ToMixWink(); break;
  97. case 1: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  98. case 2: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  99. case 3: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  100. case 4: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  101. case 5: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  102. case 6: ToSpecifiedLocTakeWink(item.Loc, item.Qty); break;
  103. }
  104. switch (item.Loc)
  105. {
  106. //case 7: while (!morkMW.MixWinkComplte) { Thread.Sleep(5); } break;
  107. case 1: while (!morkMW.TakeWinkOneComplete) { Thread.Sleep(5); } break;
  108. case 2: while (!morkMW.TakeWinkTwoComplete) { Thread.Sleep(5); } break;
  109. case 3: while (!morkMW.TakeWinkThreeComplete) { Thread.Sleep(5); } break;
  110. case 4: while (!morkMW.TakeWinkFourComplete) { Thread.Sleep(5); } break;
  111. case 5: while (!morkMW.TakeWinkFiveComplete) { Thread.Sleep(5); } break;
  112. case 6: while (!morkMW.TakeWinkSixComplete) { Thread.Sleep(5); } break;
  113. }
  114. }
  115. morkMW.AllowMixWink = true;//接酒完成,允许调酒
  116. // morkMW.AllowPourWink = true;//调酒完成,允许倒酒
  117. }
  118. }
  119. }
  120. else
  121. {
  122. if (morkMW.RobotIdle && simOrderLocInfos.Count > 0 && !morkMW.TaskLock && !morkMW.PourWinkComplete && morkMW.CupSignal)
  123. {
  124. DeviceProcessLogShow("订单开始制作");
  125. morkMW.TaskLock = true;
  126. if (simOrderLocInfos.TryDequeue(out SimOrderLocInfo res))
  127. {
  128. foreach (var item in res.mixWink)
  129. {
  130. switch (item.Loc)
  131. {
  132. // case 7: ToMixWink(); break;
  133. case 1: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  134. case 2: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  135. case 3: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  136. case 4: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  137. case 5: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  138. case 6: ToSpecifiedLocTakeWink(item.Loc, item.Time); break;
  139. }
  140. switch (item.Loc)
  141. {
  142. //case 7: while (!morkMW.MixWinkComplte) { Thread.Sleep(5); } break;
  143. case 1: while (!morkMW.TakeWinkOneComplete) { Thread.Sleep(5); } break;
  144. case 2: while (!morkMW.TakeWinkTwoComplete) { Thread.Sleep(5); } break;
  145. case 3: while (!morkMW.TakeWinkThreeComplete) { Thread.Sleep(5); } break;
  146. case 4: while (!morkMW.TakeWinkFourComplete) { Thread.Sleep(5); } break;
  147. case 5: while (!morkMW.TakeWinkFiveComplete) { Thread.Sleep(5); } break;
  148. case 6: while (!morkMW.TakeWinkSixComplete) { Thread.Sleep(5); } break;
  149. }
  150. }
  151. DeviceProcessLogShow($"所有位置接酒完成");
  152. morkMW.AllowMixWink = true;//接酒完成,允许调酒
  153. // morkMW.AllowPourWink = true;//调酒完成,允许倒酒
  154. }
  155. }
  156. }
  157. }
  158. /// <summary>
  159. /// 调酒过程
  160. /// </summary>
  161. public void ToMixWink()
  162. {
  163. // modbus.WriteSingleRegister(0000, 7);//机器人调酒
  164. if (morkMW.AllowMixWink && modbus.Connected)
  165. {
  166. DeviceProcessLogShow("开始调酒");
  167. modbus.WriteSingleRegister(0000, 7);//机器人调酒
  168. morkMW.AllowMixWink = false;
  169. }
  170. }
  171. /// <summary>
  172. /// 去对应位置接酒
  173. /// </summary>
  174. /// <param name="loc"></param>
  175. /// <param name="time"></param>
  176. public void ToSpecifiedLocTakeWink(int loc, int time)
  177. {
  178. //发送接酒信号
  179. switch (loc)
  180. {
  181. case 1: modbus.WriteSingleRegister(0000, 1); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  182. case 2: modbus.WriteSingleRegister(0000, 2); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  183. case 3: modbus.WriteSingleRegister(0000, 3); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  184. case 4: modbus.WriteSingleRegister(0000, 4); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  185. case 5: modbus.WriteSingleRegister(0000, 5); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  186. case 6: modbus.WriteSingleRegister(0000, 6); DeviceProcessLogShow($"开始接【{loc}】号位置原酒"); break;
  187. }
  188. //等待机器人到达接酒位置
  189. switch (loc)
  190. {
  191. case 1: while (!morkMW.ArriveWinkOneLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  192. case 2: while (!morkMW.ArriveWinkTwoLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  193. case 3: while (!morkMW.ArriveWinkThreeLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  194. case 4: while (!morkMW.ArriveWinkFourLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  195. case 5: while (!morkMW.ArriveWinkFiveLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  196. case 6: while (!morkMW.ArriveWinkSixLoc) { Thread.Sleep(5); } DeviceProcessLogShow($"机械臂到达【{loc}】号接酒位置"); break;
  197. }
  198. Thread.Sleep(time * 1000);//接酒等待时间
  199. //发送接酒完成信号
  200. switch (loc)
  201. {
  202. case 1: modbus.WriteSingleCoil(4596, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  203. case 2: modbus.WriteSingleCoil(4597, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  204. case 3: modbus.WriteSingleCoil(4598, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  205. case 4: modbus.WriteSingleCoil(4599, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  206. case 5: modbus.WriteSingleCoil(4600, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  207. case 6: modbus.WriteSingleCoil(4601, true); DeviceProcessLogShow($"【{loc}】号位置接酒完成"); break;
  208. }
  209. }
  210. /// <summary>
  211. /// 倒酒过程
  212. /// </summary>
  213. public void ToPourWink()
  214. {
  215. //if (morkMW.AllowPourWink && morkMW.CupSignal)
  216. //{
  217. // morkMW.AllowPourWink = false;
  218. // modbus.WriteSingleRegister(0000, 8);//倒酒
  219. //}
  220. if (morkMW.CupSignal && RTrig.GetInstance("AllowOut").Start(morkMW.MixWinkComplte) && modbus.Connected)
  221. {
  222. DeviceProcessLogShow("开始倒酒");
  223. modbus.WriteSingleRegister(0000, 8);//倒酒
  224. }
  225. }
  226. /// <summary>
  227. /// 信号检测
  228. /// </summary>
  229. public void SignalDetect()
  230. {
  231. if (RTrig.GetInstance("AllComplete").Start(morkMW.ProcessComplete))
  232. {
  233. OrderChange(morkMW.CurrentSuborderId, ORDER_STATUS.COMPLETED_COOK);
  234. morkMW.PourWinkComplete = true;
  235. DeviceProcessLogShow("订单制作完成,请取走调好酒杯");
  236. }
  237. if (morkMW.PourWinkComplete)
  238. {
  239. if (TTrig.GetInstance("PoutWinkCom").Start(morkMW.CupSignal))
  240. {
  241. OrderChange(morkMW.CurrentSuborderId, ORDER_STATUS.COMPLETED_TAKE);
  242. DeviceProcessLogShow("客户取走调好酒杯,请放置空酒杯,以待下次订单制作");
  243. }
  244. if (RTrig.GetInstance("PoutWinkCom").Start(morkMW.CupSignal))
  245. {
  246. DeviceProcessLogShow("空酒杯就位,允许执行下一订单");
  247. morkMW.PourWinkComplete = false;
  248. morkMW.TaskLock = false;
  249. Thread.Sleep(2000);
  250. }
  251. }
  252. }
  253. /// <summary>
  254. /// 读卡乐普机器人状态
  255. /// </summary>
  256. public override void ReadData()
  257. {
  258. //GetStatus("M230.0", new Action<object>((obj) =>
  259. //{
  260. //}));
  261. if (modbus.Connected)
  262. {
  263. morkMW.ArriveWinkOneLoc = modbus.ReadCoils(4616);
  264. morkMW.ArriveWinkTwoLoc = modbus.ReadCoils(4617);
  265. morkMW.ArriveWinkThreeLoc = modbus.ReadCoils(4618);
  266. morkMW.ArriveWinkFourLoc = modbus.ReadCoils(4619);
  267. morkMW.ArriveWinkFiveLoc = modbus.ReadCoils(4620);
  268. morkMW.ArriveWinkSixLoc = modbus.ReadCoils(4621);
  269. morkMW.RobotIdle = modbus.ReadCoils(4201);
  270. morkMW.CupSignal = modbus.ReadInputs(0);
  271. morkMW.TakeWinkOneComplete = modbus.ReadCoils(4606);
  272. morkMW.TakeWinkTwoComplete = modbus.ReadCoils(4607);
  273. morkMW.TakeWinkThreeComplete = modbus.ReadCoils(4608);
  274. morkMW.TakeWinkFourComplete = modbus.ReadCoils(4609);
  275. morkMW.TakeWinkFiveComplete = modbus.ReadCoils(4610);
  276. morkMW.TakeWinkSixComplete = modbus.ReadCoils(4611);
  277. morkMW.MixWinkComplte = modbus.ReadCoils(4612);
  278. morkMW.ProcessComplete = modbus.ReadCoils(4613);
  279. }
  280. else
  281. {
  282. modbus.ModbusTcpConnect("192.168.0.100", 8001);
  283. }
  284. }
  285. public void VariableMonitor()
  286. {
  287. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkOneLoc").CurrentValue = morkMW.ArriveWinkOneLoc;
  288. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkTwoLoc").CurrentValue = morkMW.ArriveWinkTwoLoc;
  289. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkThreeLoc").CurrentValue = morkMW.ArriveWinkThreeLoc;
  290. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkFourLoc").CurrentValue = morkMW.ArriveWinkFourLoc;
  291. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkFiveLoc").CurrentValue = morkMW.ArriveWinkFiveLoc;
  292. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ArriveWinkSixLoc").CurrentValue = morkMW.ArriveWinkSixLoc;
  293. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "RobotIdle").CurrentValue = morkMW.RobotIdle;
  294. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "CupSignal").CurrentValue = morkMW.CupSignal;
  295. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkOneComplete").CurrentValue = morkMW.TakeWinkOneComplete;
  296. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkTwoComplete").CurrentValue = morkMW.TakeWinkTwoComplete;
  297. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkThreeComplete").CurrentValue = morkMW.TakeWinkThreeComplete;
  298. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkFourComplete").CurrentValue = morkMW.TakeWinkFourComplete;
  299. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkFiveComplete").CurrentValue = morkMW.TakeWinkFiveComplete;
  300. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "TakeWinkSixComplete").CurrentValue = morkMW.TakeWinkSixComplete;
  301. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "MixWinkComplte").CurrentValue = morkMW.MixWinkComplte;
  302. GVL_MorkMW.varibleInfos.FirstOrDefault(p => p.VaribleName == "ProcessComplete").CurrentValue = morkMW.ProcessComplete;
  303. }
  304. public override void ResetProgram()
  305. {
  306. morkMW = null;
  307. morkMW = new GVL_MorkMW();
  308. }
  309. public override void SimOrder()
  310. {
  311. EventBus.GetInstance().Subscribe<MorkMWSimOrder>(0, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  312. {
  313. if (@event != null && @event is MorkMWSimOrder order)
  314. {
  315. if (order.mixWink.Count > 0)
  316. {
  317. string guid = Guid.NewGuid().ToString();
  318. simOrderLocInfos.Enqueue(new SimOrderLocInfo { mixWink = order.mixWink, SuborderId = guid });
  319. DeviceProcessLogShow("收到模拟订单");
  320. }
  321. }
  322. });
  323. }
  324. public override void Stop()
  325. {
  326. }
  327. private void GetStatus(string key, Action<object> action)
  328. {
  329. if (peripheralStatus.ContainsKey(key))
  330. {
  331. if (peripheralStatus[key] != null)
  332. {
  333. action?.Invoke(peripheralStatus[key]);
  334. }
  335. }
  336. }
  337. /// <summary>
  338. /// 卡乐普写数据
  339. /// </summary>
  340. /// <param name="address"></param>
  341. /// <param name="value"></param>
  342. private void WriteData(string address, object value)
  343. {
  344. EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value });
  345. }
  346. /// <summary>
  347. /// 数据解析
  348. /// </summary>
  349. public void DataParse()
  350. {
  351. EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
  352. {
  353. if (@event != null && @event is DoOrderEvent order)
  354. {
  355. morkMW.doOrderEvents.Add(order);
  356. if (listMorkMWGoods.Count == 0) return;
  357. if (morkMW.historySuborderId.FirstOrDefault(p => p == order.MorkOrder.SuborderId) != null) return;
  358. OrderCount++;
  359. var res = listMorkMWGoods?.FirstOrDefault(p => p.GoodsKey == order.MorkOrder.GoodsKey);
  360. if (res != null)
  361. {
  362. string guid = Guid.NewGuid().ToString();
  363. orderLocInfos.Enqueue(new BPASmartClient.MorkMW.Model.OrderLocInfo { mixWink = res.MorkMWBoms, SuborderId = order.MorkOrder.SuborderId });
  364. morkMW.historySuborderId.Add(order.MorkOrder.SuborderId);
  365. OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
  366. DeviceProcessLogShow($"收到【{OrderCount}】次小程序订单,当前订单【{order.MorkOrder.GoodsName}】,订单号【{order.MorkOrder.SuborderId}】");
  367. }
  368. else
  369. {
  370. DeviceProcessLogShow($"未找到订单对应商品,订单号【{order.MorkOrder.SuborderId}】");
  371. }
  372. }
  373. });
  374. }
  375. /// <summary>
  376. /// 订单状态上报
  377. /// </summary>
  378. /// <param name="subid"></param>
  379. /// <param name="oRDER_STATUS"></param>
  380. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  381. {
  382. try
  383. {
  384. var res = morkMW.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);
  385. string goodName = string.Empty;
  386. string SortNum = string.Empty;
  387. if (res != null)
  388. {
  389. goodName = res.MorkOrder.GoodsName;
  390. SortNum = res.MorkOrder.SortNum.ToString();
  391. }
  392. EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { SortNum = SortNum, GoodName = goodName, Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
  393. }
  394. catch (Exception)
  395. {
  396. DeviceProcessLogShow($"订单状态上报失败,订单号【{morkMW.CurrentSuborderId}】");
  397. //throw;
  398. }
  399. }
  400. /// <summary>
  401. /// 连接卡乐普机器人
  402. /// </summary>
  403. /// <param name="ip"></param>
  404. /// <param name="port"></param>
  405. public void ConnectKlpRobot(string ip, int port)
  406. {
  407. modbus = new ModbusTcp();
  408. modbus.Show += new Action<string>((s) =>
  409. {
  410. if (s != null) DeviceProcessLogShow(s);
  411. });
  412. modbus.ShowEx += new Action<string>((s) =>
  413. {
  414. if ((s != null)) DeviceProcessLogShow(s);
  415. });
  416. modbus.ModbusTcpConnect(ip, port);
  417. }
  418. /// <summary>
  419. /// 调酒小程序订单队列
  420. /// </summary>
  421. public ConcurrentQueue<BPASmartClient.MorkMW.Model.OrderLocInfo> orderLocInfos = new ConcurrentQueue<BPASmartClient.MorkMW.Model.OrderLocInfo>();
  422. /// <summary>
  423. /// 调酒模拟订单队列
  424. /// </summary>
  425. public ConcurrentQueue<SimOrderLocInfo> simOrderLocInfos = new ConcurrentQueue<SimOrderLocInfo>();
  426. /// <summary>
  427. /// 调酒机配方集合
  428. /// </summary>
  429. public List<MORKMWGoods> listMorkMWGoods = new List<MORKMWGoods>();
  430. }
  431. }