终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

438 lines
21 KiB

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