终端一体化运控平台
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

499 行
23 KiB

  1. using BPASmartClient.CustomResource.Pages.Model;
  2. using BPASmartClient.JXJFoodSmallStation.ViewModel;
  3. using BPA.Helper;
  4. using BPASmartClient.Modbus;
  5. using BPASmartClient.Model;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.Linq;
  11. using System.Net.NetworkInformation;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using System.Configuration;
  15. using System.Diagnostics;
  16. namespace BPASmartClient.JXJFoodSmallStation.Model
  17. {
  18. public class DeviceInquire
  19. {
  20. private volatile static DeviceInquire _Instance;
  21. public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire());
  22. private DeviceInquire() { }
  23. string IPSegment = "107.107.2.";
  24. ConcurrentDictionary<string, DeviceStatus> DeviceLists = new ConcurrentDictionary<string, DeviceStatus>();
  25. List<string> InvalidIP = new List<string>();//无效 IP 集合
  26. List<string> IPLists = new List<string>();//启动 Ping 任务IP集合
  27. ConcurrentQueue<string> IPQueues = new ConcurrentQueue<string>();//pincomplete 完成队列
  28. public ObservableCollection<DeviceCurrentStatus> TopDeviceCurrentStatuses { get; set; } = new ObservableCollection<DeviceCurrentStatus>();
  29. public ObservableCollection<DeviceCurrentStatus> BottomDeviceCurrentStatuses { get; set; } = new ObservableCollection<DeviceCurrentStatus>();
  30. public ObservableCollection<Devices> devices { get; set; } = new ObservableCollection<Devices>();
  31. private void DeviceDataInit()
  32. {
  33. TaskManage.GetInstance.StartLong(new Action(() =>
  34. {
  35. for (int i = 0; i < DeviceLists.Count; i++)
  36. {
  37. string deviceName = DeviceLists.ElementAt(i).Value.DeviceName;
  38. int TopIndex = Array.FindIndex(TopDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName);
  39. int BottomIndex = Array.FindIndex(BottomDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName);
  40. if (TopIndex >= 0 && TopIndex < TopDeviceCurrentStatuses.Count)
  41. {
  42. TopDeviceCurrentStatuses.ElementAt(TopIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback;
  43. TopDeviceCurrentStatuses.ElementAt(TopIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum;
  44. TopDeviceCurrentStatuses.ElementAt(TopIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus;
  45. }
  46. if (BottomIndex >= 0 && BottomIndex < BottomDeviceCurrentStatuses.Count)
  47. {
  48. BottomDeviceCurrentStatuses.ElementAt(BottomIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback;
  49. BottomDeviceCurrentStatuses.ElementAt(BottomIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum;
  50. BottomDeviceCurrentStatuses.ElementAt(BottomIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus;
  51. }
  52. int deviceIndex = Array.FindIndex(devices.ToArray(), p => p.IpAddress == DeviceLists.ElementAt(i).Key && p.DeviceName != DeviceLists.ElementAt(i).Value.DeviceName);
  53. if (deviceIndex >= 0 && deviceIndex < devices.Count)
  54. {
  55. devices.ElementAt(deviceIndex).DeviceName = DeviceLists.ElementAt(i).Value.DeviceName;
  56. }
  57. if (!TaskManage.GetInstance.IsContainsKey($"{deviceName} 开始监听"))
  58. {
  59. DeviceLists[DeviceLists.ElementAt(i).Key].Init(deviceName);
  60. }
  61. }
  62. Thread.Sleep(200);
  63. }), "设备状态监听", true);
  64. }
  65. private void TestData()
  66. {
  67. for (int i = 0; i < 8; i++)
  68. {
  69. TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus()
  70. {
  71. DeviceName = $"测试设备{i + 1}",
  72. DeviceNum = i + 1,
  73. RunStatus = 1,
  74. Weight = new Random().Next(100, 10000) / 100.0
  75. });
  76. devices.Add(new Devices()
  77. {
  78. DeviceName = $"测试设备{i + 1}",
  79. IpAddress = $"192.168.1.{i + 1}",
  80. });
  81. }
  82. for (int i = 8; i < 16; i++)
  83. {
  84. BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus()
  85. {
  86. DeviceName = $"测试设备{i + 1}",
  87. DeviceNum = i + 1,
  88. RunStatus = 1,
  89. Weight = new Random().Next(100, 10000) / 100.0
  90. });
  91. devices.Add(new Devices()
  92. {
  93. DeviceName = $"测试设备{i + 1}",
  94. IpAddress = $"192.168.1.{i + 1}",
  95. });
  96. }
  97. }
  98. public void Init()
  99. {
  100. //AlarmHelper<AlarmInfo>.Init();
  101. //AlarmHelper<AlarmInfo>.Alarm.EStop1 = true;
  102. //IPSegment = ConfigurationManager.AppSettings["RawMaterial_IP"];
  103. //TestData();
  104. IpAddressLines();
  105. DeviceDataInit();
  106. TaskManage.GetInstance.StartLong(new Action(() =>
  107. {
  108. if (IPQueues.Count >= IPLists.Count)
  109. IpAddressLines();
  110. Thread.Sleep(5000);
  111. }), "配料机设备上线监听", true);
  112. }
  113. public void Rescan()
  114. {
  115. InvalidIP.Clear();
  116. }
  117. public DeviceStatus GetDevice(string ip)
  118. {
  119. if (ip != null)
  120. {
  121. var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip);
  122. if (res != null) return res;
  123. }
  124. return new DeviceStatus();
  125. }
  126. public DeviceStatus GetDevice(int location)
  127. {
  128. if (location > 0 && location < 16)
  129. {
  130. var res = DeviceLists.Values.FirstOrDefault(p => p.deviceStatus.DeviceNum == location);
  131. if (res != null) return res;
  132. }
  133. return new DeviceStatus();
  134. }
  135. public List<DeviceStatus> GetDevice()
  136. {
  137. List<DeviceStatus> deviceStatuses = new List<DeviceStatus>();
  138. foreach (var device in DeviceLists)
  139. {
  140. deviceStatuses.Add(device.Value);
  141. }
  142. return deviceStatuses;
  143. }
  144. private void IpAddressLines()
  145. {
  146. IPLists.Clear();
  147. IPQueues.Clear();
  148. /* for (int i = 1; i <= 255; i++)
  149. {
  150. if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}"))
  151. {
  152. IPLists.Add($"{IPSegment}{i}");
  153. }
  154. }*/
  155. //吉香居特定IP
  156. for (int i = 0; i < 15; i++)
  157. {
  158. IPLists.Add($"{IPSegment}{i + 69}");
  159. }
  160. IPLists.ForEach((item) =>
  161. {
  162. Ping myPing = new Ping();
  163. myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
  164. myPing.SendAsync(item, 1000, null);
  165. });
  166. }
  167. private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e)
  168. {
  169. if (e.Reply != null && e.Reply.Status == IPStatus.Success)
  170. {
  171. string ip = e.Reply.Address.ToString();
  172. if (!DeviceLists.ContainsKey(ip))
  173. {
  174. DeviceStatus DS = new DeviceStatus();
  175. DS.modbusTcp.IsReconnect = false;
  176. DS.modbusTcp.ConnectOk = new Action(() =>
  177. {
  178. string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20).Trim()?.Replace(" ", "");//读取设备名称
  179. if (DeviceName.Length > 0)
  180. {
  181. DeviceLists.TryAdd(ip, DS);
  182. DeviceLists[ip].Init(DeviceName);
  183. DeviceLists[ip].modbusTcp.IsReconnect = false;
  184. App.Current.Dispatcher.Invoke(new Action(() =>
  185. {
  186. //DeviceListViewModel.devices.Add(new Devices()
  187. //{
  188. // DeviceName = DeviceName,
  189. // IpAddress = ip
  190. //});//加入连接的(有名称的)设备列表
  191. devices.Add(new Devices() { DeviceName = DeviceName, IpAddress = ip });
  192. if (TopDeviceCurrentStatuses.Count <= 7)
  193. TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  194. else
  195. BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  196. for (int i = 0; i < Json<LocaPar>.Data.RemoteRecipes.Count; i++)
  197. {
  198. for (int m = 0; m < Json<LocaPar>.Data.RemoteRecipes.ElementAt(i).RawMaterials.Count; m++)
  199. {
  200. if (Json<LocaPar>.Data.RemoteRecipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
  201. {
  202. Json<LocaPar>.Data.RemoteRecipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
  203. }
  204. }
  205. }
  206. if (Global.DeviceRawMaterials.Count > 0)
  207. {
  208. if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null)
  209. {
  210. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  211. }
  212. }
  213. else
  214. {
  215. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  216. }
  217. }));
  218. }
  219. else
  220. {
  221. //if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  222. if (DeviceLists.ContainsKey(ip))
  223. {
  224. DeviceLists[ip].Dispose();
  225. var res11 = DeviceLists[ip];
  226. DeviceLists.TryRemove(ip, out res11);
  227. }
  228. }
  229. });
  230. DS.modbusTcp.ConnectFail = new Action(() =>
  231. {
  232. //if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  233. //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败");
  234. if (DeviceLists.ContainsKey(ip))
  235. {
  236. DeviceLists[ip].Dispose();
  237. var res11 = DeviceLists[ip];
  238. DeviceLists.TryRemove(ip, out res11);
  239. }
  240. });
  241. DS.modbusTcp.Disconnect = new Action(() =>
  242. {
  243. if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip);
  244. var res = devices.FirstOrDefault(P => P.IpAddress == ip);
  245. if (res != null && devices.Contains(res))
  246. {
  247. App.Current.Dispatcher.Invoke(new Action(() =>
  248. {
  249. devices.Remove(res);
  250. var item = Global.DeviceRawMaterials.FirstOrDefault(P => P.RawMaterialName == res.DeviceName);
  251. if (item != null) Global.DeviceRawMaterials.Remove(item);
  252. var topRes = TopDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  253. var bottomRes = BottomDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  254. if (topRes != null) TopDeviceCurrentStatuses.Remove(topRes);
  255. if (bottomRes != null) BottomDeviceCurrentStatuses.Remove(bottomRes);
  256. }));
  257. }
  258. if (DeviceLists.ContainsKey(ip))
  259. {
  260. DeviceLists[ip].Dispose();
  261. var res11 = DeviceLists[ip];
  262. DeviceLists.TryRemove(ip, out res11);
  263. }
  264. });
  265. Task.Run(new Action(() =>
  266. {
  267. DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接
  268. IPQueues.Enqueue(e.Reply.Address.ToString());
  269. }));
  270. }
  271. else
  272. {
  273. IPQueues.Enqueue(e.Reply.Address.ToString());
  274. }
  275. }
  276. else
  277. {
  278. if (e.Reply != null)
  279. IPQueues.Enqueue(e.Reply.Address.ToString());
  280. }
  281. }
  282. }
  283. public class DeviceStatus
  284. {
  285. #region 对象属性声明
  286. public string DeviceName = String.Empty;
  287. public string IpAddress => modbusTcp.IPAdress;
  288. /// <summary>
  289. /// 设备状态
  290. /// </summary>
  291. public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();
  292. public ModbusTcp modbusTcp = new ModbusTcp();
  293. public bool IsConnected => modbusTcp.Connected;
  294. #endregion
  295. public void Init(string DeviceName)
  296. {
  297. modbusTcp.Show += new Action<string>((s) =>
  298. {
  299. if (s != null) MessageNotify.GetInstance.ShowRunLog(s);
  300. });
  301. modbusTcp.ShowEx += new Action<string>((s) =>
  302. {
  303. if (s != null) MessageNotify.GetInstance.ShowRunLog(s);
  304. });
  305. this.DeviceName = DeviceName;
  306. //AlarmHelper<AlarmInfo>.Init();
  307. if (modbusTcp.Connected)
  308. {
  309. TaskManage.GetInstance.StartLong(new Action(() =>
  310. {
  311. if (modbusTcp.Connected)
  312. {
  313. deviceStatus.RunStatus = (ushort)this.modbusTcp.ReadShort(DeviceAddress.RunStatus); //获取设备运行状态
  314. deviceStatus.WeightFeedback = this.modbusTcp.ReadShort(DeviceAddress.WeightFeedback);//获取设备料仓剩余重量
  315. deviceStatus.NowWeightFeedback = this.modbusTcp.GetReal(DeviceAddress.CutWeightFeedback);//获取下料重量
  316. deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号
  317. deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码
  318. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).EStop1 = deviceStatus.DeviceAlarmCode.GetBitValue(1);
  319. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).Servo = deviceStatus.DeviceAlarmCode.GetBitValue(2);
  320. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).Inverter = deviceStatus.DeviceAlarmCode.GetBitValue(3);
  321. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).EStop2 = deviceStatus.DeviceAlarmCode.GetBitValue(7);
  322. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).SiloUpperLimit = deviceStatus.DeviceAlarmCode.GetBitValue(8);
  323. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).SiloLowerLimit = deviceStatus.DeviceAlarmCode.GetBitValue(9);
  324. //允许配料即产线气缸抬起,发送给味魔方
  325. if (deviceStatus.DeviceNum >= 1 && deviceStatus.DeviceNum <= 15)
  326. {
  327. if (GVL_SmallStation.GetInstance.plcReadDataDB3.StockBinAllowIssue[deviceStatus.DeviceNum - 1])
  328. {
  329. this.modbusTcp.Write("LW41", (ushort)1);
  330. GVL_SmallStation.GetInstance.StockBinCylinderStatus.SetBitValue((byte)(deviceStatus.DeviceNum), true);
  331. }
  332. else
  333. {
  334. this.modbusTcp.Write("LW41", (ushort)0);
  335. GVL_SmallStation.GetInstance.StockBinCylinderStatus.SetBitValue((byte)(deviceStatus.DeviceNum), false);
  336. }
  337. }
  338. Thread.Sleep(10);
  339. }
  340. }), $"{DeviceName} 开始监听", true);
  341. }
  342. }
  343. public void SetDeviceName(string name)
  344. {
  345. this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]);
  346. this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
  347. }
  348. /// <summary>
  349. /// 开盖
  350. /// </summary>
  351. public void OpenLid()
  352. {
  353. //modbusTcp.Write(DeviceAddress.OpenLid, (ushort)1);
  354. }
  355. /// <summary>
  356. /// 关盖
  357. /// </summary>
  358. public void CloseLid()
  359. {
  360. //modbusTcp.Write(DeviceAddress.CloseLid, (ushort)1);
  361. }
  362. public bool StatusReset()
  363. {
  364. return this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1);
  365. //var res = modbusTcp.Read(DeviceAddress.RunStatus);
  366. }
  367. public void Dispose()
  368. {
  369. TaskManage.GetInstance.StopTask($"{DeviceName} 开始监听");
  370. }
  371. public void Start(float Value)
  372. {
  373. //if (modbusTcp.Connected)
  374. //{
  375. // var res = Json<DevicePar>.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName);
  376. // if (res != null)
  377. // {
  378. // prop1:
  379. // modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight);
  380. // var Value1 = (float)this.modbusTcp.GetReal(DeviceAddress.SlowlyAddWeight);
  381. // if (Value1 != null && Value1.ToString() != res.SlowlyAddWeight.ToString()) goto prop1;
  382. // prop2:
  383. // modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight);
  384. // var Value2 = (float)this.modbusTcp.GetReal(DeviceAddress.PreCloseValveWeight);
  385. // if (Value2 != null && Value2.ToString() != res.PreCloseValveWeight.ToString()) goto prop2;
  386. // prop3:
  387. // modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration);
  388. // var Value3 = this.modbusTcp.GetUint(DeviceAddress.RapidAcceleration);
  389. // if (Value3 != null && Value3.ToString() != res.RapidAcceleration.ToString()) goto prop3;
  390. // prop4:
  391. // modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration);
  392. // var Value4 = this.modbusTcp.GetUint(DeviceAddress.SlowAcceleration);
  393. // if (Value4 != null && Value4.ToString() != res.SlowAcceleration.ToString()) goto prop4;
  394. // prop5:
  395. // modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed);
  396. // var Value5 = this.modbusTcp.GetUint(DeviceAddress.ServoManualSpeed);
  397. // if (Value5 != null && Value5.ToString() != res.ServoManualSpeed.ToString()) goto prop5;
  398. // prop6:
  399. // modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight);
  400. // var Value6 = this.modbusTcp.GetUint(DeviceAddress.SiloUpperLimitWeight);
  401. // if (Value6 != null && Value6.ToString() != res.SiloUpperLimitWeight.ToString()) goto prop6;
  402. // prop7:
  403. // modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo);
  404. // var Value7 = this.modbusTcp.GetUint(DeviceAddress.LowerLimitWeightOfSilo);
  405. // if (Value7 != null && Value7.ToString() != res.LowerLimitWeightOfSilo.ToString()) goto prop7;
  406. // /*prop8:
  407. // var Value8 = this.modbusTcp.GetUint(DeviceAddress.StirringSpeed);
  408. // if (Value8 != null && Value8.ToString() != num.ToString()) goto prop8;*/
  409. // uint num = (uint)res.StirringSpeed * 100;
  410. // modbusTcp.SetUint(DeviceAddress.StirringSpeed, num);
  411. // MessageNotify.GetInstance.ShowRunLog($"{res.MaterialName},参数下发完成");
  412. // }
  413. // int Count = 0;
  414. //Start:
  415. // Count++;
  416. // modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入原料重量
  417. // modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
  418. // MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},下发次数{Count},柔性味魔方开始配料");
  419. // Thread.Sleep(200);
  420. // if (this.modbusTcp.ReadShort(DeviceAddress.DosingStatusFeedback) == (short)0 && Count <=10) goto Start;
  421. //}
  422. if (modbusTcp.Connected)
  423. {
  424. var res = Json<DevicePar>.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName);
  425. if (res != null)
  426. {
  427. modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight);
  428. modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight);
  429. modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration);
  430. modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration);
  431. modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed);
  432. modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight);
  433. modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo);
  434. modbusTcp.SetUint(DeviceAddress.StirringSpeed, (uint)res.StirringSpeed * 100);
  435. MessageNotify.GetInstance.ShowRunLog($"{res.MaterialName},参数下发完成");
  436. }
  437. modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入原料重量
  438. if (!modbusTcp.Write(DeviceAddress.Start, (ushort)1))//设备启动写入
  439. {
  440. MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},启动信号写入失败");
  441. }
  442. MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},柔性味魔方开始配料");
  443. }
  444. }
  445. }
  446. }