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

237 lines
9.2 KiB

  1. using BPASmartClient.Helper;
  2. using BPASmartClient.Modbus;
  3. using BPASmartClient.DosingSystem.ViewModel;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.Net.NetworkInformation;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using BPASmartClient.CustomResource.UserControls.MessageShow;
  14. using BPASmartClient.CustomResource.Pages.Model;
  15. using BPASmartClient.Model;
  16. namespace BPASmartClient.DosingSystem.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 = "192.168.0.";
  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 void Init()
  29. {
  30. IpAddressLines();
  31. ThreadManage.GetInstance().StartLong(new Action(() =>
  32. {
  33. if (IPQueues.Count >= IPLists.Count)
  34. IpAddressLines();
  35. Thread.Sleep(5000);
  36. }), "配料机设备上线监听", true);
  37. }
  38. public void Rescan()
  39. {
  40. InvalidIP.Clear();
  41. }
  42. public DeviceStatus GetDevice(string ip)
  43. {
  44. if (ip != null)
  45. {
  46. var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip);
  47. if (res != null) return res;
  48. }
  49. return new DeviceStatus();
  50. }
  51. private void IpAddressLines()
  52. {
  53. IPLists.Clear();
  54. IPQueues.Clear();
  55. for (int i = 1; i <= 255; i++)
  56. {
  57. if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}"))
  58. {
  59. IPLists.Add($"{IPSegment}{i}");
  60. }
  61. }
  62. IPLists.ForEach((item) =>
  63. {
  64. Ping myPing = new Ping();
  65. myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
  66. myPing.SendAsync(item, 1000, null);
  67. });
  68. }
  69. private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e)
  70. {
  71. if (e.Reply.Status == IPStatus.Success)
  72. {
  73. string ip = e.Reply.Address.ToString();
  74. if (!DeviceLists.ContainsKey(ip))
  75. {
  76. DeviceStatus DS = new DeviceStatus();
  77. DS.modbusTcp.IsReconnect = false;
  78. DS.modbusTcp.ConnectOk = new Action(() =>
  79. {
  80. string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20).Trim();//读取设备名称
  81. if (DeviceName.Length > 0)
  82. {
  83. DeviceLists.TryAdd(ip, DS);
  84. DeviceLists[ip].Init(DeviceName);
  85. DeviceLists[ip].modbusTcp.IsReconnect = false;
  86. App.Current.Dispatcher.Invoke(new Action(() =>
  87. {
  88. DeviceListViewModel.devices.Add(new Devices()
  89. {
  90. DeviceName = DeviceName,
  91. IpAddress = ip
  92. });//加入连接的(有名称的)设备列表
  93. for (int i = 0; i < Json<LocaPar>.Data.Recipes.Count; i++)
  94. {
  95. for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
  96. {
  97. if (Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
  98. {
  99. Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
  100. }
  101. }
  102. }
  103. if (Global.DeviceRawMaterials.Count > 0)
  104. {
  105. if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null)
  106. {
  107. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip ,RawMaterialSource = 1});
  108. }
  109. }
  110. else
  111. {
  112. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip , RawMaterialSource = 1 });
  113. }
  114. }));
  115. }
  116. else
  117. {
  118. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  119. }
  120. });
  121. DS.modbusTcp.ConnectFail = new Action(() =>
  122. {
  123. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  124. //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败");
  125. });
  126. DS.modbusTcp.Disconnect = new Action(() =>
  127. {
  128. if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip);
  129. var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip);
  130. if (res != null && DeviceListViewModel.devices.Contains(res))
  131. App.Current.Dispatcher.Invoke(new Action(() =>
  132. {
  133. DeviceListViewModel.devices.Remove(res);
  134. var item = Global.DeviceRawMaterials.FirstOrDefault(P => P.RawMaterialName == res.DeviceName);
  135. if (item != null) Global.DeviceRawMaterials.Remove(item);
  136. }));
  137. if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose();
  138. });
  139. Task.Run(new Action(() =>
  140. {
  141. DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接
  142. IPQueues.Enqueue(e.Reply.Address.ToString());
  143. }));
  144. }
  145. else IPQueues.Enqueue(e.Reply.Address.ToString());
  146. }
  147. else IPQueues.Enqueue(e.Reply.Address.ToString());
  148. }
  149. }
  150. public class DeviceStatus
  151. {
  152. #region 对象属性声明
  153. public string DeviceName = String.Empty;
  154. public string IpAddress => modbusTcp.IPAdress;
  155. /// <summary>
  156. /// 设备状态
  157. /// </summary>
  158. public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();
  159. public ModbusTcp modbusTcp = new ModbusTcp();
  160. public bool IsConnected => modbusTcp.Connected;
  161. #endregion
  162. public void Init(string DeviceName)
  163. {
  164. this.DeviceName = DeviceName;
  165. if (modbusTcp.Connected)
  166. {
  167. ThreadManage.GetInstance().StartLong(new Action(() =>
  168. {
  169. //获取设备运行状态
  170. var res = this.modbusTcp.Read(DeviceAddress.RunStatus);
  171. if (res != null && res is ushort[] ushortValue)
  172. {
  173. if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0];
  174. }
  175. //获取设备料仓剩余重量
  176. deviceStatus.WeightFeedback = this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);
  177. var resddd = this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);
  178. var rrr = this.modbusTcp.Read(DeviceAddress.WeightFeedback);
  179. var t = this.modbusTcp.GetReal(DeviceAddress.CutWeightFeedback);
  180. Thread.Sleep(100);
  181. }), $"{DeviceName} 开始监听", true);
  182. }
  183. }
  184. public void SetDeviceName(string name)
  185. {
  186. this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]);
  187. this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
  188. }
  189. public void StatusReset()
  190. {
  191. this.modbusTcp.Write(DeviceAddress.RunStatus, (ushort)0);
  192. }
  193. public void Dispose()
  194. {
  195. ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听");
  196. }
  197. public void Start(float Value)
  198. {
  199. if (modbusTcp.Connected)
  200. {
  201. modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入配方量
  202. modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
  203. }
  204. }
  205. }
  206. }