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

383 行
17 KiB

  1. #define test
  2. using BPA.Helper;
  3. using BPASmartClient.SmallBatchingSystem;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using BPASmartClient.CustomResource.Pages.Model;
  13. using BPASmartClient.CustomResource.UserControls.MessageShow;
  14. using BPASmartClient.CustomResource.UserControls;
  15. namespace BPASmartClient.SmallBatchingSystem
  16. {
  17. public class Control
  18. {
  19. private volatile static Control _Instance;
  20. public static Control GetInstance => _Instance ?? (_Instance = new Control());
  21. private Control() { }
  22. public ConcurrentQueue<RecipeInfo> MakeOrderQueue { get; set; } = new ConcurrentQueue<RecipeInfo>();
  23. public bool IsCancel { get; set; }
  24. public void Init()
  25. {
  26. ThreadManage.GetInstance().Start(new Action(() =>
  27. {
  28. PlcServer.GetInstance.Connect();
  29. }), "设备初始化");
  30. ThreadManage.GetInstance().StartLong(new Action(() =>
  31. {
  32. while (MakeOrderQueue.Count > 0)
  33. {
  34. if (MakeOrderQueue.TryDequeue(out RecipeInfo recipeInfo))
  35. {
  36. //ProcessOne(recipeInfo);
  37. ProcessTwo(recipeInfo);
  38. }
  39. }
  40. Thread.Sleep(10);
  41. }), "配方流程控制");
  42. }
  43. private void ProcessOne(RecipeInfo recipeInfo)
  44. {
  45. IsCancel = false;
  46. List<int> OutletInfo = new List<int>();
  47. recipeInfo.SiloInfoModels.ToList()?.ForEach(item =>
  48. {
  49. var res = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(item.SiloName)) != null);
  50. if (res != null) if (!OutletInfo.Contains(res.OutletLoc)) OutletInfo.Add(res.OutletLoc);
  51. });
  52. foreach (var temp in OutletInfo)
  53. {
  54. PlcServer.GetInstance.WriteData("VW302", (ushort)temp);//设置出料口位置
  55. PlcServer.GetInstance.WriteData("M10.0", true);//定位启动
  56. RunLog($"启动定位,出料口位置:{temp}");
  57. int index = temp - 1;
  58. if (index >= 0)
  59. {
  60. RunLog("等待定位完成");
  61. while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈
  62. if (IsCancel) break;
  63. RunLog("定位完成");
  64. PlcServer.GetInstance.WriteData("M20.0", false);
  65. while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);
  66. if (IsCancel) break;
  67. RunLog("定位完成,复位成功");
  68. foreach (var temp1 in recipeInfo.SiloInfoModels)
  69. {
  70. var rest = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null);
  71. if (rest != null && rest.OutletLoc == temp)
  72. {
  73. var res = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == temp1.SiloName);
  74. if (res != null)
  75. {
  76. StatusNotify(res.SiloName, Status.正在配料);
  77. RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{temp1.SiloWeight}");
  78. PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)temp1.SiloWeight);
  79. RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}");
  80. PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true);
  81. while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成
  82. if (IsCancel) break;
  83. RunLog("出料完成,复位出料完成状态");
  84. PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号
  85. while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功
  86. if (IsCancel) break;
  87. RunLog("出料完成复位成功");
  88. StatusNotify(res.SiloName, Status.配料完成);
  89. }
  90. }
  91. }
  92. if (IsCancel) return;
  93. }
  94. }
  95. if (!IsCancel)
  96. {
  97. RunLog($"写入配方执行完成信号");
  98. PlcServer.GetInstance.WriteData("M10.4", true);
  99. RunLog("等待配方执行完成");
  100. while (!PlcDataModel.RecipeBatchingComplete && !IsCancel) Thread.Sleep(1);
  101. if (IsCancel) return;
  102. RunLog($"【{recipeInfo.RecipeName}】配方执行完成");
  103. ActionManage.GetInstance.Send("GrindArenaceousCancel");
  104. }
  105. }
  106. /// <summary>
  107. /// 计时配料
  108. /// </summary>
  109. /// <param name="recipeInfo"></param>
  110. private void ProcessTwo(RecipeInfo recipeInfo)
  111. {
  112. IsCancel = false;
  113. Dictionary<int, List<int>> DeviceSoilInfo = new Dictionary<int, List<int>>();
  114. List<int> OutletInfo = new List<int>();
  115. recipeInfo.SiloInfoModels.ToList()?.ForEach(item =>
  116. {
  117. var res = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s == item.SiloName) != null);
  118. if (res != null)
  119. {
  120. var soliInfo = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == item.SiloName);
  121. if (soliInfo != null)
  122. {
  123. if (!DeviceSoilInfo.ContainsKey(res.OutletLoc))
  124. {
  125. DeviceSoilInfo.Add(res.OutletLoc, new List<int>());
  126. DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc);
  127. }
  128. else
  129. {
  130. DeviceSoilInfo[res.OutletLoc].Add(soliInfo.SiloLoc);
  131. }
  132. }
  133. }
  134. });
  135. foreach (var temp in DeviceSoilInfo)
  136. {
  137. PlcServer.GetInstance.WriteData("VW302", (ushort)temp.Key);//设置出料口位置
  138. //PlcServer.GetInstance.WriteData("M10.0", true);//定位启动
  139. PlcServer.GetInstance.WriteData("M10.4", true);//定位启动
  140. RunLog($"启动定位,出料口位置:{temp}");
  141. int index = temp.Key - 1;
  142. if (index >= 0)
  143. {
  144. RunLog("等待定位完成");
  145. while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈
  146. if (IsCancel) break;
  147. RunLog("定位完成");
  148. PlcServer.GetInstance.WriteData("M20.0", false);
  149. while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);
  150. if (IsCancel) break;
  151. RunLog("定位完成,复位成功");
  152. foreach (var temp1 in temp.Value)
  153. {
  154. //var rest = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null);
  155. //if (rest != null && rest.OutletLoc == temp)
  156. //{
  157. var res = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloLoc == temp1);
  158. if (res != null)
  159. {
  160. var tempRecipe = recipeInfo.SiloInfoModels.FirstOrDefault(p => p.SiloName == res.SiloName);
  161. if (tempRecipe != null)
  162. {
  163. StatusNotify(res.SiloName, Status.正在配料);
  164. RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{tempRecipe.SiloWeight}");
  165. PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(tempRecipe.SiloWeight * 10));
  166. RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}");
  167. PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true);
  168. while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成
  169. if (IsCancel) break;
  170. RunLog("出料完成,复位出料完成状态");
  171. #if test
  172. PlcServer.GetInstance.WriteData("M10.0", false);//复位出料完成信号
  173. #else
  174. PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号
  175. #endif
  176. while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功
  177. if (IsCancel) break;
  178. RunLog("出料完成复位成功");
  179. StatusNotify(res.SiloName, Status.配料完成);
  180. }
  181. }
  182. //}
  183. }
  184. if (IsCancel) return;
  185. }
  186. }
  187. //IsCancel = false;
  188. //List<int> OutletInfo = new List<int>();
  189. //recipeInfo.SiloInfoModels.ToList()?.ForEach(item =>
  190. //{
  191. // var res = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(item.SiloName)) != null);
  192. // if (res != null) if (!OutletInfo.Contains(res.OutletLoc)) OutletInfo.Add(res.OutletLoc);
  193. //});
  194. //foreach (var temp in OutletInfo)
  195. //{
  196. // PlcServer.GetInstance.WriteData("VW302", (ushort)temp);//设置出料口位置
  197. // //PlcServer.GetInstance.WriteData("M10.0", true);//定位启动
  198. // PlcServer.GetInstance.WriteData("M10.4", true);//定位启动
  199. // RunLog($"启动定位,出料口位置:{temp}");
  200. // int index = temp - 1;
  201. // if (index >= 0)
  202. // {
  203. // RunLog("等待定位完成");
  204. // while (!PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);//等待定位反馈
  205. // if (IsCancel) break;
  206. // RunLog("定位完成");
  207. // PlcServer.GetInstance.WriteData("M20.0", false);
  208. // while (PlcDataModel.TargetLocComplete && !IsCancel) Thread.Sleep(1);
  209. // if (IsCancel) break;
  210. // RunLog("定位完成,复位成功");
  211. // foreach (var temp1 in recipeInfo.SiloInfoModels)
  212. // {
  213. // var rest = Json<ConfigInfoModel>.Data.OutletInfoModels.FirstOrDefault(p => p.SiloInfos.FirstOrDefault(s => s.Contains(temp1.SiloName)) != null);
  214. // if (rest != null && rest.OutletLoc == temp)
  215. // {
  216. // var res = Json<ConfigInfoModel>.Data.SiloInfoModels.FirstOrDefault(p => p.SiloName == temp1.SiloName);
  217. // if (res != null)
  218. // {
  219. // StatusNotify(res.SiloName, Status.正在配料);
  220. // RunLog($"写重量地址:{GetWeightAdd(res.SiloLoc)},重量:{temp1.SiloWeight}");
  221. // PlcServer.GetInstance.WriteData(GetWeightAdd(res.SiloLoc), (ushort)(temp1.SiloWeight * 10));
  222. // RunLog($"写启动信号地址:{GetStartSingleAdd(res.SiloLoc)}");
  223. // PlcServer.GetInstance.WriteData(GetStartSingleAdd(res.SiloLoc), true);
  224. // while (!PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成
  225. // if (IsCancel) break;
  226. // RunLog("出料完成,复位出料完成状态");
  227. //#if test
  228. // PlcServer.GetInstance.WriteData("M10.0", false);//复位出料完成信号
  229. //#else
  230. //PlcServer.GetInstance.WriteData("M4.0", false);//复位出料完成信号
  231. //#endif
  232. // while (PlcDataModel.BatchingCompleted && !IsCancel) Thread.Sleep(1);//等待出料完成信号复位成功
  233. // if (IsCancel) break;
  234. // RunLog("出料完成复位成功");
  235. // StatusNotify(res.SiloName, Status.配料完成);
  236. // }
  237. // }
  238. // }
  239. // if (IsCancel) return;
  240. // }
  241. //}
  242. if (!IsCancel)
  243. {
  244. RunLog($"写入配方执行完成信号");
  245. //PlcServer.GetInstance.WriteData("M10.4", true);
  246. PlcServer.GetInstance.WriteData("M10.5", true);
  247. RunLog("等待配方执行完成");
  248. while (!PlcDataModel.RecipeBatchingComplete && !IsCancel) Thread.Sleep(1);
  249. if (IsCancel) return;
  250. RunLog($"【{recipeInfo.RecipeName}】配方执行完成");
  251. ActionManage.GetInstance.Send("GrindArenaceousCancel");
  252. }
  253. }
  254. /// <summary>
  255. /// 获取重量设置地址
  256. /// </summary>
  257. /// <param name="num"></param>
  258. /// <returns></returns>
  259. private string GetWeightAdd(int num)
  260. {
  261. #if test
  262. if (num > 0)
  263. {
  264. int add = 0;
  265. if (num >= 1 && num <= 18)
  266. {
  267. add = 200 + (num - 1) * 2;
  268. }
  269. return $"VW{add}";
  270. }
  271. return default;
  272. #else
  273. if (num > 0)
  274. {
  275. int add = 0;
  276. if (num >= 1 && num <= 18)
  277. {
  278. add = 100 + (num - 1) * 2;
  279. }
  280. else if (num >= 9 && num <= 18)
  281. {
  282. add = 102 + (num - 1) * 2;
  283. }
  284. return $"VW{add}";
  285. }
  286. return default;
  287. #endif
  288. }
  289. private void StatusNotify(string SiloName, Status Status)
  290. {
  291. ActionManage.GetInstance.Send("StatusNotify", new RecipeStatus() { RawMaterialName = SiloName, Status = Status.ToString() });
  292. }
  293. public void RunLog(string info)
  294. {
  295. BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.ShowRunLog(info);
  296. Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
  297. }
  298. public void OperationLog(string info)
  299. {
  300. BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.ShowUserLog(info);
  301. Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
  302. }
  303. public void DebugLog(string info)
  304. {
  305. BPASmartClient.Message.MessageLog.GetInstance.DebugLog(info);
  306. }
  307. public void NotifyPrompt(string info)
  308. {
  309. App.Current.Dispatcher.Invoke(() =>
  310. {
  311. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", info);
  312. });
  313. }
  314. /// <summary>
  315. /// 获取启动信号地址
  316. /// </summary>
  317. /// <param name="num"></param>
  318. /// <returns></returns>
  319. private string GetStartSingleAdd(int num)
  320. {
  321. #if test
  322. if (num > 0)
  323. {
  324. string Add = string.Empty;
  325. var t = num / 8;
  326. var c = (num % 8);
  327. if (c == 0)
  328. {
  329. t--;
  330. c = 7;
  331. }
  332. else c--;
  333. Add = $"M{t + 4}.{c}";
  334. return Add;
  335. }
  336. return default;
  337. #else
  338. if (num > 0)
  339. {
  340. string Add = string.Empty;
  341. var t = num / 8;
  342. var c = (num % 8);
  343. if (c == 0)
  344. {
  345. t--;
  346. c = 7;
  347. }
  348. else c--;
  349. Add = $"M{t}.{c}";
  350. return Add;
  351. }
  352. return default;
  353. #endif
  354. }
  355. }
  356. }