终端一体化运控平台
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Control_MorkTM.cs 16 KiB

2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. using BPA.Message;
  2. using BPA.Message.Enum;
  3. using BPASmartClient.Device;
  4. using BPASmartClient.EventBus;
  5. using BPASmartClient.Helper;
  6. using BPASmartClient.Message;
  7. using BPASmartClient.Model;
  8. using BPASmartClient.Model.PLC;
  9. using BPASmartClient.MorkTM;
  10. using BPASmartClient.MorkTM.Model;
  11. using System.Collections.Concurrent;
  12. using static BPASmartClient.EventBus.EventBus;
  13. namespace BPASmartClient.MorkTM
  14. {
  15. public class Control_MorkTM : BaseDevice
  16. {
  17. public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.TMC_MT; } }
  18. GVL_MorkTM morkTM = new GVL_MorkTM();
  19. PolymerBatching polymer = new PolymerBatching();
  20. //浮点数放大倍数
  21. const int expand = 100;
  22. public override void DoMain()
  23. {
  24. ServerInit();
  25. DataParse();
  26. polymer.GetMaterialInfo();
  27. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  28. {
  29. if(o.Length > 0)
  30. {
  31. Dictionary<int, float> res = new Dictionary<int, float>();
  32. res.Add(Convert.ToInt32(o[0]), Convert.ToSingle(o[1]));
  33. SetMatertialWeight(res);
  34. Thread.Sleep(100);
  35. OpenUsePassageWay(Convert.ToInt32(o[0]));
  36. }
  37. }), "通道口出料");
  38. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  39. {
  40. if(o.Length > 0)
  41. {
  42. PosionTurnOnTest(Convert.ToInt32(o[0]));
  43. }
  44. }), "转盘转动");
  45. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  46. {
  47. if (o.Length > 0)
  48. {
  49. OpenPassway(Convert.ToInt32(o[0]));
  50. }
  51. }), "开启通道");
  52. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  53. {
  54. if (o.Length > 0)
  55. {
  56. CheckPassway(Convert.ToInt32(o[0]), Convert.ToInt32(o[1]));
  57. }
  58. }), "开始矫正");
  59. ActionManage.GetInstance.Register(new Action<object[]>((o) =>
  60. {
  61. if (o.Length > 0)
  62. {
  63. CheckMaterailWeight(Convert.ToInt32(o[0]), Convert.ToInt32(o[1]));
  64. }
  65. }), "矫正重量");
  66. ActionManage.GetInstance.Register(new Action<object>((o) =>
  67. {
  68. if (o != null && o is WritePar writePar) WriteData(writePar.Address, writePar.Value);
  69. }), "WriteVW");
  70. ActionManage.GetInstance.Register(new Action<object>((o) =>
  71. {
  72. if (o != null && o is WritePar writePar) WriteData(writePar.Address, writePar.Value);
  73. }), "WriteBools");
  74. morkTM.ReachPosions = new List<bool>() { morkTM.ReachPosion_1, morkTM.ReachPosion_2, morkTM.ReachPosion_3, morkTM.ReachPosion_4, morkTM.ReachPosion_5, morkTM.ReachPosion_6 , morkTM.ReachOutPosion_0, };
  75. DeviceProcessLogShow("设备初始化完成");
  76. }
  77. private void ServerInit()
  78. {
  79. //物料信息
  80. EventBus.EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  81. {
  82. if (@event == null) return;
  83. if (@event is MaterialDeliveryEvent material)
  84. {
  85. orderMaterialDelivery = material.orderMaterialDelivery;
  86. }
  87. });
  88. //配方数据信息
  89. EventBus.EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  90. {
  91. if (@event == null) return;
  92. if (@event is RecipeBomEvent recipe)
  93. {
  94. recipeBoms = recipe.recipeBoms;
  95. }
  96. });
  97. }
  98. private void DataParse()
  99. {
  100. EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  101. {
  102. if(@event == null) return;
  103. if(@event is DoOrderEvent order)
  104. {
  105. if (order.MorkOrder.GoodBatchings == null) return;
  106. OrderCount++;
  107. morkTM.doOrderEvents.Add(order);
  108. OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
  109. DeviceProcessLogShow($"接收到{OrderCount}次订单");
  110. Dictionary<int, float> OrderPushes = new Dictionary<int, float>();
  111. foreach (var item in order.MorkOrder.GoodBatchings)
  112. {
  113. var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
  114. if (res != null)
  115. {
  116. OrderPushes.TryAdd(int.Parse(res.BatchingLoc), item.BatchingCount);
  117. }
  118. }
  119. morkTM.morkOrderPushesTeaWithMilk.Enqueue(new OrderLocInfo()
  120. {
  121. GoodName = order.MorkOrder.GoodsName,
  122. SuborderId = order.MorkOrder.SuborderId,
  123. GoodPushes = OrderPushes
  124. });
  125. }
  126. });
  127. }
  128. private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
  129. {
  130. var res = morkTM.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);
  131. string goodName = string.Empty;
  132. string SortNum = string.Empty;
  133. EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent()
  134. {
  135. SortNum = res.MorkOrder. SortNum.ToString(),
  136. GoodName = res.MorkOrder.GoodsName,
  137. Status = oRDER_STATUS,
  138. SubOrderId = res.MorkOrder.SuborderId,
  139. deviceClientType = DeviceType
  140. });
  141. if(oRDER_STATUS == ORDER_STATUS.COMPLETED_COOK) morkTM.doOrderEvents.Remove(res);
  142. }
  143. public override void MainTask()
  144. {
  145. IsHealth = true;
  146. MakeTeaWithMilkProcess();
  147. }
  148. private void MakeTeaWithMilkProcess()
  149. {
  150. if (morkTM.morkOrderPushesTeaWithMilk.Count > 0)
  151. {
  152. if (morkTM.morkOrderPushesTeaWithMilk.TryDequeue(out OrderLocInfo orderLoc)) //&&原点位置是否有杯子)
  153. {
  154. DeviceProcessLogShow($"开始制作奶茶{orderLoc.GoodName}");
  155. morkTM.MakeCount = 0;
  156. SetMatertialWeight(orderLoc.GoodPushes);//设置物料出料量
  157. morkTM.RecipesPushes.Clear();
  158. morkTM.RecipesPushes = orderLoc.GoodPushes;
  159. MakeProcess(orderLoc.GoodName, morkTM.MakeCount, morkTM.RecipesPushes.Count);//制作进度
  160. OrderChange(orderLoc.SuborderId, ORDER_STATUS.COOKING);
  161. foreach (var item in morkTM.RecipesPushes)
  162. {
  163. morkTM.MakeCount++;
  164. PosionTurnOn(item.Key);//设定转盘位置并等待到位信号
  165. Thread.Sleep(1000);
  166. OpenUsePassageWay(item.Key);//打开通道并等待出料完成
  167. DeviceProcessLogShow($"奶茶{orderLoc.GoodName}:配料{item.Key}:添加量{item.Value}");
  168. MakeProcess(orderLoc.GoodName,morkTM.MakeCount,morkTM.RecipesPushes.Count);
  169. }
  170. TurnOutPosion();
  171. OrderChange(orderLoc.SuborderId, ORDER_STATUS.COMPLETED_COOK);
  172. MakeProcess(orderLoc.GoodName, 1, 1);
  173. DeviceProcessLogShow($"奶茶{orderLoc.GoodName}制作完成");
  174. }
  175. }
  176. }
  177. /// <summary>
  178. /// 打开出料通道
  179. /// </summary>
  180. private void OpenUsePassageWay(int pos)
  181. {
  182. string address = "";
  183. foreach (var item in polymer.OutPosionPLCs)//根据位置筛选物料plc点位
  184. {
  185. if(item.posion is MaterialPosion posion)
  186. {
  187. if(posion == (MaterialPosion)pos)
  188. {
  189. WriteData(item.SetPLCPosion,true);
  190. address = item.GetPLCPosion;
  191. return;
  192. }
  193. }
  194. }
  195. while(!morkTM.outMaterialCompletes[pos]) //等待出料完成
  196. {
  197. Thread.Sleep(1000);
  198. }
  199. WriteData(address, false);
  200. }
  201. /// <summary>
  202. /// 转盘旋转位置设定
  203. /// </summary>
  204. /// <param name="posion"></param>
  205. private void PosionTurnOn(int posion)
  206. {
  207. int i = 0;
  208. string address = "";
  209. foreach (var item in polymer.GoodsMaterialPosion)
  210. {
  211. if (item.Key.Contains((MaterialPosion)posion))
  212. {
  213. WriteData(item.Value.SetPLCPosion,true);
  214. i = Convert.ToInt32(item.Value.posion);
  215. address = item.Value.GetPLCPosion;
  216. return;
  217. }
  218. }
  219. while(!morkTM.ReachPosions[i-1])//等待转盘到达信号
  220. {
  221. Thread.Sleep(1000);
  222. }
  223. if(address != null) WriteData(address, false);//把信号置为0
  224. }
  225. #region 调试功能
  226. /// <summary>
  227. /// 转盘回原点
  228. /// </summary>
  229. private void TurnOutPosion()
  230. {
  231. WriteData("M4.6", true);
  232. while (!morkTM.ReachPosions[6])
  233. {
  234. Thread.Sleep(1000);
  235. }
  236. WriteData("M14.6", false);
  237. }
  238. /// <summary>
  239. /// 调试转盘
  240. /// </summary>
  241. /// <param name="posion"></param>
  242. private void PosionTurnOnTest(int posion)
  243. {
  244. if(posion==0) TurnOutPosion();
  245. else
  246. {
  247. string address = string.Empty;
  248. int i = 0;
  249. foreach (var item in polymer.TurnPosionPLCs)
  250. {
  251. if ((OutMaterialPosion)item.posion == (OutMaterialPosion)posion)
  252. {
  253. WriteData(item.SetPLCPosion, true);
  254. address = item.GetPLCPosion;
  255. i = Convert.ToInt32(item.posion);
  256. return ;
  257. }
  258. }
  259. while(morkTM.ReachPosions[posion - 1])
  260. {
  261. Thread.Sleep(1000);
  262. }
  263. WriteData(address,false);
  264. DeviceProcessLogShow($"转盘转动到位置{i}");
  265. }
  266. }
  267. /// <summary>
  268. /// 开启通道
  269. /// </summary>
  270. private void OpenPassway(int posion)
  271. {
  272. foreach(var item in polymer.OutPosionPLCs)
  273. {
  274. if((MaterialPosion)item.posion == (MaterialPosion)posion)
  275. {
  276. WriteData(item.SetPLCPosion,true);
  277. return ;
  278. }
  279. }
  280. }
  281. /// <summary>
  282. /// 开始校正
  283. /// </summary>
  284. /// <param name="passway"></param>
  285. /// <param name="time"></param>
  286. private void CheckPassway(int passway,int time)
  287. {
  288. WriteData(polymer.PasswayPosionList[(MaterialPosion)passway], Convert.ToInt32(time * expand));//写入出料时间
  289. Thread.Sleep(100);
  290. WriteData("M5.0", true);//开始校正
  291. }
  292. /// <summary>
  293. /// 确认校正重量
  294. /// </summary>
  295. private void CheckMaterailWeight(int passway,float weight)
  296. {
  297. WriteData(polymer.PasswayPosionList[(MaterialPosion)passway], weight*expand);
  298. }
  299. /// <summary>
  300. /// 奶茶制作进度
  301. /// </summary>
  302. private void MakeProcess(string goodName,int percent,int count)
  303. {
  304. int res = Convert.ToInt32(Math.Floor((double)percent / count)) * 100;
  305. ActionManage.GetInstance.Send("奶茶制作进度",new object[] {goodName, res });
  306. }
  307. #endregion
  308. /// <summary>
  309. /// 把每一个物料的用量写入plc
  310. /// </summary>
  311. /// <param name="materials"></param>
  312. private void SetMatertialWeight(Dictionary<int, float> materials)
  313. {
  314. foreach (var material in materials)
  315. {
  316. int value = Convert.ToInt32(material.Value*expand);
  317. WriteData(polymer.MaterialPosionList[(MaterialPosion)material.Key], value);
  318. DeviceProcessLogShow($"通道{material.Key}预设料{material.Value}g");
  319. Thread.Sleep(200);
  320. }
  321. }
  322. public override void ReadData()
  323. {
  324. //启用通道的地址1
  325. GetStatus("M0.0", new Action<object>((obj) =>
  326. {
  327. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 28)
  328. {
  329. }
  330. }));
  331. GetStatus("M10.0",new Action<object>((obj) =>
  332. {
  333. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 28)
  334. {
  335. for (int i = 0; i < 28; i++)
  336. {
  337. if (morkTM.outMaterialCompletes.ContainsKey(i+1))
  338. {
  339. morkTM.outMaterialCompletes[i+1] = bools[i];
  340. }
  341. else
  342. {
  343. morkTM.outMaterialCompletes.Add(i+1, bools[i]);
  344. }
  345. }
  346. }
  347. }));
  348. //转盘移动的地址
  349. GetStatus("M4.0", new Action<object>((obj) =>
  350. {
  351. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7)
  352. {
  353. }
  354. }));
  355. //装盘移动到位的地址
  356. GetStatus("M14.0", new Action<object>((obj) =>
  357. {
  358. if (obj is bool[] bools && bools.Length > 0 && bools.Length <= 7)
  359. {
  360. morkTM.ReachPosion_1 = bools[0];
  361. morkTM.ReachPosion_2 = bools[1];
  362. morkTM.ReachPosion_3 = bools[2];
  363. morkTM.ReachPosion_4 = bools[3];
  364. morkTM.ReachPosion_5 = bools[4];
  365. morkTM.ReachPosion_6 = bools[5];
  366. morkTM.ReachOutPosion_0 = bools[6];
  367. for (int i = 0; i < 7; i++)
  368. {
  369. morkTM.ReachPosions[i] = bools[i];
  370. }
  371. }
  372. }));
  373. }
  374. public override void ResetProgram()
  375. {
  376. morkTM = null;
  377. morkTM = new GVL_MorkTM();
  378. }
  379. private void WriteData(string address, object value)
  380. {
  381. EventBus.EventBus.GetInstance().Publish(new WriteModel() { DeviceId = DeviceId, Address = address, Value = value });
  382. }
  383. private void GetStatus(string key, Action<object> action)
  384. {
  385. if (peripheralStatus.ContainsKey(key))
  386. {
  387. if (peripheralStatus[key] != null)
  388. {
  389. action?.Invoke(peripheralStatus[key]);
  390. }
  391. }
  392. }
  393. public override void SimOrder()
  394. {
  395. ActionManage.GetInstance.Register(new Action<object>((o) =>
  396. {
  397. if (o is string goodName)
  398. {
  399. }
  400. }), "");
  401. }
  402. public override void Stop()
  403. {
  404. throw new NotImplementedException();
  405. }
  406. }
  407. }