终端一体化运控平台
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

455 líneas
18 KiB

  1. using BPASmartClient.CustomResource.Pages.Model;
  2. using BPASmartClient.Helper;
  3. using BPASmartClient.JXJFoodBigStation.Model.HK_PLC;
  4. using BPASmartClient.JXJFoodBigStation.Model.Siemens;
  5. using BPASmartClient.Modbus;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.Configuration;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. namespace BPASmartClient.JXJFoodBigStation.Model
  16. {
  17. public class ProcessControl
  18. {
  19. private volatile static ProcessControl _Instance;
  20. public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl());
  21. private ProcessControl() { }
  22. public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus();
  23. public HKDeviceStatus HKDevice = new HKDeviceStatus();
  24. GVL_BigStation BigStation = new GVL_BigStation();
  25. /// <summary>
  26. /// 配方数据
  27. /// </summary>
  28. public ObservableCollection<RecipeData> RemoteRecipes = new ObservableCollection<RecipeData>();
  29. /// <summary>
  30. /// 配方数据
  31. /// </summary>
  32. public ObservableCollection<RecipeData> IssuedComplete = new ObservableCollection<RecipeData>();
  33. /// <summary>
  34. /// 原料的名称和料仓的位置对应
  35. /// </summary>
  36. public Dictionary<string, short> RawMaterialsNamePos = new Dictionary<string, short>();
  37. /// <summary>
  38. /// 配方队列
  39. /// </summary>
  40. public ConcurrentQueue<string> RecipeQueue = new ConcurrentQueue<string>();
  41. /// <summary>
  42. /// AGV到达工站队列
  43. /// </summary>
  44. public ConcurrentQueue<string> AGVToWorkStationQueue = new ConcurrentQueue<string>();
  45. /// <summary>
  46. /// 接收原料数据
  47. /// </summary>
  48. public RecipeRawMaterial RawMaterial;
  49. public void Init()
  50. {
  51. RawMaterialsNamePos.Add("1", 1);
  52. RawMaterialsNamePos.Add("2", 2);
  53. RawMaterialsNamePos.Add("3", 3);
  54. RawMaterialsNamePos.Add("4", 4);
  55. RawMaterialsNamePos.Add("5", 5);
  56. RawMaterialsNamePos.Add("6", 6);
  57. RawMaterialsNamePos.Add("7", 7);
  58. RawMaterialsNamePos.Add("8", 8);
  59. RawMaterialsNamePos.Add("9", 9);
  60. RawMaterialsNamePos.Add("10", 10);
  61. RawMaterialsNamePos.Add("11", 11);
  62. RawMaterialsNamePos.Add("12", 12);
  63. ActionManage.GetInstance.Register(new Action<object>((res) =>
  64. {
  65. ObservableCollection<RawMaterial> RawMaterials = new ObservableCollection<RawMaterial>();
  66. if (SiemensDevice.IsConnected)
  67. {
  68. if (res != null && res is DL_Start_DB recipe)
  69. {
  70. RawMaterials.Clear();
  71. for (int i = 0; i < 15; i++)
  72. {
  73. if (RawMaterialsNamePos.ContainsKey(recipe.RecipeName))
  74. {
  75. RawMaterials.Add(new RawMaterial()
  76. {
  77. RawMaterialName = recipe.Material[i].Material_Name,
  78. RawMaterialBarrelNum = recipe.Material[i].Material_BarrelNum,
  79. RawMaterialWeight = recipe.Material[i].Material_Weight,
  80. RawMaterialLocation = (int)RawMaterialsNamePos[recipe.Material[i].Material_Name]
  81. });
  82. }
  83. else
  84. {
  85. //报警,配方的原料名称下发和设备不一致
  86. }
  87. }
  88. Json<RemoteRecipe>.Data.Recipes.Add(new RecipeData()
  89. {
  90. RecipeName = recipe.RecipeName,
  91. RecipeCode = recipe.RecipeCode,
  92. RawMaterial = RawMaterials,
  93. TrayCode = recipe.TrayCode
  94. });
  95. }
  96. }
  97. }), "SiemensSendRecipe", true);
  98. string HK_PLC_IP = ConfigurationManager.AppSettings["HKPlc_IP"];
  99. string Siemens_PLC_IP = ConfigurationManager.AppSettings["Siemens_IP"];
  100. try
  101. {
  102. HKDevice.HK_PLC_S7.Connect(S7.Net.CpuType.S71500, HK_PLC_IP);
  103. //SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP);
  104. if (HKDevice.IsConnected)
  105. {
  106. HKDevice.Init();
  107. MessageLog.GetInstance.ShowRunLog("海科plc连接成功");
  108. }
  109. if (SiemensDevice.IsConnected)
  110. {
  111. SiemensDevice.Init();
  112. }
  113. }
  114. catch (Exception ex)
  115. {
  116. }
  117. ActionManage.GetInstance.CancelRegister("ManualSendRecipe");
  118. ActionManage.GetInstance.Register(new Action<Object>((o) =>
  119. {
  120. if (o !=null && o is RecipeData a)
  121. {
  122. Json<LocalRecipeDataColl>.Data.Recipes.Add(a);
  123. foreach (var item in Json<LocalRecipeDataColl>.Data.Recipes.ElementAt(0).RawMaterial)
  124. {
  125. item.RawMaterialLocation = Convert.ToInt32(item.RawMaterialName);
  126. }
  127. }
  128. }), "ManualSendRecipe", true);
  129. RecipeQueue.Clear();
  130. //Json<RemoteRecipeDataColl>.Data.Recipes = TestData.GetInstance.Recipes;//添加测试数据
  131. ThreadManage.GetInstance().StartLong(new Action(() =>
  132. {
  133. //ReadPLCDeviceInfo();
  134. ReceviceData();
  135. RecipeInfoToHKPLC();
  136. Thread.Sleep(10);
  137. }), "流程处理", true);
  138. ThreadManage.GetInstance().StartLong(new Action(() =>
  139. {
  140. if (HKDevice.IsConnected && SiemensDevice.IsConnected)
  141. {
  142. AgvGetInOut();
  143. }
  144. Thread.Sleep(10);
  145. }), "AGV进站送取货", true);
  146. ThreadManage.GetInstance().StartLong(new Action(() =>
  147. {
  148. ReadSiemensCommData();
  149. ReadHKPLCCommData();
  150. Thread.Sleep(10);
  151. }), "读取西门子和海科PLC的数据", true);
  152. }
  153. /// <summary>
  154. /// AGV送货
  155. /// </summary>
  156. /// <param name="bitNum"></param>
  157. private void AGV_Delivery(int bitNum)
  158. {
  159. if ((ReadSiemens("M4002." + bitNum) is bool) && BigStation.AgvDeliveryPosition == 0)
  160. {
  161. BigStation.AgvDeliveryPosition = 1;
  162. WriteHKPLC("M4002." + bitNum, true);
  163. WriteSiemens("M4002." + bitNum, false);
  164. }
  165. else if (ReadHK("M5002." + bitNum) is bool && BigStation.AgvDeliveryPosition == 1)
  166. {
  167. BigStation.AgvDeliveryPosition = 2;
  168. WriteSiemens("M5002." + bitNum, true);
  169. WriteHKPLC("M5002." + bitNum, false);
  170. }
  171. else if (ReadSiemens("M4004." + bitNum) is bool && BigStation.AgvDeliveryPosition == 2)
  172. {
  173. BigStation.AgvDeliveryPosition = 3;
  174. WriteHKPLC("M4004." + bitNum, true);
  175. WriteSiemens("M4004." + bitNum, false);
  176. }
  177. else if (ReadHK("M5004." + bitNum) is bool && BigStation.AgvDeliveryPosition == 3)
  178. {
  179. BigStation.AgvDeliveryPosition = 4;
  180. WriteSiemens("M5004." + bitNum, true);
  181. WriteHKPLC("M5004." + bitNum, false);
  182. }
  183. else if (ReadSiemens("M4005." + bitNum) is bool && BigStation.AgvDeliveryPosition == 4)
  184. {
  185. BigStation.AgvDeliveryPosition = 5;
  186. WriteHKPLC("M4005." + bitNum, true);
  187. WriteSiemens("M4005." + bitNum, false);
  188. }
  189. else if (ReadHK("M5005." + bitNum) is bool && BigStation.AgvDeliveryPosition == 5)
  190. {
  191. WriteSiemens("M5005." + bitNum, true);
  192. WriteHKPLC("M5005." + bitNum, false);
  193. }
  194. }
  195. /// <summary>
  196. /// AGV取货
  197. /// </summary>
  198. /// <param name="bitNum"></param>
  199. private void AGV_Pick(int bitNum)
  200. {
  201. if (ReadSiemens("M4003" + bitNum) is bool && BigStation.AgvPickUpPosition == 0)
  202. {
  203. BigStation.AgvPickUpPosition = 1;
  204. WriteHKPLC("M4003." + bitNum, true);
  205. WriteSiemens("M4003." + bitNum, false);
  206. }
  207. if (ReadHK("M5003" + bitNum) is bool && BigStation.AgvPickUpPosition == 1)
  208. {
  209. BigStation.AgvPickUpPosition = 2;
  210. WriteSiemens("M5003" + bitNum, true);
  211. WriteHKPLC("M5003" + bitNum, false);
  212. }
  213. if (ReadSiemens("M4006." + bitNum) is bool && BigStation.AgvPickUpPosition == 2)
  214. {
  215. BigStation.AgvPickUpPosition = 3;
  216. WriteHKPLC("M4006." + bitNum, true);
  217. WriteSiemens("M4006." + bitNum, false);
  218. }
  219. if (ReadHK("M5006." + bitNum) is bool && BigStation.AgvPickUpPosition == 3)
  220. {
  221. WriteSiemens("M5006." + bitNum, true);
  222. WriteHKPLC("M5006." + bitNum, false);
  223. }
  224. }
  225. /// <summary>
  226. /// AGV进站送货
  227. /// </summary>
  228. private void AgvGetInOut()
  229. {
  230. //获取工位上是否有小车
  231. SiemensDevice.Siemens_PLC_S7.Write<bool>(SiemensCommAddress.StationIsExistCar, (bool)
  232. HKDevice.HK_PLC_S7.Read<bool>("M4007.0"));
  233. //检测AGV到站信号
  234. if (AGVToWorkStationQueue.Count > 0)
  235. {
  236. int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == AGVToWorkStationQueue.ElementAt(0));
  237. int TrayLocation = RemoteRecipes.ElementAt(index).TrayCode;//根据配方编号,找到托盘的ID 托盘ID1-6
  238. string RecipeCode = (string)RemoteRecipes.ElementAt(index).RecipeCode;
  239. if (TrayLocation > 0 && TrayLocation < 7)
  240. {
  241. AGV_Delivery(TrayLocation - 1);
  242. if (BigStation.AgvDeliveryPosition == 5)
  243. {
  244. BigStation.AgvDeliveryPosition = 0;
  245. }
  246. AGV_Pick(TrayLocation - 1);
  247. if (BigStation.AgvPickUpPosition == 3)
  248. {
  249. BigStation.AgvPickUpPosition = 0;
  250. AGVToWorkStationQueue.TryDequeue(out RecipeCode);
  251. }
  252. }
  253. }
  254. }
  255. private void ReceviceData()
  256. {
  257. if (!BigStation.IsAllowManual && RemoteRecipes.Count == 0)//一个配方执行完成后,再获取配方数据
  258. {
  259. RemoteRecipes = Json<RemoteRecipe>.Data.Recipes;
  260. }
  261. else if (BigStation.IsAllowManual && RemoteRecipes.Count == 0)
  262. {
  263. RemoteRecipes = Json<LocalRecipeDataColl>.Data.Recipes;
  264. }
  265. if (RemoteRecipes.Count > 0)
  266. {
  267. foreach (var data in RemoteRecipes)
  268. {
  269. if (!(RecipeQueue.Contains(data.RecipeCode)))
  270. RecipeQueue.Enqueue(data.RecipeCode);
  271. }
  272. }
  273. else
  274. {
  275. RecipeQueue.Clear();
  276. BigStation.RecipeDosingStatus = 0;
  277. }
  278. }
  279. private void RecipeInfoToHKPLC()
  280. {
  281. if (RecipeQueue.Count > 0)
  282. {
  283. int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueue.ElementAt(0));
  284. if (index >= 0 && index < RemoteRecipes.Count)
  285. {
  286. string code = RemoteRecipes.ElementAt(index).RecipeCode;
  287. int trayCode = RemoteRecipes.ElementAt(index).TrayCode;
  288. if (RTrig.GetInstance("M5001.0").Start(HKDevice.HK_PLC_S7.Read<bool>("M5001.0")) && BigStation.RecipeDosingStatus == 0)//配方1是否允许下发配发
  289. {
  290. HKDevice.StockBinPar(RemoteRecipes.ElementAt(index));
  291. HKDevice.HK_PLC_S7.Write<bool>("M4001.0", true);//配发下发完成,to plc
  292. HKDevice.HK_PLC_S7.Write<bool>("M5001.0", false);//复位允许下发配方1信号
  293. BigStation.RecipeDosingStatus = 1;
  294. MessageLog.GetInstance.ShowRunLog($"配方状态:{code}下发完成");
  295. }
  296. if (HKDevice.HK_PLC_S7.Read<bool>("M5001.4") && BigStation.RecipeDosingStatus == 1)
  297. {
  298. BigStation.RecipeDosingStatus = 2;
  299. HKDevice.HK_PLC_S7.Write<bool>("M5001.4", false);//
  300. MessageLog.GetInstance.ShowRunLog($"配方状态:{code}配方配料");
  301. }
  302. if (BigStation.RecipeDosingStatus == 2)
  303. {
  304. if (RTrig.GetInstance("StockState").Start(HKDevice.HK_PLC_S7.Read<bool>("M5007.0")))
  305. {
  306. BigStation.RecipeDosingStatus = 3;
  307. MessageLog.GetInstance.ShowRunLog($"配方状态:{code}配料完成");
  308. HKDevice.HK_PLC_S7.Write<bool>("M5007.0",false);
  309. RecipeQueue.TryDequeue(out code);
  310. IssuedComplete.Add(RemoteRecipes.ElementAt(index));//将该配方添加到下
  311. if (!BigStation.IsAllowManual)
  312. {
  313. Json<RemoteRecipe>.Data.Recipes.RemoveAt(index);//制作完成,移除当前配方
  314. }
  315. else
  316. {
  317. Json<LocalRecipeDataColl>.Data.Recipes.RemoveAt(index);//制作完成,移除当前配方
  318. }
  319. BigStation.RecipeDosingStatus = 0;
  320. }
  321. }
  322. }
  323. }
  324. }
  325. public ConcurrentDictionary<string, Object> ReadHKPLCData = new ConcurrentDictionary<string, object>();
  326. public ConcurrentDictionary<string, Object> ReadSiemensData = new ConcurrentDictionary<string, object>();
  327. private void ReadSiemensCommData()
  328. {
  329. if (SiemensDevice.IsConnected)
  330. {
  331. GetSiemensStatus("", new Action<object>((obj) =>
  332. {
  333. if (obj is bool[] bools && bools.Length > 0)
  334. {
  335. }
  336. }));
  337. }
  338. }
  339. private void ReadHKPLCCommData()
  340. {
  341. if (HKDevice.IsConnected)
  342. {
  343. GetHKStatus("", new Action<object>((obj) =>
  344. {
  345. if (obj is bool[] bools && bools.Length > 0)
  346. {
  347. }
  348. }));
  349. }
  350. }
  351. private void GetHKStatus(string key, Action<object> action)
  352. {
  353. if (ReadHKPLCData.ContainsKey(key))
  354. {
  355. if (ReadHKPLCData[key] != null)
  356. {
  357. action?.Invoke(ReadHKPLCData[key]);
  358. }
  359. }
  360. }
  361. private void GetSiemensStatus(string key, Action<object> action)
  362. {
  363. if (ReadSiemensData.ContainsKey(key))
  364. {
  365. if (ReadSiemensData[key] != null)
  366. {
  367. action?.Invoke(ReadSiemensData[key]);
  368. }
  369. }
  370. }
  371. private void WriteSiemens(string Address, object Value)
  372. {
  373. if (SiemensDevice.IsConnected)
  374. {
  375. SiemensDevice.Siemens_PLC_S7.Write<object>(Address, Value);
  376. }
  377. }
  378. private void WriteHKPLC(string Address, object Value)
  379. {
  380. HKDevice.HK_PLC_S7.Write<object>(Address, Value);
  381. }
  382. private object ReadSiemens(string Address)
  383. {
  384. if (SiemensDevice.IsConnected)
  385. {
  386. return SiemensDevice.Siemens_PLC_S7.Read<object>(Address);
  387. }
  388. else
  389. {
  390. return null;
  391. }
  392. }
  393. private bool[] ReadBoolsSiemens(int address, int count)
  394. {
  395. if (SiemensDevice.IsConnected)
  396. {
  397. return SiemensDevice.Siemens_PLC_S7.ReadBools(address, count);
  398. }
  399. else
  400. {
  401. return null;
  402. }
  403. }
  404. private object ReadHK(string Address)
  405. {
  406. if (HKDevice.IsConnected)
  407. {
  408. return HKDevice.HK_PLC_S7.Read<object>(Address);
  409. }
  410. else
  411. {
  412. return null;
  413. }
  414. }
  415. private bool[] ReadBoolsHK(int address, int count)
  416. {
  417. if (HKDevice.IsConnected)
  418. {
  419. return HKDevice.HK_PLC_S7.ReadBools(address, count);
  420. }
  421. else
  422. {
  423. return null;
  424. }
  425. }
  426. /// <summary>
  427. /// 获取料仓的原料名称和原料位置
  428. /// </summary>
  429. private void ReadPLCDeviceInfo()
  430. {
  431. /*for (int i = 0; i < 12; i++)
  432. {
  433. string RawMaterialName = HKDevice.HK_PLC_S7.Read<string>("");
  434. short RawMaterialLocation = HKDevice.HK_PLC_S7.Read<short>("");
  435. if (RawMaterialsNamePos.ContainsKey(RawMaterialName))
  436. RawMaterialsNamePos.Add(RawMaterialName, RawMaterialLocation);
  437. }*/
  438. }
  439. }
  440. }