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

1956 líneas
119 KiB

  1. using BPA.Message;
  2. using BPASmartClient.CustomResource.Pages.Model;
  3. using BPASmartClient.Helper;
  4. using BPASmartClient.JXJFoodSmallStation.Model.GVL;
  5. using BPASmartClient.JXJFoodSmallStation.Model.HK_PLC;
  6. using BPASmartClient.JXJFoodSmallStation.Model.RawMaterial;
  7. using BPASmartClient.JXJFoodSmallStation.Model.Siemens;
  8. using BPASmartClient.JXJFoodSmallStation.Model.WindSend;
  9. using BPASmartClient.Modbus;
  10. using System;
  11. using System.Collections.Concurrent;
  12. using System.Collections.Generic;
  13. using System.Collections.ObjectModel;
  14. using System.ComponentModel.DataAnnotations;
  15. using System.Configuration;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Threading;
  20. using System.Threading.Tasks;
  21. namespace BPASmartClient.JXJFoodSmallStation.Model
  22. {
  23. public class ProcessControl
  24. {
  25. private volatile static ProcessControl _Instance;
  26. public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl());
  27. private ProcessControl() { }
  28. /// <summary>
  29. /// 配方数据
  30. /// </summary>
  31. public ObservableCollection<RemoteRecipeData> RemoteRecipes = new ObservableCollection<RemoteRecipeData>();
  32. /// <summary>
  33. /// 原料的名称和料仓的位置对应
  34. /// </summary>
  35. public Dictionary<string, short> RawMaterialsNamePos = new Dictionary<string, short>();
  36. public ObservableCollection<RawMaterialStockBin> RawMaterialsInfo => Json<DevicePar>.Data.rawMaterialStockBin;
  37. /// <summary>
  38. /// 配方队列
  39. /// </summary>
  40. public ConcurrentQueue<string> RecipeQueueTray1 = new ConcurrentQueue<string>();
  41. /// <summary>
  42. /// 物料集合
  43. /// </summary>
  44. public Dictionary<int, ConcurrentQueue<string>> RecipeQueueTray { get; set; } = new Dictionary<int, ConcurrentQueue<string>>();
  45. public ConcurrentQueue<string> RecipeQueueTray2 = new ConcurrentQueue<string>();
  46. public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus();
  47. public HKDeviceStatus HKDevice = new HKDeviceStatus();
  48. public WindSendDeviceStatus WindSendDevice = new WindSendDeviceStatus();
  49. public ObservableCollection<PlcInfos> CommData { get; set; } = new ObservableCollection<PlcInfos>();
  50. public ObservableCollection<PlcInfos> ProcessVar { get; set; } = new ObservableCollection<PlcInfos>();
  51. /// <summary>
  52. /// 配方完成信息。
  53. /// </summary>
  54. XL_Finish_DB[] RecipeFinishInfo = new XL_Finish_DB[5];
  55. /// <summary>
  56. /// 风送PLC的DB块
  57. /// </summary>
  58. WindSend_Write WindSendData = new WindSend_Write();
  59. /// <summary>
  60. /// 接收原料数据
  61. /// </summary>
  62. public RecipeRawMaterial RawMaterial;
  63. public DateTime StockBinAlarmTime = DateTime.Now;
  64. public string? HK_PLC_IP = ConfigurationManager.AppSettings["HKPlc_IP"];
  65. public string? Siemens_PLC_IP = ConfigurationManager.AppSettings["Siemens_IP"];
  66. public string? WindSend_PLC_IP = ConfigurationManager.AppSettings["WindSend_IP"];
  67. public void Init()
  68. {
  69. RecipeQueueTray.TryAdd(0, new ConcurrentQueue<string>());
  70. RecipeQueueTray.TryAdd(1, new ConcurrentQueue<string>());
  71. RecipeQueueTray.TryAdd(2, new ConcurrentQueue<string>());
  72. RecipeQueueTray.TryAdd(3, new ConcurrentQueue<string>());
  73. RecipeQueueTray.TryAdd(4, new ConcurrentQueue<string>());
  74. PlcVarMonitor();
  75. StockBinNameWithPos();
  76. RawMaterialNameWithCode();
  77. RegisterInit();
  78. DeviceConnect();
  79. //Json<RemoteRecipeDataColl>.Data.Recipes = TestData.GetInstance.Recipes;//添加测试数据
  80. ThreadManage.GetInstance().StartLong(new Action(() =>
  81. {
  82. GVL_SmallStation.GetInstance.DisEnableStockAlarm = Json<DevicePar>.Data.deviceConnectPar.ShieldStockbinAlarm;
  83. if (HKDevice.IsConnected)
  84. {
  85. GVL_SmallStation.GetInstance.HeartBeatToPlc = !GVL_SmallStation.GetInstance.HeartBeatToPlc;
  86. HKDevice.HK_PLC_S7.Write("DB4.DBX0.0", GVL_SmallStation.GetInstance.HeartBeatToPlc);
  87. GVL_SmallStation.GetInstance.HeartBeatFromPlc = HKDevice.HK_PLC_S7.Read<bool>("DB45.DBX0.0");
  88. if (DeviceInquire.GetInstance.devices.Count < 15 && HKDevice.IsConnected && Json<RemoteRecipeDataColl>.Data.Recipes.Count > 0 && GVL_SmallStation.GetInstance.DisEnableStockBinAlarm == false && DateTime.Now.Subtract(StockBinAlarmTime).TotalSeconds >= 60 & !GVL_SmallStation.GetInstance.DisEnableStockAlarm)
  89. {
  90. HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", true);
  91. App.Current.Dispatcher.Invoke(() =>
  92. {
  93. MessageNotify.GetInstance.ShowDialog($"未读取到15个柔性味魔方料仓", DialogType.Error);
  94. StockBinAlarmTime = DateTime.Now;
  95. });
  96. HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", false);
  97. }
  98. }
  99. Thread.Sleep(200);
  100. }), "海科plc通信心跳", true);
  101. ThreadManage.GetInstance().StartLong(new Action(() =>
  102. {
  103. if (GVL_SmallStation.GetInstance.Order_Cancel)
  104. {
  105. CancelOrder();//订单取消,不执行配方流程
  106. }
  107. else
  108. {
  109. ReceviceData();//配方请求
  110. RecipeInfoToHKPLC();//配方配料
  111. }
  112. Thread.Sleep(10);
  113. }), "小料站流程控制", true);
  114. ThreadManage.GetInstance().StartLong(new Action(() =>
  115. {
  116. RealTimeData();
  117. foreach (var item in Json<DevicePar>.Data.windSendRawMaterial)
  118. {
  119. if (GVL_SmallStation.GetInstance.RawMaterialsNameCode.ContainsKey(item.RawMaterialName))
  120. {
  121. item.RawMaterialChineseName = GVL_SmallStation.GetInstance.RawMaterialsNameCode[item.RawMaterialName];
  122. }
  123. else
  124. {
  125. item.RawMaterialChineseName = "";
  126. }
  127. }
  128. Thread.Sleep(10);
  129. }), "西门子PLC和小料站PLC的实时数据交互流程", true);
  130. ThreadManage.GetInstance().StartLong(new Action(() =>
  131. {
  132. HKPlcRead();
  133. GetStatus();
  134. Thread.Sleep(10);
  135. }), "海科PLC实时数据", true);
  136. }
  137. /// <summary>
  138. /// 气缸的传感器值
  139. /// </summary>
  140. private void GetStatus()
  141. {
  142. for (int i = 0; i < 8; i++)
  143. {
  144. GVL_SmallStation.GetInstance.Cylinder_JackInfo[i] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX0." + i);
  145. }
  146. for (int i = 0; i < 7; i++)
  147. {
  148. GVL_SmallStation.GetInstance.Cylinder_JackInfo[i + 8] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX1." + i);
  149. }
  150. GVL_SmallStation.GetInstance.Cylinder_JackInfo[20] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX3.6");//进料桶气缸
  151. GVL_SmallStation.GetInstance.Cylinder_JackInfo[21] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX3.7");//出料筒气缸1
  152. GVL_SmallStation.GetInstance.Cylinder_JackInfo[22] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.0");//出料筒气缸2
  153. GVL_SmallStation.GetInstance.Cylinder_JackInfo[23] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.1");//出料筒气缸3
  154. GVL_SmallStation.GetInstance.Cylinder_JackInfo[24] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.2");//托盘1_1气缸
  155. GVL_SmallStation.GetInstance.Cylinder_JackInfo[25] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.3");//托盘1_2气缸
  156. GVL_SmallStation.GetInstance.Cylinder_JackInfo[26] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.4");//托盘2_1气缸
  157. GVL_SmallStation.GetInstance.Cylinder_JackInfo[27] = HKDevice.HK_PLC_S7.Read<bool>("DB5.DBX4.5");//托盘2_2气缸
  158. }
  159. /// <summary>
  160. /// DB块的变量实时值
  161. /// </summary>
  162. private void HKPlcRead()
  163. {
  164. if (HKDevice.IsConnected)
  165. {
  166. foreach (PropertyInfo item in typeof(PlcReadAddressDB3).GetProperties())
  167. {
  168. int index = Array.FindIndex(CommData.ToArray(), p => p.Name == item.Name);
  169. if (index >= 0)
  170. {
  171. if (item.PropertyType.IsArray)
  172. {
  173. CommData.ElementAt(index).Value = "";
  174. Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null);
  175. foreach (var values in array)
  176. {
  177. string data = values.ToString();
  178. if (data.ToLower() == "false")
  179. data = "0";
  180. if (data.ToLower() == "true")
  181. data = "1";
  182. CommData.ElementAt(index).Value = CommData.ElementAt(index).Value + data + ",";
  183. }
  184. }
  185. else
  186. {
  187. CommData.ElementAt(index).Value = GVL_SmallStation.GetInstance.plcReadDataDB3.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null).ToString();
  188. }
  189. }
  190. }
  191. }
  192. if (WindSendDevice.IsConnected)
  193. {
  194. foreach (PropertyInfo item in typeof(WindSend_Write).GetProperties())
  195. {
  196. int index = Array.FindIndex(CommData.ToArray(), p => p.Name == item.Name);
  197. if (index >= 0)
  198. {
  199. if (item.PropertyType.IsArray)
  200. {
  201. CommData.ElementAt(index).Value = "";
  202. Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null);
  203. foreach (var values in array)
  204. {
  205. string data = values.ToString();
  206. if (data.ToLower() == "false")
  207. data = "0";
  208. if (data.ToLower() == "true")
  209. data = "1";
  210. CommData.ElementAt(index).Value = CommData.ElementAt(index).Value + data + ",";
  211. }
  212. }
  213. else
  214. {
  215. CommData.ElementAt(index).Value = GVL_SmallStation.GetInstance.WindSendDB95.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance.WindSendDB95, null).ToString();
  216. }
  217. }
  218. }
  219. foreach (PropertyInfo item in typeof(WindSend_Read).GetProperties())
  220. {
  221. int index = Array.FindIndex(CommData.ToArray(), p => p.Name == item.Name);
  222. if (index >= 0)
  223. {
  224. if (item.PropertyType.IsArray)
  225. {
  226. CommData.ElementAt(index).Value = "";
  227. Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null);
  228. foreach (var values in array)
  229. {
  230. string data = values.ToString();
  231. if (data.ToLower() == "false")
  232. data = "0";
  233. if (data.ToLower() == "true")
  234. data = "1";
  235. CommData.ElementAt(index).Value = CommData.ElementAt(index).Value + data + ",";
  236. }
  237. }
  238. else
  239. {
  240. CommData.ElementAt(index).Value = GVL_SmallStation.GetInstance.WindSendDB94.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance.WindSendDB94, null).ToString();
  241. }
  242. }
  243. }
  244. }
  245. foreach (PropertyInfo item in typeof(GVL_SmallStation).GetProperties())
  246. {
  247. int index = Array.FindIndex(ProcessVar.ToArray(), p => p.Name == item.Name);
  248. if (index >= 0)
  249. {
  250. if (item.PropertyType.IsArray)
  251. {
  252. ProcessVar.ElementAt(index).Value = "";
  253. Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance, null);
  254. foreach (var values in array)
  255. {
  256. string data = values.ToString();
  257. if (data.ToLower() == "false")
  258. data = "0";
  259. if (data.ToLower() == "true")
  260. data = "1";
  261. ProcessVar.ElementAt(index).Value = ProcessVar.ElementAt(index).Value + data + ",";
  262. }
  263. }
  264. else
  265. {
  266. ProcessVar.ElementAt(index).Value = GVL_SmallStation.GetInstance.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance, null).ToString();
  267. }
  268. }
  269. }
  270. }
  271. /// <summary>
  272. /// 小料站和西门子PLC之间的实时数据
  273. /// </summary>
  274. private void RealTimeData()
  275. {
  276. if (HKDevice.IsConnected)
  277. {
  278. //获取系统状态
  279. GVL_SmallStation.GetInstance.PlcSystemIsAutoRun = HKDevice.HK_PLC_S7.Read<bool>("DB44.DBX0.0");//系统启停
  280. GVL_SmallStation.GetInstance.PlcSystemMode = HKDevice.HK_PLC_S7.Read<bool>("DB44.DBX0.1");//系统模式
  281. GVL_SmallStation.GetInstance.PlcSystemIsPause = HKDevice.HK_PLC_S7.Read<bool>("DB44.DBX0.2");//系统暂停
  282. GVL_SmallStation.GetInstance.Station1HaveTray = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX40.0");//工站1 有货架
  283. GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[0] = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.0");
  284. GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[1] = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.1");
  285. GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[2] = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.2");
  286. GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[3] = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.3");
  287. GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[4] = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.4");
  288. if (GVL_SmallStation.GetInstance.WindSendDosingComple)
  289. {
  290. //HKDevice.HK_PLC_S7.Write<bool>("DB4.DBX1.7", true);
  291. HKDevice.HK_PLC_S7.Write<bool>("DB4.DBX4.0", true);
  292. GVL_SmallStation.GetInstance.WindSendDosingComple = false;
  293. MessageNotify.GetInstance.ShowRunLog("风送配料完成信号,发给产线plc信号");
  294. }
  295. //if (HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX1.1"))
  296. //{
  297. // HKDevice.HK_PLC_S7.Write<bool>("DB4.DBX1.7", false);
  298. //}
  299. /*if (HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX1.7"))//允许下配方1或者允许下配方2
  300. {
  301. GVL_SmallStation.GetInstance.IsAllowSiemensSendRecipe = true;
  302. }*/
  303. //for (int i = 0; i < 5; i++)
  304. //{
  305. // if (GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[i] && RecipeQueueTray[i].Count == 0)
  306. // {
  307. // GVL_SmallStation.GetInstance.IsAllowSiemensSendRecipe = true;
  308. // }
  309. //}
  310. //GVL_SmallStation.GetInstance.Station1Sensor = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.1");
  311. //GVL_SmallStation.GetInstance.Station2Sensor = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.2");
  312. //GVL_SmallStation.GetInstance.Station1Cylinder = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.3");
  313. //GVL_SmallStation.GetInstance.Station2Cylinder = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX2.4");
  314. //GVL_SmallStation.GetInstance.RobotStatus = HKDevice.HK_PLC_S7.Read<ushort>("DB3.DBW100");
  315. //GVL_SmallStation.GetInstance.RobotProgramNum = HKDevice.HK_PLC_S7.Read<byte>("DB3.DBB102");
  316. if (Json<RemoteRecipeDataColl>.Data.Recipes.Count <= 3)
  317. {
  318. GVL_SmallStation.GetInstance.IsAllowSiemensSendRecipe = true;
  319. }
  320. GVL_SmallStation.GetInstance.Station1Sensor = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX40.1");
  321. GVL_SmallStation.GetInstance.Station1Cylinder = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX40.2");
  322. GVL_SmallStation.GetInstance.RobotStatus = HKDevice.HK_PLC_S7.Read<byte>("DB3.DBB0");
  323. GVL_SmallStation.GetInstance.RobotProgramNum = HKDevice.HK_PLC_S7.Read<byte>("DB3.DBB1");
  324. }
  325. if (SiemensDevice.IsConnected)
  326. {
  327. ushort TrayCylinder = 0;
  328. ushort TraySensor = 0;
  329. if (GVL_SmallStation.GetInstance.Station1Sensor)
  330. {
  331. TraySensor = TraySensor.SetBitValue(1, true);
  332. }
  333. else
  334. {
  335. TraySensor = TraySensor.SetBitValue(0, false);
  336. }
  337. if (!GVL_SmallStation.GetInstance.Station1Cylinder)
  338. {
  339. TrayCylinder = TrayCylinder.SetBitValue(1, true);
  340. }
  341. else
  342. {
  343. TrayCylinder = TrayCylinder.SetBitValue(0, false);
  344. }
  345. this.SiemensDevice.Siemens_PLC_S7.Write<bool>("DB2231.DBX28.4", GVL_SmallStation.GetInstance.WindSendAllowAGVPutGet);
  346. this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW190", TraySensor);//添加工位传感器的信号
  347. this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW192", TrayCylinder);//添加工位气缸的信号
  348. ushort AGV_Put = (ushort)SiemensDevice.XL_Status.AgvFinishPut;
  349. if (AGV_Put.Get16bitValue(1))
  350. {
  351. GVL_SmallStation.GetInstance.AGV_PutTray1Finish = true;
  352. }
  353. else
  354. {
  355. GVL_SmallStation.GetInstance.AGV_PutTray1Finish = false;
  356. }
  357. ushort AGV_Get = (ushort)SiemensDevice.XL_Status.AgvFinishGet;
  358. if (AGV_Get.Get16bitValue(1))
  359. {
  360. GVL_SmallStation.GetInstance.AGV_GetTray1Finish = true;
  361. }
  362. else
  363. {
  364. GVL_SmallStation.GetInstance.AGV_GetTray1Finish = false;
  365. }
  366. }
  367. }
  368. public void CancelOrder()
  369. {
  370. if (GVL_SmallStation.GetInstance.Order_Cancel) //订单取消
  371. {
  372. if (!string.IsNullOrEmpty(GVL_SmallStation.GetInstance.Order_CancelRecipeCode))
  373. {
  374. string code = GVL_SmallStation.GetInstance.Order_CancelRecipeCode;
  375. //index是在远程配方集合文件中,该配方所在位置索引。
  376. int index = Array.FindIndex(Json<RemoteRecipeDataColl>.Data.Recipes.ToArray(), p => p.RecipeCode == code);
  377. int[] cnt = new int[5] { -1, -1, -1, -1, -1 };
  378. //index1 是在五个配方队列中,该配方所在的配方队列的key。
  379. int index1 = -1;
  380. for (int i = 0; i < 5; i++)
  381. {
  382. cnt[i] = Array.FindIndex(RecipeQueueTray[i].ToArray(), p => p == code);
  383. if (cnt[i] >= 0)
  384. {
  385. index1 = i;
  386. }
  387. }
  388. switch (GVL_SmallStation.GetInstance.OrderCancelStep)
  389. {
  390. case 0://前提条件判断
  391. if (index == -1)
  392. {
  393. GVL_SmallStation.GetInstance.OrderCancelStep = 30;
  394. MessageNotify.GetInstance.ShowRunLog($"远程配方集合中并未找到订单配方号:【{code}】");
  395. }
  396. else
  397. {
  398. if (index1 >= 0)
  399. {
  400. //在配方执行列表中找到此配方。
  401. GVL_SmallStation.GetInstance.OrderCancelStep = 1;
  402. }
  403. //在远程配方集合的文件中找到了,但是没在配方队列中找到。
  404. else
  405. {
  406. GVL_SmallStation.GetInstance.OrderCancelStep = 20;
  407. }
  408. }
  409. break;
  410. //Case 1-9为
  411. case 1:
  412. if (GVL_SmallStation.GetInstance.RecipeProcessStatus[index1] != 0)
  413. {
  414. GVL_SmallStation.GetInstance.RecipeProcessStatus[index1] = 0;
  415. HKDevice.HK_PLC_S7.Write("DB4.DBX6." + index1, true);
  416. MessageNotify.GetInstance.ShowRunLog($"PLC正在执行配料流程,正在申请取消订单:{code}。配方流程状态【{index1}】已经清零。");
  417. GVL_SmallStation.GetInstance.OrderCancelStep = 2;
  418. }
  419. else
  420. {
  421. MessageNotify.GetInstance.ShowRunLog($"AGV未到达工站前,未给plc下发配方,取消订单:{code}");
  422. GVL_SmallStation.GetInstance.OrderCancelStep = 3;
  423. }
  424. break;
  425. case 2:
  426. //2023年8月18日: PLC无取消订单反馈,直接发送取消订单的BOOL量即可。
  427. //if (HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX42." + index1))
  428. {
  429. if (GVL_SmallStation.GetInstance.Station1Cylinder == false)
  430. {
  431. GVL_SmallStation.GetInstance.OrderCancelStep = 3;
  432. HKDevice.HK_PLC_S7.Write("DB4.DBX6." + index1, false);
  433. //MessageNotify.GetInstance.ShowRunLog($"PLC正在执行配料流程,取消订单:{code}");
  434. MessageNotify.GetInstance.ShowRunLog($"检测到配料PLC工位气缸信号为False,已取消订单:【{code}】");
  435. }
  436. }
  437. break;
  438. case 3:
  439. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true);
  440. MessageNotify.GetInstance.ShowRunLog($"向主控PLC写入订单取消确认信号。");
  441. GVL_SmallStation.GetInstance.OrderCancelStep = 4;
  442. break;
  443. case 4:
  444. if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false)
  445. {
  446. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false);
  447. GVL_SmallStation.GetInstance.OrderCancelStep = 9;
  448. MessageNotify.GetInstance.ShowRunLog($"检测到主控PLC的【DB2201.DBX440.1】为False,已向主控PLC写入订单取消确认信号为False。配方队列【{index1+1}】,西门子取消订单【{code}】完成。");
  449. }
  450. break;
  451. case 9:
  452. App.Current.Dispatcher.Invoke(() =>
  453. {
  454. Json<RemoteRecipeDataColl>.Data.Recipes.RemoveAt(index);
  455. });
  456. //RecipeQueueTray1.TryDequeue(out code);
  457. if (RecipeQueueTray[index1].TryDequeue(out _))
  458. {
  459. MessageNotify.GetInstance.ShowRunLog($"已从配方队列【{index1+1}】移除配方:【{code}】。");
  460. }
  461. else
  462. {
  463. MessageNotify.GetInstance.ShowRunLog($"从配方队列【{index1 + 1}】移除配方:【{code}】失败。");
  464. }
  465. GVL_SmallStation.GetInstance.RecipeProcessStatus[index1] = 0;
  466. GVL_SmallStation.GetInstance.Order_Cancel = false;
  467. GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
  468. GVL_SmallStation.GetInstance.OrderCancelStep = 0;
  469. MessageNotify.GetInstance.ShowRunLog($"取消订单流程结束,已复位流程相关变量。");
  470. break;
  471. case 20:
  472. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true);
  473. GVL_SmallStation.GetInstance.OrderCancelStep = 21;
  474. break;
  475. case 21:
  476. if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false)
  477. {
  478. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false);
  479. GVL_SmallStation.GetInstance.OrderCancelStep = 29;
  480. MessageNotify.GetInstance.ShowRunLog($"队列1,西门子取消订单完成,订单号:{code}");
  481. }
  482. break;
  483. case 29:
  484. App.Current.Dispatcher.Invoke(() =>
  485. {
  486. Json<RemoteRecipeDataColl>.Data.Recipes.RemoveAt(index);
  487. });
  488. GVL_SmallStation.GetInstance.Order_Cancel = false;
  489. GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
  490. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 0;
  491. GVL_SmallStation.GetInstance.OrderCancelStep = 0;
  492. break;
  493. //30-39为订单还未下发至上位机
  494. case 30:
  495. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true);
  496. GVL_SmallStation.GetInstance.OrderCancelStep = 31;
  497. break;
  498. case 31:
  499. if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false)
  500. {
  501. SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false);
  502. GVL_SmallStation.GetInstance.OrderCancelStep = 39;
  503. MessageNotify.GetInstance.ShowRunLog($"西门子取消订单完成,订单号:{code}");
  504. }
  505. break;
  506. case 39:
  507. GVL_SmallStation.GetInstance.Order_Cancel = false;
  508. GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
  509. GVL_SmallStation.GetInstance.OrderCancelStep = 0;
  510. break;
  511. }
  512. }
  513. }
  514. }
  515. /// <summary>
  516. /// 将配方添加到配方队列中
  517. /// </summary>
  518. private void ReceviceData()
  519. {
  520. if (!GVL_SmallStation.GetInstance.IsUseLocalRecipe)
  521. {
  522. RemoteRecipes = Json<RemoteRecipeDataColl>.Data.Recipes;
  523. if (RemoteRecipes.Count > 0)
  524. {
  525. foreach (var data in RemoteRecipes)
  526. {
  527. if (data.TrayCode == 1 &&!IsInQueue(data.RecipeCode))
  528. {
  529. if (SiemensDevice.XL_Status is XL_Status_DB status)
  530. {
  531. switch (GVL_SmallStation.GetInstance.SiemensSendRecipeStatus)
  532. {
  533. case 3:
  534. SiemensDevice.Siemens_PLC_S7.WriteString(2231, data.RecipeCode, 10);
  535. SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", true);
  536. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 4;
  537. MessageNotify.GetInstance.ShowRunLog($"配方【{data.RecipeCode}】,请求配料");
  538. break;
  539. case 4:
  540. if (SiemensDevice.XL_Status.Dosing_Confirm)
  541. {
  542. SiemensDevice.Siemens_PLC_S7.WriteString(2231, "", 10);//复位字符串
  543. SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", false);
  544. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 5;
  545. MessageNotify.GetInstance.ShowRunLog($"配方【{data.RecipeCode}】,西门子确认配料");
  546. }
  547. break;
  548. case 5:
  549. if (SiemensDevice.XL_Status.Dosing_Confirm == false)
  550. {
  551. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 6;
  552. MessageNotify.GetInstance.ShowRunLog($"配方【{data.RecipeCode}】,西门子确认配料信号复位完成");
  553. }
  554. break;
  555. case 6:
  556. //TODO:这里多订单时可能需要修改为i<2,大于等于2的情况下 无法下发配方到配料PLC。。
  557. for (int i = 0; i < 5; i++)
  558. {
  559. if (GVL_SmallStation.GetInstance.NotUseSmallStation)
  560. {
  561. if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
  562. {
  563. RecipeQueueTray[i].Enqueue(data.RecipeCode);
  564. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 0;
  565. MessageNotify.GetInstance.ShowRunLog($"西门子配方配料 ,不使用小料配料,配方ID:【{data.RecipeCode}】,加入配方队列【{i+1}】");
  566. break;
  567. }
  568. }
  569. else if (GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[i])
  570. {
  571. if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
  572. {
  573. RecipeQueueTray[i].Enqueue(data.RecipeCode);
  574. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 0;
  575. MessageNotify.GetInstance.ShowRunLog($"西门子配方配料 ,等待PLC允许配料,配方ID:【{data.RecipeCode}】,加入配方队列【{i+1}】");
  576. break;
  577. }
  578. }
  579. }
  580. break;
  581. default:
  582. break;
  583. }
  584. }
  585. }
  586. }
  587. }
  588. else
  589. {
  590. for (int i = 0; i < 5; i++)
  591. {
  592. RecipeQueueTray[i].Clear();
  593. GVL_SmallStation.GetInstance.RecipeProcessStatus[i] = 0;
  594. }
  595. GVL_SmallStation.GetInstance.WindSendDosingStatus = 0;
  596. GVL_SmallStation.GetInstance.WindSendDosing = false;
  597. }
  598. }
  599. else
  600. {
  601. RemoteRecipes = Json<RemoteRecipeDataColl>.Data.Recipes;
  602. if (RemoteRecipes.Count > 0)
  603. {
  604. foreach (var data in RemoteRecipes)
  605. {
  606. if (data.TrayCode == 1)
  607. {
  608. for (int i = 0; i < 5; i++)
  609. {
  610. if (GVL_SmallStation.GetInstance.NotUseSmallStation)
  611. {
  612. if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
  613. {
  614. RecipeQueueTray[i].Enqueue(data.RecipeCode);
  615. MessageNotify.GetInstance.ShowRunLog($"本地配方配料 ,不使用小料配料,配方ID:【{data.RecipeCode}】,加入配方队列【{i}】");
  616. }
  617. }
  618. else if (GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[i])
  619. {
  620. if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
  621. {
  622. RecipeQueueTray[i].Enqueue(data.RecipeCode);
  623. MessageNotify.GetInstance.ShowRunLog($"本地配方配料 ,等待PLC允许配料,配方ID:【{data.RecipeCode}】,加入配方队列【{i}】");
  624. }
  625. }
  626. }
  627. }
  628. }
  629. }
  630. else
  631. {
  632. for (int i = 0; i < 5; i++)
  633. {
  634. RecipeQueueTray[i].Clear();
  635. GVL_SmallStation.GetInstance.RecipeProcessStatus[i] = 0;
  636. }
  637. GVL_SmallStation.GetInstance.WindSendDosingStatus = 0;
  638. GVL_SmallStation.GetInstance.WindSendDosing = false;
  639. }
  640. }
  641. }
  642. /// <summary>
  643. /// 小料站配料
  644. /// </summary>
  645. private void RecipeInfoToHKPLC()
  646. {
  647. #region AGV信号交互
  648. if (!GVL_SmallStation.GetInstance.NotUseSmallStation)
  649. {
  650. //2023-8-18:i<5--> i<1 。只有一个工位,只发一个工位的信号即可。
  651. for (int i = 0; i < 1; i++)
  652. {
  653. switch (GVL_SmallStation.GetInstance.Tray_AGVLogic[i])
  654. {
  655. case 0:
  656. if (GVL_SmallStation.GetInstance.AGV_PutTray1Finish /*&& (RecipeQueueTray[i].Count > 0) && GVL_SmallStation.GetInstance.AGVIsGetTray == false*/)
  657. {
  658. GVL_SmallStation.GetInstance.AGVIsGetTray = true;
  659. HKDevice.HK_PLC_S7.Write("DB4.DBX8." + i, true);
  660. GVL_SmallStation.GetInstance.AGV_PutTray1Finish = false;
  661. GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 1;
  662. MessageNotify.GetInstance.ShowRunLog($"AGV到位,发送到位信号【{"DB4.DBX8." + i}】给PLC。");
  663. }
  664. break;
  665. case 1:
  666. if (GVL_SmallStation.GetInstance.Station1HaveTray)
  667. {
  668. HKDevice.HK_PLC_S7.Write("DB4.DBX8." + i, false);
  669. GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 2;
  670. MessageNotify.GetInstance.ShowRunLog($"海科PLC写入货架信号【{"DB4.DBX8." + i}】托盘【{1}】有货架");
  671. }
  672. break;
  673. case 2:
  674. //2023-8-18:注释。
  675. if (GVL_SmallStation.GetInstance.AGV_GetTray1Finish/* && GVL_SmallStation.GetInstance.RecipeProcessStatus[i] == 0*/)
  676. {
  677. GVL_SmallStation.GetInstance.AGVIsGetTray = false;
  678. HKDevice.HK_PLC_S7.Write("DB4.DBX10." + i, true);
  679. GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 3;
  680. MessageNotify.GetInstance.ShowRunLog($"AGV取托盘【{1}】完成,发送给小料配料PLC的取托盘完成【{"DB4.DBX10." + i}】信号1s后复位。");
  681. }
  682. break;
  683. case 3:
  684. //if (HKDevice.HK_PLC_S7.Read<bool>("DB4.DBX10." + i) == true)
  685. {
  686. Thread.Sleep(1000);
  687. HKDevice.HK_PLC_S7.Write("DB4.DBX10." + i, false);
  688. GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 0;
  689. GVL_SmallStation.GetInstance.AGV_GetTray1Finish = false;
  690. MessageNotify.GetInstance.ShowRunLog($"AGV取托盘【{1}】完成,信号【{"DB4.DBX10." + i}】复位。");
  691. }
  692. break;
  693. default:
  694. break;
  695. }
  696. }
  697. }
  698. #endregion
  699. foreach (var recipe in RecipeQueueTray)
  700. {
  701. int recipeNum = recipe.Key;
  702. if (RecipeQueueTray[recipeNum].Count > 0)
  703. {
  704. int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueueTray[recipeNum].ElementAt(0));
  705. if (index >= 0 && index < RemoteRecipes.Count)
  706. {
  707. string code = RemoteRecipes.ElementAt(index).RecipeCode;
  708. int trayCode = RemoteRecipes.ElementAt(index).TrayCode;
  709. string recipeName = RemoteRecipes.ElementAt(index).RecipeName;
  710. string windSend = RemoteRecipes.ElementAt(index).ToString();
  711. if (trayCode == 1)
  712. {
  713. #region 未使用小料站的情况下配料
  714. if (GVL_SmallStation.GetInstance.NotUseSmallStation)
  715. {
  716. if (GVL_SmallStation.GetInstance.AGV_PutTray1Finish)
  717. {
  718. Thread.Sleep(5000);
  719. var res = Json<RemoteRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code);
  720. if (RemoteRecipes.ElementAt(index).RecipesSource == RecipeSource.远程 /*!GVL_SmallStation.GetInstance.IsUseLocalRecipe*/)
  721. {
  722. RecipeFinishInfo[recipeNum].Order_No = RemoteRecipes.ElementAt(index).RecipeCode;
  723. RecipeFinishInfo[recipeNum].Product_Code = RemoteRecipes.ElementAt(index).RecipeName;
  724. RecipeFinishInfo[recipeNum].Job_No = (short)trayCode;
  725. for (int i = 0; i < 20; i++)
  726. {
  727. RecipeFinishInfo[recipeNum].Material[i] = new UDT1();
  728. }
  729. for (int i = 0; i < 10; i++)
  730. {
  731. RecipeFinishInfo[recipeNum].Powder[i] = new UDT2();
  732. }
  733. for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++)
  734. {
  735. RecipeFinishInfo[recipeNum].Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName;
  736. RecipeFinishInfo[recipeNum].Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum;
  737. RecipeFinishInfo[recipeNum].Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001;
  738. }
  739. for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++)
  740. {
  741. RecipeFinishInfo[recipeNum].Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight;
  742. }
  743. RecipeFinishInfo[recipeNum].Ask_For_Finish = true;
  744. RecipeFinishInfo[recipeNum].DosingTime = Convert.ToInt16(0);
  745. MessageNotify.GetInstance.ShowRunLog($"托盘【{trayCode}】,配方【{res.RecipeCode}】,配料完成,开始写入反馈数据。");
  746. SendDataOperation(() =>
  747. {
  748. SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo[recipeNum], 2261);
  749. }, () =>
  750. {
  751. return SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2261.DBX0.0");
  752. });
  753. MessageNotify.GetInstance.ShowRunLog($"托盘【{trayCode}】,配方【{res.RecipeCode}】,配料完成反馈数据写入成功,西门子已确认。");
  754. var result= SiemensDevice.Siemens_PLC_S7.Write<bool>("DB2261.DBX450.0", false,5);
  755. if (!string.IsNullOrEmpty(result) && result.Contains("成功"))
  756. {
  757. MessageNotify.GetInstance.ShowRunLog($"托盘【{trayCode}】,配方【{res.RecipeCode}】,配料完成信号写入复位。");
  758. }
  759. else
  760. {
  761. MessageNotify.GetInstance.ShowRunLog($"托盘【{trayCode}】,配方【{res.RecipeCode}】,配料完成,已发送数据,但复位请求完成信号失败。");
  762. }
  763. //SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo[recipeNum], 2261);
  764. }
  765. else
  766. {
  767. MessageNotify.GetInstance.ShowRunLog($"托盘【{trayCode}】,配方【{res.RecipeCode}】,本地配方配料完成,不反馈完成数据至西门子。");
  768. }
  769. GVL_SmallStation.GetInstance.WindSendDosing = false;
  770. App.Current.Dispatcher.Invoke(() =>
  771. {
  772. Json<RemoteRecipeDataColl>.Data.Recipes.Remove(res);
  773. });
  774. RecipeQueueTray[recipeNum].TryDequeue(out code);
  775. GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0;
  776. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 0;
  777. }
  778. }
  779. #endregion
  780. else
  781. {
  782. //粉料仓下发配方
  783. #region 粉料仓配料
  784. if (GVL_SmallStation.GetInstance.IsUseWindSend && GVL_SmallStation.GetInstance.WindSendDosing == false && RemoteRecipes.ElementAt(index).WindSend.Count != 0 /*&& GVL_SmallStation.GetInstance.Tray_AGVLogic[recipeNum] == 2*/)
  785. {
  786. if (WindSendDevice.IsConnected)
  787. {
  788. if (GVL_SmallStation.GetInstance.WindSendDosingStatus == 1)
  789. {
  790. WindSend_Write WindSendData111 = new WindSend_Write();
  791. WindSendDevice.Siemens_PLC_S7.WriteClass<WindSend_Write>(WindSendData111, 95);
  792. Thread.Sleep(200);
  793. WindSendData111.TargetRecipeCode = code;
  794. WindSendData111.IsAllowDosing = true;
  795. MessageNotify.GetInstance.ShowRunLog($"开始写入风送料仓配方【{code}】。");
  796. foreach (var item in RemoteRecipes.ElementAt(index).WindSend)
  797. {
  798. if (item.RawMaterialName == Json<DevicePar>.Data.windSendRawMaterial.ElementAt(0).RawMaterialName || item.Location == 1)
  799. {
  800. WindSendData111.RawMaterial1_SetWeight = item.RawMaterialWeight;
  801. MessageNotify.GetInstance.ShowRunLog($"风送料仓【{item.RawMaterialName}】,设定重量【{item.RawMaterialWeight}】");
  802. continue;
  803. }
  804. if (item.RawMaterialName == Json<DevicePar>.Data.windSendRawMaterial.ElementAt(1).RawMaterialName || item.Location == 2)
  805. {
  806. WindSendData111.RawMaterial2_SetWeight = item.RawMaterialWeight;
  807. MessageNotify.GetInstance.ShowRunLog($"风送料仓【{item.RawMaterialName}】,设定重量【{item.RawMaterialWeight}】");
  808. continue;
  809. }
  810. if (item.RawMaterialName == Json<DevicePar>.Data.windSendRawMaterial.ElementAt(2).RawMaterialName || item.Location == 3)
  811. {
  812. WindSendData111.RawMaterial3_SetWeight = item.RawMaterialWeight;
  813. MessageNotify.GetInstance.ShowRunLog($"风送料仓【{item.RawMaterialName}】,设定重量【{item.RawMaterialWeight}】");
  814. continue;
  815. }
  816. if (item.RawMaterialName == Json<DevicePar>.Data.windSendRawMaterial.ElementAt(3).RawMaterialName || item.Location == 4)
  817. {
  818. WindSendData111.RawMaterial4_SetWeight = item.RawMaterialWeight;
  819. MessageNotify.GetInstance.ShowRunLog($"风送料仓【{item.RawMaterialName}】,设定重量【{item.RawMaterialWeight}】");
  820. continue;
  821. }
  822. if (item.RawMaterialName == Json<DevicePar>.Data.windSendRawMaterial.ElementAt(4).RawMaterialName || item.Location == 5)
  823. {
  824. WindSendData111.RawMaterial5_SetWeight = item.RawMaterialWeight;
  825. MessageNotify.GetInstance.ShowRunLog($"风送料仓【{item.RawMaterialName}】,设定重量【{item.RawMaterialWeight}】");
  826. continue;
  827. }
  828. }
  829. WindSendDevice.Siemens_PLC_S7.WriteClass<WindSend_Write>(WindSendData111, 95);
  830. GVL_SmallStation.GetInstance.WindSendDosing = true;
  831. GVL_SmallStation.GetInstance.WindSendDosingStatus = 2;
  832. MessageNotify.GetInstance.ShowRunLog($"风送系统配方【{code}】写入完成。");
  833. }
  834. }
  835. else
  836. {
  837. if (Delay.GetInstance("delayTime").Start(true, 60))
  838. {
  839. Delay.GetInstance("delayTime").Start(false, 60);
  840. MessageNotify.GetInstance.ShowRunLog($"风送设备PLC未连接");
  841. }
  842. }
  843. }
  844. #endregion
  845. if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 0)
  846. {
  847. GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0;
  848. #region 向配料PLC下发配方数据。
  849. HKDevice.IssueRecipeToPlc(RemoteRecipes.ElementAt(index).RawMaterial, recipeNum);
  850. //2023.8.16:如果没有粉料仓需要配料的数据,发送一下信号给配料PLC判断粉料仓完成。
  851. if (RemoteRecipes.ElementAt(index).WindSend.Count==0)
  852. {
  853. HKDevice.HK_PLC_S7.Write<bool>("DB4.DBX44."+recipeNum, true);
  854. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号【{code}】,配方号【{recipeNum + 1}】,该配方无风送料,已向配料PLC下发信号。");
  855. }
  856. HKDevice.HK_PLC_S7.Write("DB4.DBX2." + recipeNum, true);
  857. #endregion
  858. GVL_SmallStation.GetInstance.DosingTime[recipeNum] = DateTime.Now;
  859. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 1;
  860. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号【{code}】,配方号【{recipeNum + 1}】,下发完成");
  861. }
  862. //等待配料PLC反馈配方收到。
  863. bool recipeReceviceFinish = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX4." + recipeNum);
  864. if (recipeReceviceFinish && GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 1)
  865. {
  866. HKDevice.HK_PLC_S7.Write("DB4.DBX2." + recipeNum, false);
  867. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 2;
  868. GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = 0;
  869. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号【{code}】,配方号【{recipeNum + 1}】,配方接收完成");
  870. }
  871. //如果没检测到,配方接收完成信号,是否应该返回第0步 下发。
  872. else
  873. {
  874. }
  875. if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 2)
  876. {
  877. #region 味魔方配料,并验证误差。
  878. for (byte i = 1; i < 16; i++)
  879. {
  880. int indexArr = -1;
  881. if (GVL_SmallStation.GetInstance.plcReadDataDB3.StockBinAllowIssue[i - 1])
  882. {
  883. switch (recipeNum)
  884. {
  885. case 0:
  886. indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe1BarrelPosReserve.ToArray(), p => p == i);
  887. break;
  888. case 1:
  889. indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe2BarrelPosReserve.ToArray(), p => p == i);
  890. break;
  891. case 2:
  892. indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe3BarrelPosReserve.ToArray(), p => p == i);
  893. break;
  894. case 3:
  895. indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe4BarrelPosReserve.ToArray(), p => p == i);
  896. break;
  897. case 4:
  898. indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe5BarrelPosReserve.ToArray(), p => p == i);
  899. break;
  900. }
  901. if (indexArr >= 0 && GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].Get16bitValue((byte)i) == false)
  902. {
  903. int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
  904. float weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeight * 1000;//单位g转换kg
  905. if (weight <= 0)
  906. {
  907. if (i >= 1 && i <= 8)
  908. {
  909. string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX12." + (i - 1), true);
  910. MessageNotify.GetInstance.ShowRunLog(commInfo);
  911. }
  912. else if (i >= 9 && i <= 15)
  913. {
  914. string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX13." + (i - 9), true);
  915. MessageNotify.GetInstance.ShowRunLog(commInfo1);
  916. }
  917. GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].SetBitValue((byte)i, false);//配料完成设备写成false
  918. GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].SetBitValue((byte)i, true);//配料完成设备写成false
  919. }
  920. else
  921. {
  922. if (loc_index >= 0)
  923. {
  924. DeviceInquire.GetInstance.GetDevice((int)i)?.Start(weight);//根据料仓编号 启动并写入每个原料重量
  925. GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].SetBitValue((byte)i, true);//配料完成设备写成false
  926. }
  927. else
  928. {
  929. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号:{code},配方号{recipeNum + 1},{indexArr + 1}号桶,错误没有找到{(int)i}号仓的配方");
  930. }
  931. }
  932. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号:{code},配方号{recipeNum + 1},{indexArr + 1}号桶,{(int)i}号仓,正在配料");
  933. }
  934. else
  935. {
  936. //MessageNotify.GetInstance.ShowRunLog($"错误,有允许配料信号,但没有相应的位置 和桶号");
  937. }
  938. if ((DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3) && indexArr >= 0 && GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].Get16bitValue((byte)i))
  939. {
  940. int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i);
  941. if (res < 0)
  942. {
  943. }
  944. else
  945. {
  946. Thread.Sleep(GVL_SmallStation.GetInstance.Time);
  947. RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.NowWeightFeedback;
  948. bool info = DeviceInquire.GetInstance.GetDevice(i).StatusReset();
  949. MessageNotify.GetInstance.ShowRunLog($"柔性味魔方,托盘1,配方:{recipeName},{i}号仓,配料完成,下料完成重量:{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight}");
  950. float AlarmRange = Math.Abs(RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight - RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).RawMaterialWeight * 1000);
  951. int iIndex = Array.FindIndex(Json<DevicePar>.Data.deviceParModels.ToArray(), p => p.MaterialName == DeviceInquire.GetInstance.GetDevice(i).DeviceName);
  952. if (iIndex >= 0)
  953. {
  954. if (Math.Abs(Json<DevicePar>.Data.deviceParModels.ElementAt(iIndex).ErrorRange) < AlarmRange)
  955. {
  956. HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", true);
  957. App.Current.Dispatcher.Invoke(() =>
  958. {
  959. MessageNotify.GetInstance.ShowDialog($"{i}号仓配料误差过大,设置出料重量{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).RawMaterialWeight * 1000}g,实际出料重量{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight}g,相差{AlarmRange}g,允许误差为{Math.Abs(Json<DevicePar>.Data.deviceParModels.ElementAt(iIndex).ErrorRange)}g,请联系人工处理", DialogType.Warning);
  960. HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", false);
  961. });
  962. }
  963. }
  964. if (i >= 1 && i <= 8)
  965. {
  966. string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX12." + (i - 1), true);
  967. MessageNotify.GetInstance.ShowRunLog(commInfo);
  968. }
  969. else if (i >= 9 && i <= 15)
  970. {
  971. string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX13." + (i - 9), true);
  972. MessageNotify.GetInstance.ShowRunLog(commInfo1);
  973. }
  974. GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].SetBitValue((byte)i, false);//配料完成设备写成false
  975. MessageNotify.GetInstance.ShowRunLog($"配方队列:【{recipeNum + 1}】,配方ID:【{code}】,{GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].ToBinString()}");
  976. }
  977. }
  978. }
  979. }
  980. #endregion
  981. //等待配料PLC反馈配料完成信号。
  982. var completedSingleAddr = "DB3.DBX6." + recipeNum;
  983. bool DosingComple = HKDevice.HK_PLC_S7.Read<bool>(completedSingleAddr);
  984. var dosingCompleTrig = RTrig.GetInstance("配方配料完成").Start(DosingComple);
  985. //2023-8-18:删除通过小料仓下发情况和配料完成信号判断配料完成。只通过配料完成上升沿且配料下发有仓完成过作为判断配料结束信号。
  986. if (GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] > 0 && dosingCompleTrig /*&& DosingComple)*/)
  987. {
  988. MessageNotify.GetInstance.ShowRunLog($"接收到配料PLC配料完成信号【{completedSingleAddr}】上升沿,配方ID:【{code}】,配方队列【{recipeNum + 1}】。");
  989. GVL_SmallStation.GetInstance.RecipeDosingCompleNum = GVL_SmallStation.GetInstance.RecipeDosingCompleNum + 1;
  990. GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = 0;
  991. if (GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] > 0)
  992. {
  993. for (int i = 1; i < 17; i++)
  994. {
  995. if (GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].Get16bitValue((byte)i))
  996. {
  997. MessageNotify.GetInstance.ShowRunLog($"配方ID:【{code}】,配方队列【{recipeNum + 1}】,料仓配料完成,但存在料仓未配料:{i}号仓");
  998. }
  999. }
  1000. }
  1001. foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial)
  1002. {
  1003. MessageNotify.GetInstance.ShowRunLog($"配方ID:【{code}】:【{item.RawMaterialName}】,下料重量:【{item.Laying_Off_Weight}】g");
  1004. }
  1005. #region 生成配方完成数据。
  1006. if (RemoteRecipes.ElementAt(index).RecipesSource == RecipeSource.远程 /*!GVL_SmallStation.GetInstance.IsUseLocalRecipe*/)
  1007. {
  1008. double totalMakeTime = DateTime.Now.Subtract(GVL_SmallStation.GetInstance.DosingTime[recipeNum]).TotalSeconds;
  1009. RecipeFinishInfo[recipeNum] = new();
  1010. RecipeFinishInfo[recipeNum].Order_No = RemoteRecipes.ElementAt(index).RecipeCode;
  1011. RecipeFinishInfo[recipeNum].Product_Code = RemoteRecipes.ElementAt(index).RecipeName;
  1012. RecipeFinishInfo[recipeNum].Job_No = (short)trayCode;
  1013. for (int i = 0; i < 20; i++)
  1014. {
  1015. RecipeFinishInfo[recipeNum].Material[i] = new UDT1();
  1016. }
  1017. for (int i = 0; i < 10; i++)
  1018. {
  1019. RecipeFinishInfo[recipeNum].Powder[i] = new UDT2();
  1020. }
  1021. for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++)
  1022. {
  1023. RecipeFinishInfo[recipeNum].Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName;
  1024. RecipeFinishInfo[recipeNum].Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum;
  1025. RecipeFinishInfo[recipeNum].Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001;
  1026. }
  1027. for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++)
  1028. {
  1029. RecipeFinishInfo[recipeNum].Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight;
  1030. }
  1031. RecipeFinishInfo[recipeNum].Ask_For_Finish = true;
  1032. RecipeFinishInfo[recipeNum].DosingTime = Convert.ToInt16(totalMakeTime);
  1033. //SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo[recipeNum], 2261);
  1034. //MessageNotify.GetInstance.ShowRunLog($"托盘1,配方【{res.RecipeCode}】,配料完成,数据反馈给西门子");
  1035. //MessageNotify.GetInstance.ShowRecipeLog($"配方名称:【{res.RecipeName}】\t 配方号:【{res.RecipeCode}】");
  1036. }
  1037. //else
  1038. //{
  1039. // MessageNotify.GetInstance.ShowRunLog($"托盘1,配方【{res.RecipeCode}】,配料完成,数据无法反馈给西门子,西门子设备未连接或处于本地配方");
  1040. // MessageNotify.GetInstance.ShowRecipeLog($"配方名称:【{res.RecipeName}】\t 配方号:【{res.RecipeCode}】");
  1041. //}
  1042. #endregion
  1043. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 30;
  1044. }
  1045. }
  1046. #region 发送完成数据
  1047. if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 30)
  1048. {
  1049. //如果不是远程配方,不需要发送,直接进入下一步。
  1050. if (RemoteRecipes.ElementAt(index).RecipesSource == RecipeSource.远程)
  1051. {
  1052. //如果MES没连接,直接不发送 等待连接上。
  1053. if (SiemensDevice.IsConnected)
  1054. {
  1055. //发送完成 确认MES已经收到了。
  1056. //TODO:多配方队列单反馈变量,不知道到时候会不会有数据抢占的现象。
  1057. if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2261.DBX0.0"))
  1058. {
  1059. CleanFinishData(recipeNum);
  1060. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 40;
  1061. //SiemensDevice.Siemens_PLC_S7.Write<bool>("DB2261.DBX450.0", false);
  1062. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方【{code}】,MES系统确认收到完成数据。");
  1063. }
  1064. else
  1065. {
  1066. SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo[recipeNum], 2261);
  1067. Thread.Sleep(3000);
  1068. }
  1069. }
  1070. }
  1071. else
  1072. {
  1073. MessageNotify.GetInstance.ShowRunLog($"托盘1,配方【{code}】,配料完成,为本地配方,不发送完成数据。");
  1074. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 40;
  1075. }
  1076. }
  1077. #endregion
  1078. #region 发送完成数据完成,清理本地流程数据。
  1079. if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 40)
  1080. {
  1081. var res = Json<RemoteRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code);
  1082. GVL_SmallStation.GetInstance.WindSendDosing = false;
  1083. App.Current.Dispatcher.Invoke(() =>
  1084. {
  1085. Json<RemoteRecipeDataColl>.Data.Recipes.Remove(res);
  1086. });
  1087. RecipeQueueTray[recipeNum].TryDequeue(out code);
  1088. GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0;
  1089. GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 0;
  1090. MessageNotify.GetInstance.ShowRecipeLog($"配方名称:【{res.RecipeName}】\t 配方号:【{res.RecipeCode}】");
  1091. MessageNotify.GetInstance.ShowRunLog($"配方【{code}】,配料流程完成。");
  1092. }
  1093. #endregion
  1094. }
  1095. }
  1096. }
  1097. }
  1098. }
  1099. }
  1100. private void StockBinInit()
  1101. {
  1102. for (int i = 1; i < 16; i++)
  1103. {
  1104. if (DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3)
  1105. {
  1106. DeviceInquire.GetInstance.GetDevice(i).StatusReset();
  1107. }
  1108. }
  1109. }
  1110. /// <summary>
  1111. /// 料仓的位置和原料名称的对应
  1112. /// </summary>
  1113. public void StockBinNameWithPos()
  1114. {
  1115. RawMaterialsNamePos.Clear();
  1116. foreach (var material in RawMaterialsInfo)
  1117. {
  1118. if (!string.IsNullOrEmpty(material.RawMaterialName))
  1119. {
  1120. if (!RawMaterialsNamePos.ContainsKey(material.RawMaterialName))
  1121. {
  1122. RawMaterialsNamePos.Add(material.RawMaterialName, (short)material.RawMaterialLocation);
  1123. }
  1124. }
  1125. }
  1126. }
  1127. /// <summary>
  1128. /// PLC的DB3变量列表
  1129. /// </summary>
  1130. public void PlcVarMonitor()
  1131. {
  1132. foreach (PropertyInfo item in typeof(PlcReadAddressDB3).GetProperties())
  1133. {
  1134. if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
  1135. {
  1136. string type = item.PropertyType.ToString();
  1137. CommData.Add(new PlcInfos()
  1138. {
  1139. Count = CommData.Count + 1,
  1140. Name = item.Name,
  1141. Address = item.GetCustomAttribute<VarCommAttribute>().Address,
  1142. Type = type.Substring(type.IndexOf(".") + 1),
  1143. Describe = item.GetCustomAttribute<VarCommAttribute>().Describe,
  1144. Value = item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3).ToString(),
  1145. });
  1146. }
  1147. }
  1148. foreach (PropertyInfo item in typeof(WindSend_Read).GetProperties())
  1149. {
  1150. if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
  1151. {
  1152. string type = item.PropertyType.ToString();
  1153. CommData.Add(new PlcInfos()
  1154. {
  1155. Count = CommData.Count + 1,
  1156. Name = item.Name,
  1157. Address = item.GetCustomAttribute<VarCommAttribute>().Address,
  1158. Type = type.Substring(type.IndexOf(".") + 1),
  1159. Describe = item.GetCustomAttribute<VarCommAttribute>().Describe,
  1160. Value = item.GetValue(GVL_SmallStation.GetInstance.WindSendDB94).ToString(),
  1161. });
  1162. }
  1163. }
  1164. foreach (PropertyInfo item in typeof(WindSend_Write).GetProperties())
  1165. {
  1166. if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
  1167. {
  1168. string type = item.PropertyType.ToString();
  1169. CommData.Add(new PlcInfos()
  1170. {
  1171. Count = CommData.Count + 1,
  1172. Name = item.Name,
  1173. Address = item.GetCustomAttribute<VarCommAttribute>().Address,
  1174. Type = type.Substring(type.IndexOf(".") + 1),
  1175. Describe = item.GetCustomAttribute<VarCommAttribute>().Describe,
  1176. Value = item.GetValue(GVL_SmallStation.GetInstance.WindSendDB95).ToString(),
  1177. });
  1178. }
  1179. }
  1180. foreach (PropertyInfo item in typeof(GVL_SmallStation).GetProperties())
  1181. {
  1182. if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
  1183. {
  1184. string type = item.PropertyType.ToString();
  1185. ProcessVar.Add(new PlcInfos()
  1186. {
  1187. Count = ProcessVar.Count + 1,
  1188. Name = item.Name,
  1189. Type = type.Substring(type.IndexOf(".") + 1),
  1190. Address = item.GetCustomAttribute<VarCommAttribute>().Address,
  1191. Describe = item.GetCustomAttribute<VarCommAttribute>().Describe,
  1192. Value = item.GetValue(GVL_SmallStation.GetInstance).ToString()
  1193. });
  1194. }
  1195. }
  1196. }
  1197. public void RegisterInit()
  1198. {
  1199. //手动控制气缸 DB5.DBX0.0~DB5.DBX4.5
  1200. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1201. {
  1202. if (o != null)
  1203. {
  1204. if (o.ToString().Contains("升降气缸"))
  1205. {
  1206. int index = Convert.ToInt16(o.ToString().Substring(o.ToString().Length - 2));
  1207. if (index >= 1 && index <= 15)
  1208. {
  1209. string address = "DB5.DBX" + (index / 8) + "." + (index % 8 - 1);
  1210. if (index == 8) address = "DB5.DBX0.7";
  1211. HKDevice.HK_PLC_S7.Write<bool>(address, true);
  1212. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:{address},值:true。");
  1213. }
  1214. }
  1215. else if (o.ToString().Contains("阻挡气缸"))
  1216. {
  1217. int index = Convert.ToInt16(o.ToString().Substring(o.ToString().Length - 2));
  1218. if (index >= 1 && index <= 15)
  1219. {
  1220. string address = "";
  1221. if (index == 1) address = "DB5.DBX1.7";
  1222. if (index == 2) address = "DB5.DBX2.0";
  1223. if (index == 3) address = "DB5.DBX2.1";
  1224. if (index == 4) address = "DB5.DBX2.2";
  1225. if (index == 5) address = "DB5.DBX2.3";
  1226. if (index == 6) address = "DB5.DBX2.4";
  1227. if (index == 7) address = "DB5.DBX2.5";
  1228. if (index == 8) address = "DB5.DBX2.6";
  1229. if (index == 9) address = "DB5.DBX2.7";
  1230. if (index == 10) address = "DB5.DBX3.0";
  1231. if (index == 11) address = "DB5.DBX3.1";
  1232. if (index == 12) address = "DB5.DBX3.2";
  1233. if (index == 13) address = "DB5.DBX3.3";
  1234. if (index == 14) address = "DB5.DBX3.4";
  1235. if (index == 15) address = "DB5.DBX3.5";
  1236. HKDevice.HK_PLC_S7.Write<bool>(address, true);
  1237. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:{address},值:true。");
  1238. }
  1239. }
  1240. else if (o.ToString().Contains("进料桶顶升气缸"))
  1241. {
  1242. HKDevice.HK_PLC_S7.Write("DB5.DBX3.6", false);//默认顶升
  1243. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX3.6,值:false。");
  1244. }
  1245. else if (o.ToString().Contains("出料桶顶升气缸1"))
  1246. {
  1247. HKDevice.HK_PLC_S7.Write("DB5.DBX3.7", true);
  1248. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX3.7,值:true。");
  1249. }
  1250. else if (o.ToString().Contains("出料桶顶升气缸2"))
  1251. {
  1252. HKDevice.HK_PLC_S7.Write("DB5.DBX4.0", true);
  1253. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.0,值:true。");
  1254. }
  1255. else if (o.ToString().Contains("出料桶顶升气缸3"))
  1256. {
  1257. HKDevice.HK_PLC_S7.Write("DB5.DBX4.1", true);
  1258. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.1,值:true。");
  1259. }
  1260. else if (o.ToString().Contains("托盘气缸1_1"))
  1261. {
  1262. HKDevice.HK_PLC_S7.Write("DB5.DBX4.2", false);//默认伸出
  1263. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.2,值:false。");
  1264. }
  1265. else if (o.ToString().Contains("托盘气缸1_2"))
  1266. {
  1267. HKDevice.HK_PLC_S7.Write("DB5.DBX4.3", false);
  1268. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.3,值:false。");
  1269. }
  1270. else if (o.ToString().Contains("托盘气缸2_1"))
  1271. {
  1272. HKDevice.HK_PLC_S7.Write("DB5.DBX4.4", false);
  1273. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.4,值:false。");
  1274. }
  1275. else if (o.ToString().Contains("托盘气缸2_2"))
  1276. {
  1277. HKDevice.HK_PLC_S7.Write("DB5.DBX4.5", false);
  1278. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.5,值:false。");
  1279. }
  1280. }
  1281. }), "ManualOpen", true);//根据下发的配方ID将 托盘的位置信息添加到配方中
  1282. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1283. {
  1284. if (o != null)
  1285. {
  1286. if (o.ToString().Contains("升降气缸"))
  1287. {
  1288. int index = Convert.ToInt16(o.ToString().Substring(o.ToString().Length - 2));
  1289. if (index >= 1 && index <= 15)
  1290. {
  1291. string address = "DB5.DBX" + (index / 8) + "." + (index % 8 - 1);
  1292. if (index == 8) address = "DB5.DBX0.7";
  1293. HKDevice.HK_PLC_S7.Write<bool>(address, false);
  1294. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:{address},值:false。");
  1295. }
  1296. }
  1297. else if (o.ToString().Contains("阻挡气缸"))
  1298. {
  1299. int index = Convert.ToInt16(o.ToString().Substring(o.ToString().Length - 2));
  1300. if (index >= 1 && index <= 15)
  1301. {
  1302. string address = "";
  1303. if (index == 1) address = "DB5.DBX1.7";
  1304. if (index == 2) address = "DB5.DBX2.0";
  1305. if (index == 3) address = "DB5.DBX2.1";
  1306. if (index == 4) address = "DB5.DBX2.2";
  1307. if (index == 5) address = "DB5.DBX2.3";
  1308. if (index == 6) address = "DB5.DBX2.4";
  1309. if (index == 7) address = "DB5.DBX2.5";
  1310. if (index == 8) address = "DB5.DBX2.6";
  1311. if (index == 9) address = "DB5.DBX2.7";
  1312. if (index == 10) address = "DB5.DBX3.0";
  1313. if (index == 11) address = "DB5.DBX3.1";
  1314. if (index == 12) address = "DB5.DBX3.2";
  1315. if (index == 13) address = "DB5.DBX3.3";
  1316. if (index == 14) address = "DB5.DBX3.4";
  1317. if (index == 15) address = "DB5.DBX3.5";
  1318. HKDevice.HK_PLC_S7.Write<bool>(address, false);
  1319. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:{address},值:false。");
  1320. }
  1321. }
  1322. else if (o.ToString().Contains("进料桶顶升气缸"))
  1323. {
  1324. HKDevice.HK_PLC_S7.Write("DB5.DBX3.6", true);
  1325. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX3.6,值:true。");
  1326. }
  1327. else if (o.ToString().Contains("出料桶顶升气缸1"))
  1328. {
  1329. HKDevice.HK_PLC_S7.Write("DB5.DBX3.7", false);
  1330. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX3.7,值:false。");
  1331. }
  1332. else if (o.ToString().Contains("出料桶顶升气缸2"))
  1333. {
  1334. HKDevice.HK_PLC_S7.Write("DB5.DBX4.0", false);
  1335. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.0,值:false。");
  1336. }
  1337. else if (o.ToString().Contains("出料桶顶升气缸3"))
  1338. {
  1339. HKDevice.HK_PLC_S7.Write("DB5.DBX4.1", false);
  1340. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.1,值:false。");
  1341. }
  1342. else if (o.ToString().Contains("托盘气缸1_1"))
  1343. {
  1344. HKDevice.HK_PLC_S7.Write("DB5.DBX4.2", true);
  1345. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.2,值:true。");
  1346. }
  1347. else if (o.ToString().Contains("托盘气缸1_2"))
  1348. {
  1349. HKDevice.HK_PLC_S7.Write("DB5.DBX4.3", true);
  1350. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.3,值:true。");
  1351. }
  1352. else if (o.ToString().Contains("托盘气缸2_1"))
  1353. {
  1354. HKDevice.HK_PLC_S7.Write("DB5.DBX4.4", true);
  1355. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.4,值:true。");
  1356. }
  1357. else if (o.ToString().Contains("托盘气缸2_2"))
  1358. {
  1359. HKDevice.HK_PLC_S7.Write("DB5.DBX4.5", true);
  1360. MessageNotify.GetInstance.ShowUserLog($"手动操作气缸,地址:DB5.DBX4.5,值:true。");
  1361. }
  1362. }
  1363. }), "ManualClose", true);//根据下发的配方ID将 托盘的位置信息添加到配方中
  1364. //手动控制电机轴 DB5.DBX4.6~DB5.DBX5.2
  1365. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX4.6", true); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX4.6,值:true。"); }), "StartAxisLoadCommand", true);
  1366. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX4.6", false); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX4.6,值:false。"); }), "StopAxisLoadCommand", true);
  1367. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX4.7", true); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX4.7,值:true。"); }), "StartAxisMidCommand", true);
  1368. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX4.7", false); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX4.7,值:false。"); }), "StopAxisMidCommand", true);
  1369. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.0", true); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.0,值:true。"); }), "StartAxisUnLoadCommand", true);
  1370. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.0", false); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.0,值:false。"); }), "StopAxisUnLoadCommand", true);
  1371. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.1", true); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.1,值:true。"); }), "StartAxis1Command", true);
  1372. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.1", false); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.1,值:false。"); }), "StopAxis1Command", true);
  1373. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.2", true); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.2,值:true。"); }), "StartAxis2Command", true);
  1374. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB5.DBX5.2", false); MessageNotify.GetInstance.ShowUserLog($"手动控制电机轴,地址:DB5.DBX5.2,值:false。"); }), "StopAxis2Command", true);
  1375. //西门子配方处理
  1376. ActionManage.GetInstance.Register(new Action<object>((res) =>
  1377. {
  1378. ObservableCollection<RemoteRecipeRawMaterial> RawMaterials = new ObservableCollection<RemoteRecipeRawMaterial>();
  1379. ObservableCollection<WindSendRawMaterial> WindSendData = new ObservableCollection<WindSendRawMaterial>();
  1380. if (SiemensDevice.IsConnected)
  1381. {
  1382. if (res != null && res is XL_Start_DB recipe)
  1383. {
  1384. if (!string.IsNullOrEmpty(recipe.RecipeCode))
  1385. {
  1386. RawMaterials.Clear();
  1387. for (int i = 0; i < GVL_SmallStation.Max_DosingSotckBinNum; i++)
  1388. {
  1389. if (!string.IsNullOrEmpty(recipe.Material[i].Material_Name))
  1390. {
  1391. if (RawMaterialsNamePos.ContainsKey(recipe.Material[i].Material_Name))
  1392. {
  1393. RawMaterials.Add(new RemoteRecipeRawMaterial()
  1394. {
  1395. RawMaterialName = recipe.Material[i].Material_Name,
  1396. RawMaterialBarrelNum = recipe.Material[i].Material_BarrelNum,
  1397. RawMaterialWeight = recipe.Material[i].Material_Weight,
  1398. RawMaterialLocation = (int)RawMaterialsNamePos[recipe.Material[i].Material_Name],
  1399. RawMaterialType="小料"
  1400. });
  1401. }
  1402. else
  1403. {
  1404. MessageNotify.GetInstance.ShowRunLog($"原料:{recipe.Material[i].Material_Name},不在配料表");
  1405. }
  1406. }
  1407. else
  1408. {
  1409. break;
  1410. }
  1411. }
  1412. for (int i = 0; i < GVL_SmallStation.Max_PowderSotckBinNum; i++)
  1413. {
  1414. var rawMaterialName = recipe.Powder[i].Powder_Name;
  1415. if (!string.IsNullOrEmpty(rawMaterialName))
  1416. {
  1417. WindSendData.Add(new WindSendRawMaterial()
  1418. {
  1419. RawMaterialName = rawMaterialName,
  1420. RawMaterialWeight = recipe.Powder[i].Powder_Weight,
  1421. RawMaterialBarrelNum=3,
  1422. Location=Json<DevicePar>.Data.windSendRawMaterial.FirstOrDefault(raw=>raw.RawMaterialName== rawMaterialName).Location,
  1423. RawMaterialType="粉料"
  1424. });
  1425. }
  1426. else
  1427. {
  1428. break;
  1429. }
  1430. }
  1431. App.Current.Dispatcher.Invoke(() =>
  1432. {
  1433. Json<RemoteRecipeDataColl>.Data.Recipes.Add(new RemoteRecipeData()
  1434. {
  1435. RecipeName = recipe.RecipeName,
  1436. RecipeCode = recipe.RecipeCode,
  1437. RawMaterial = RawMaterials,
  1438. TrayCode = recipe.StockCode,
  1439. WindSend = WindSendData,
  1440. RecipesSource=RecipeSource.远程
  1441. });
  1442. });
  1443. }
  1444. }
  1445. }
  1446. }), "SiemensRecipeRecive", true);
  1447. //将本地配方发送到西门子配方里,执行配料
  1448. ActionManage.GetInstance.Register(new Action<Object>((res) =>
  1449. {
  1450. if (res != null && res is RemoteRecipeData rm)
  1451. {
  1452. //Json<RemoteRecipeDataColl>.Data.Recipes.Add(rm);
  1453. var newRecipe=new RemoteRecipeData();
  1454. newRecipe.RecipeName = rm.RecipeName;
  1455. newRecipe.RecipeCode = rm.RecipeCode;
  1456. newRecipe.TrayCode = rm.TrayCode;
  1457. newRecipe.RecipesSource = RecipeSource.本地;
  1458. foreach (var item in rm.RawMaterial)
  1459. {
  1460. newRecipe.RawMaterial.Add(new RemoteRecipeRawMaterial()
  1461. {
  1462. DeviceIp = item.DeviceIp,
  1463. RawMaterialName = item.RawMaterialName,
  1464. RawMaterialBarrelNum = item.RawMaterialBarrelNum,
  1465. RawMaterialType = item.RawMaterialType,
  1466. RawMaterialWeight = item.RawMaterialWeight,
  1467. Laying_Off_Weight = item.Laying_Off_Weight,
  1468. StockBinRemainingWeight = item.StockBinRemainingWeight,
  1469. RawMaterialLocation = item.RawMaterialLocation,
  1470. IsDosingComple = item.IsDosingComple
  1471. });
  1472. }
  1473. foreach (var item in rm.WindSend)
  1474. {
  1475. newRecipe.WindSend.Add(new WindSendRawMaterial()
  1476. {
  1477. DeviceIp = item.DeviceIp,
  1478. Location=item.Location,
  1479. RawMaterialChineseName = item.RawMaterialChineseName,
  1480. RawMaterialName = item.RawMaterialName,
  1481. RawMaterialWeight = item.RawMaterialWeight,
  1482. DosingCompleWeight = item.DosingCompleWeight,
  1483. RawMaterialBarrelNum = item.RawMaterialBarrelNum,
  1484. RawMaterialType = item.RawMaterialType,
  1485. });
  1486. }
  1487. Json<RemoteRecipeDataColl>.Data.Recipes.Add(newRecipe);
  1488. }
  1489. }), "LocalSimulationRecipeIssue", true);
  1490. //手动控制系统模式
  1491. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.0", true); MessageNotify.GetInstance.ShowUserLog($"手动控制系统启动,地址:DB44.DBX0.0,值:true。"); }), "SystemStart", true);
  1492. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.0", false); MessageNotify.GetInstance.ShowUserLog($"手动控制系统停止,地址:DB44.DBX0.0,值:false。"); }), "SystemStop", true);
  1493. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.2", true); MessageNotify.GetInstance.ShowUserLog($"手动控制系统暂停,地址:DB44.DBX0.2,值:true。"); }), "SystemPause", true);
  1494. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.2", false); MessageNotify.GetInstance.ShowUserLog($"手动控制系统复位,地址:DB44.DBX0.2,值:false。"); }), "SystemReset", true);
  1495. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.1", false); MessageNotify.GetInstance.ShowUserLog($"手动切换为自动模式,地址:DB44.DBX0.1,值:false。"); }), "SystemAutoMode", true);
  1496. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.1", true); MessageNotify.GetInstance.ShowUserLog($"手动切换为手动模式,地址:DB44.DBX0.1,值:true。"); }), "SystemDebugMode", true);
  1497. //流程控制
  1498. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.3", true);}), "ManualSystemReset", true);
  1499. ActionManage.GetInstance.Register(new Action(() => { HKDevice.HK_PLC_S7.Write<bool>("DB44.DBX0.4", true);}), "CLearRecipeInfo", true);
  1500. ActionManage.GetInstance.Register(new Action(() =>
  1501. {
  1502. MessageNotify.GetInstance.ShowRunLog("系统流程开始复位。");
  1503. Json<RemoteRecipeDataColl>.Data.Recipes.Clear();
  1504. MessageNotify.GetInstance.ShowRunLog("远程配方数据已清空。");
  1505. GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 0;
  1506. GVL_SmallStation.GetInstance.WindSendDosingStatus = 0;
  1507. GVL_SmallStation.GetInstance.WindSendDosing = false;
  1508. GVL_SmallStation.GetInstance.Order_Cancel = false;
  1509. GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
  1510. GVL_SmallStation.GetInstance.OrderCancelStep = 0;
  1511. MessageNotify.GetInstance.ShowRunLog("系统流程变量已复位。");
  1512. for (int i = 0; i < 5; i++)
  1513. {
  1514. RecipeQueueTray[i].Clear();
  1515. GVL_SmallStation.GetInstance.RecipeProcessStatus[i] = 0;
  1516. GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 0;
  1517. }
  1518. MessageNotify.GetInstance.ShowRunLog("配方队列已清空。");
  1519. StockBinInit();
  1520. MessageNotify.GetInstance.ShowRunLog("料仓初始化完成。");
  1521. WindSendReset();
  1522. MessageNotify.GetInstance.ShowRunLog("风送系统复位完成。");
  1523. //for (int i = 0; i < GVL_SmallStation.GetInstance.StockInDosingComple.Length; i++)
  1524. //{
  1525. // GVL_SmallStation.GetInstance.StockInDosingComple[i] = false;
  1526. //}
  1527. MessageNotify.GetInstance.ShowRunLog("系统流程复位结束,等待西门子重新下发订单");
  1528. }), "BPASystemReset", true);
  1529. //往海科PLC写值
  1530. ActionManage.GetInstance.Register(new Action<Object>((o) =>
  1531. {
  1532. if (o != null && o is HKDeviceWrite data)
  1533. {
  1534. if (data.PlcVarType == PlcVarType.Bool)
  1535. {
  1536. bool value = (bool)data.Value;
  1537. HKDevice.HK_PLC_S7.Write<bool>(data.Address, value);
  1538. }
  1539. else if (data.PlcVarType == PlcVarType.Byte)
  1540. {
  1541. byte value = (byte)data.Value;
  1542. HKDevice.HK_PLC_S7.Write<byte>(data.Address, value);
  1543. }
  1544. else if (data.PlcVarType == PlcVarType.Int)
  1545. {
  1546. short value = (short)data.Value;
  1547. HKDevice.HK_PLC_S7.Write<short>(data.Address, value);
  1548. }
  1549. else if (data.PlcVarType == PlcVarType.Dint)
  1550. {
  1551. int value = (int)data.Value;
  1552. HKDevice.HK_PLC_S7.Write<int>(data.Address, value);
  1553. }
  1554. else if (data.PlcVarType == PlcVarType.Real)
  1555. {
  1556. float value = (float)data.Value;
  1557. HKDevice.HK_PLC_S7.Write<float>(data.Address, value);
  1558. }
  1559. }
  1560. }), "PLCWrite", true);
  1561. //电机速度
  1562. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1563. {
  1564. if (o != null && o is short value)
  1565. {
  1566. HKDevice.HK_PLC_S7.Write("DB47.DBW8", value);
  1567. }
  1568. }), "AxisLoadSpeedSet", true);
  1569. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1570. {
  1571. if (o != null && o is short value)
  1572. {
  1573. HKDevice.HK_PLC_S7.Write("DB47.DBW10", value);
  1574. }
  1575. }), "AxisMidSpeedSet", true);
  1576. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1577. {
  1578. if (o != null && o is short value)
  1579. {
  1580. HKDevice.HK_PLC_S7.Write("DB47.DBW12", value);
  1581. }
  1582. }), "AxisUnLoadSpeedSet", true);
  1583. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1584. {
  1585. if (o != null && o is float value)
  1586. {
  1587. HKDevice.HK_PLC_S7.Write("DB47.DBD0", value);
  1588. }
  1589. }), "Axis1SpeedSet", true);
  1590. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1591. {
  1592. if (o != null && o is float value)
  1593. {
  1594. HKDevice.HK_PLC_S7.Write("DB47.DBD4", value);
  1595. }
  1596. }), "Axis2SpeedSet", true);
  1597. //机器人的操作
  1598. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1599. {
  1600. if (o != null && o is string address)
  1601. {
  1602. HKDevice.HK_PLC_S7.Write(address, true);
  1603. }
  1604. }), "RobotSendTrueCommand", true);
  1605. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1606. {
  1607. if (o != null && o is string address)
  1608. {
  1609. HKDevice.HK_PLC_S7.Write(address, false);
  1610. }
  1611. }), "RobotSendFalseCommand", true);
  1612. ActionManage.GetInstance.Register(new Action<object>((o) =>
  1613. {
  1614. if (o != null && o is short Value)
  1615. {
  1616. HKDevice.HK_PLC_S7.Write("DB4.DBB1", (byte)Value);
  1617. }
  1618. }), "RobotSetProgramNum", true);
  1619. }
  1620. public void DeviceConnect()
  1621. {
  1622. try
  1623. {
  1624. if (Json<DevicePar>.Data.deviceConnectPar.HKPlcConnect)
  1625. {
  1626. HKDevice.HK_PLC_S7.Connect(S7.Net.CpuType.S71200, HK_PLC_IP);
  1627. if (HKDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("海科plc连接成功");
  1628. }
  1629. }
  1630. catch (Exception ex)
  1631. {
  1632. MessageNotify.GetInstance.ShowAlarmLog("海科plc连接失败,等待重新连接");
  1633. }
  1634. finally
  1635. {
  1636. HKDevice.Init();
  1637. MessageNotify.GetInstance.ShowRunLog("海科plc初始化完成");
  1638. }
  1639. try
  1640. {
  1641. if (Json<DevicePar>.Data.deviceConnectPar.SiemensConnect)
  1642. {
  1643. SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP);
  1644. if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子plc连接成功");
  1645. }
  1646. }
  1647. catch (Exception ex)
  1648. {
  1649. MessageNotify.GetInstance.ShowAlarmLog("西门子plc连接失败,等待重新连接");
  1650. }
  1651. finally
  1652. {
  1653. SiemensDevice.Init();
  1654. MessageNotify.GetInstance.ShowRunLog("西门子plc初始化完成");
  1655. }
  1656. try
  1657. {
  1658. if (Json<DevicePar>.Data.deviceConnectPar.WindSendConnect)
  1659. {
  1660. WindSendDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71200, WindSend_PLC_IP);
  1661. if (WindSendDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("风送plc连接成功");
  1662. }
  1663. }
  1664. catch (Exception ex)
  1665. {
  1666. MessageNotify.GetInstance.ShowAlarmLog("粉料plc连接失败,等待重新连接");
  1667. }
  1668. finally
  1669. {
  1670. WindSendDevice.Init();
  1671. MessageNotify.GetInstance.ShowRunLog("风送粉料plc初始化完成");
  1672. }
  1673. ThreadManage.GetInstance().StartLong(new Action(() =>
  1674. {
  1675. try
  1676. {
  1677. if (!HKDevice.IsConnected && Json<DevicePar>.Data.deviceConnectPar.HKPlcConnect)
  1678. {
  1679. HKDevice.HK_PLC_S7.Connect(S7.Net.CpuType.S71200, HK_PLC_IP);
  1680. if (HKDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("海科PLC重新连接成功");
  1681. }
  1682. }
  1683. catch (Exception ex)
  1684. {
  1685. }
  1686. try
  1687. {
  1688. if (!SiemensDevice.IsConnected && Json<DevicePar>.Data.deviceConnectPar.SiemensConnect)
  1689. {
  1690. SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP);
  1691. if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子PLC重新连接成功");
  1692. }
  1693. }
  1694. catch (Exception ex)
  1695. {
  1696. }
  1697. try
  1698. {
  1699. if (!WindSendDevice.IsConnected && Json<DevicePar>.Data.deviceConnectPar.WindSendConnect)
  1700. {
  1701. WindSendDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71200, WindSend_PLC_IP);
  1702. if (WindSendDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("风送plc重新连接成功");
  1703. }
  1704. }
  1705. catch (Exception ex)
  1706. {
  1707. }
  1708. Thread.Sleep(50);
  1709. }), "设备连接", true);
  1710. }
  1711. private void DosingDevice(int Index, int DeviceID)
  1712. {
  1713. if (RTrig.GetInstance("Tray2StatusDevice" + DeviceID).Start(DeviceInquire.GetInstance.GetDevice(DeviceID).deviceStatus.RunStatus == 3))
  1714. {
  1715. MessageNotify.GetInstance.ShowRunLog($"柔性味魔方,托盘2,配方:{RemoteRecipes.ElementAt(Index).RecipeName},{DeviceID}号仓,配料完成");
  1716. int res = Array.FindIndex(RemoteRecipes.ElementAt(Index).RawMaterial.ToArray(), p => p.RawMaterialLocation == DeviceID);
  1717. RemoteRecipes.ElementAt(Index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(DeviceID).deviceStatus.CutWeightFeedback;
  1718. DeviceInquire.GetInstance.GetDevice(DeviceID).StatusReset();
  1719. if (DeviceID >= 1 && DeviceID <= 8)
  1720. {
  1721. HKDevice.HK_PLC_S7.Write("DB4.DBX30." + (DeviceID - 1), true);
  1722. }
  1723. else if (DeviceID >= 9 && DeviceID <= 15)
  1724. {
  1725. HKDevice.HK_PLC_S7.Write("DB4.DBX31." + (DeviceID - 9), true);
  1726. }
  1727. }
  1728. }
  1729. private void WindSendReset()
  1730. {
  1731. float weight = (float)0.0;
  1732. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBD0", weight);
  1733. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBD4", weight);
  1734. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBD8", weight);
  1735. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBD12", weight);
  1736. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBD16", weight);
  1737. WindSendDevice.Siemens_PLC_S7.Write("DB95.DBX38.1", false);
  1738. }
  1739. public void RawMaterialNameWithCode()
  1740. {
  1741. GVL_SmallStation.GetInstance.RawMaterialsNameCode.Clear();
  1742. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0001", "色拉油");
  1743. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0002", "一级菜油");
  1744. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0003", "菜籽油");
  1745. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0004", "青花椒油");
  1746. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0005", "卤牛肉丁");
  1747. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0006", "冻鸡肉丁");
  1748. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0007", "香菇丁");
  1749. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0008", "高水分糍粑海椒");
  1750. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0009", "低水分糍粑海椒");
  1751. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0010", "辣豆瓣");
  1752. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0011", "整豆豉");
  1753. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0012", "豆豉细粒");
  1754. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0013", "卤黄豆");
  1755. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0014", "野山椒粒");
  1756. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0015", "竹笋丁");
  1757. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0016", "香辣酱辣椒酱");
  1758. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0017", "芽菜粒");
  1759. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0018", "榨菜丁");
  1760. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0019", "盐菜");
  1761. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0020", "洋葱丁");
  1762. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0021", "番茄酱");
  1763. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0022", "甜豆瓣");
  1764. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0023", "甜面酱");
  1765. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0024", "芝麻酱");
  1766. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0025", "炸花生");
  1767. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0026", "盐渍青椒丁");
  1768. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0027", "备料剁红椒");
  1769. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0028", "萝卜丁");
  1770. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0029", "油芝麻");
  1771. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0030", "生姜");
  1772. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0031", "大蒜");
  1773. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0032", "榨菜酱");
  1774. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0033", "炸碗豆");
  1775. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0034", "大头菜丁");
  1776. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0035", "酱油");
  1777. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0036", "I+G");
  1778. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0037", "味精");
  1779. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0038", "白糖");
  1780. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0039", "食盐");
  1781. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0040", "花椒酱");
  1782. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0041", "调味膏2");
  1783. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0042", "调味膏5");
  1784. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0043", "十三香调味膏");
  1785. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0044", "酱香膏");
  1786. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0045", "芽菜香料粉");
  1787. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0046", "香料A");
  1788. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0047", "香料D");
  1789. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0048", "猪肉精膏");
  1790. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0049", "调味膏3");
  1791. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0050", "柠檬酸粉");
  1792. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0051", "辣椒红");
  1793. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0052", "辣椒油树脂");
  1794. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0053", "水态混和酸");
  1795. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0054", "加水稀释后防腐剂");
  1796. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0055", "异维C钠粉");
  1797. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0056", "琼脂粉");
  1798. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0057", "香葱油");
  1799. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0058", "水态甜味剂");
  1800. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0059", "孜然粉");
  1801. GVL_SmallStation.GetInstance.RawMaterialsNameCode.TryAdd("0060", "孜然油");
  1802. }
  1803. /// <summary>
  1804. /// 检查指定的配方号是否已经下发至配方执行队列中。
  1805. /// </summary>
  1806. /// <param name="recipeCode">需要检测的配方号</param>
  1807. /// <returns>是否在下发配方执行队列中</returns>
  1808. private bool IsInQueue(string recipeCode)
  1809. {
  1810. bool result = false;
  1811. foreach (var queue in RecipeQueueTray.Values)
  1812. {
  1813. if (queue.Contains(recipeCode))
  1814. {
  1815. result = true;
  1816. break;
  1817. }
  1818. }
  1819. return result;
  1820. }
  1821. /// <summary>
  1822. /// 发送操作,直到收到确认信号
  1823. /// </summary>
  1824. /// <param name="operate"></param>
  1825. /// <param name="ack"></param>
  1826. /// <param name="retrySecond"></param>
  1827. /// <returns></returns>
  1828. /// <exception cref="ArgumentNullException"></exception>
  1829. private bool SendDataOperation(Action operate,Func<bool> ack, int retrytimes = 3,int retryInterval=3)
  1830. {
  1831. if (operate is null)
  1832. {
  1833. throw new ArgumentNullException("operate", "需要执行的操作不可为Null。");
  1834. }
  1835. if (ack is null)
  1836. {
  1837. throw new ArgumentNullException("ack", "验证确认的委托不可为Null。");
  1838. }
  1839. var isSuccess = false;
  1840. var isConnected = SiemensDevice.IsConnected;
  1841. var retryDelay = TimeSpan.FromSeconds(retryInterval);
  1842. int count = 0;
  1843. operate?.Invoke();
  1844. isSuccess = ack.Invoke();
  1845. while (!isSuccess && count<retrytimes)
  1846. {
  1847. count++;
  1848. if (isConnected)
  1849. {
  1850. Thread.Sleep(retryDelay);
  1851. operate?.Invoke();
  1852. isSuccess = isSuccess && ack.Invoke();
  1853. }
  1854. }
  1855. return isSuccess;
  1856. }
  1857. private void CleanFinishData(int recipeNum)
  1858. {
  1859. RecipeFinishInfo[recipeNum].Order_No = "";
  1860. RecipeFinishInfo[recipeNum].Product_Code = "";
  1861. RecipeFinishInfo[recipeNum].Job_No = 0;
  1862. for (int i = 0; i < 20; i++)
  1863. {
  1864. RecipeFinishInfo[recipeNum].Material[i] = new UDT1();
  1865. }
  1866. for (int i = 0; i < 10; i++)
  1867. {
  1868. RecipeFinishInfo[recipeNum].Powder[i] = new UDT2();
  1869. }
  1870. RecipeFinishInfo[recipeNum].Ask_For_Finish = false;
  1871. RecipeFinishInfo[recipeNum].DosingTime = 0;
  1872. SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo[recipeNum], 2261);
  1873. }
  1874. }
  1875. }