终端一体化运控平台
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

234 rader
9.7 KiB

  1. using BPASmartClient.Helper;
  2. using BPASmartClient.Modbus;
  3. using BPASmartClient.JXJFoodSmallStation.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. namespace BPASmartClient.JXJFoodSmallStation.Model
  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. ConcurrentDictionary<int, DeviceStatus> DeviceLocation = new ConcurrentDictionary<int, DeviceStatus>();
  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. public DeviceStatus GetDeviceObject(int location)
  52. {
  53. if (location >= 1 && location <= 15)
  54. {
  55. var res = DeviceLists.Values.FirstOrDefault(p => p.RawMaterialLocation == location);
  56. if (res != null) return res;
  57. }
  58. return new DeviceStatus();
  59. }
  60. private void IpAddressLines()
  61. {
  62. IPLists.Clear();
  63. IPQueues.Clear();
  64. for (int i = 1; i <= 255; i++)
  65. {
  66. if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}"))
  67. {
  68. IPLists.Add($"{IPSegment}{i}");
  69. }
  70. }
  71. IPLists.ForEach((item) =>
  72. {
  73. Ping myPing = new Ping();
  74. myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
  75. myPing.SendAsync(item, 1000, null);
  76. });
  77. }
  78. private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e)
  79. {
  80. if (e.Reply.Status == IPStatus.Success)
  81. {
  82. string ip = e.Reply.Address.ToString();
  83. if (!DeviceLists.ContainsKey(ip))
  84. {
  85. DeviceStatus DS = new DeviceStatus();
  86. DS.modbusTcp.IsReconnect = false;
  87. DS.modbusTcp.ConnectOk = new Action(() =>
  88. {
  89. string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20);//读取设备名称
  90. int rawMaterialLocation = DS.modbusTcp.GetAddress(DeviceAddress.Location);
  91. if (DeviceName.Length > 0)
  92. {
  93. DeviceLists.TryAdd(ip, DS);
  94. DeviceLists[ip].Init(DeviceName, rawMaterialLocation);
  95. DeviceLists[ip].modbusTcp.IsReconnect = false;
  96. App.Current.Dispatcher.Invoke(new Action(() =>
  97. {
  98. DeviceListViewModel.devices.Add(new Devices()
  99. {
  100. DeviceName = DeviceName,
  101. IpAddress = ip
  102. });//加入连接的(有名称的)设备列表
  103. for (int i = 0; i < Json<LocaPar>.Data.Recipes.Count; i++)
  104. {
  105. for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
  106. {
  107. if (Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
  108. {
  109. Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
  110. Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMateriaLocation = rawMaterialLocation;
  111. }
  112. }
  113. }
  114. if (!NewRecipeViewModel.RawMaterialNames.Contains(DeviceName))
  115. NewRecipeViewModel.RawMaterialNames.Add(DeviceName);
  116. }));
  117. }
  118. else
  119. {
  120. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  121. }
  122. });
  123. DS.modbusTcp.ConnectFail = new Action(() =>
  124. {
  125. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  126. //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败");
  127. });
  128. DS.modbusTcp.Disconnect = new Action(() =>
  129. {
  130. if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip);
  131. var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip);
  132. if (res != null && DeviceListViewModel.devices.Contains(res))
  133. App.Current.Dispatcher.Invoke(new Action(() =>
  134. {
  135. DeviceListViewModel.devices.Remove(res);
  136. if (NewRecipeViewModel.RawMaterialNames.Contains(res.DeviceName))
  137. NewRecipeViewModel.RawMaterialNames.Remove(res.DeviceName);
  138. }));
  139. if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose();
  140. });
  141. Task.Run(new Action(() =>
  142. {
  143. DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接
  144. IPQueues.Enqueue(e.Reply.Address.ToString());
  145. }));
  146. }
  147. else IPQueues.Enqueue(e.Reply.Address.ToString());
  148. }
  149. else IPQueues.Enqueue(e.Reply.Address.ToString());
  150. }
  151. }
  152. public class DeviceStatus
  153. {
  154. #region 对象属性声明
  155. public string DeviceName = String.Empty;
  156. public string IpAddress => modbusTcp.IPAdress;
  157. public bool IsConnected => modbusTcp.Connected;
  158. public int RawMaterialLocation { get; set; }
  159. /// <summary>
  160. /// 设备状态
  161. /// </summary>
  162. public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();
  163. public ModbusTcp modbusTcp = new ModbusTcp();
  164. #endregion
  165. public void Init(string DeviceName,int rawMaterialLocation)
  166. {
  167. this.DeviceName = DeviceName;
  168. this.RawMaterialLocation = rawMaterialLocation;
  169. if (modbusTcp.Connected)
  170. {
  171. ThreadManage.GetInstance().StartLong(new Action(() =>
  172. {
  173. //获取设备运行状态
  174. var res = this.modbusTcp.Read(DeviceAddress.RunStatus);
  175. if (res != null && res is ushort[] ushortValue)
  176. {
  177. if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0];
  178. }
  179. //获取设备料仓剩余重量
  180. deviceStatus.WeightFeedback = this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);
  181. deviceStatus.CutWeightFeedback = this.modbusTcp.GetUint(DeviceAddress.CutWeightFeedback);
  182. deviceStatus.RawMaterialType =(ushort) this.modbusTcp.GetUint(DeviceAddress.RawMaterialType);
  183. Thread.Sleep(100);
  184. }), $"{DeviceName} 开始监听", true);
  185. }
  186. }
  187. public void SetDeviceName(string name)
  188. {
  189. this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]);
  190. this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
  191. }
  192. public void StatusReset()
  193. {
  194. this.modbusTcp.Write(DeviceAddress.RunStatus, (ushort)0);
  195. }
  196. public void OutRawMaterialReset()
  197. {
  198. this.modbusTcp.Write(DeviceAddress.OutRawMaterialFinish, (ushort)0);
  199. }
  200. public void Dispose()
  201. {
  202. ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听");
  203. }
  204. /// <summary>
  205. /// 设置出料重量,触发出料信号
  206. /// </summary>
  207. /// <param name="Value"></param>
  208. public void Start(uint Value)
  209. {
  210. if (modbusTcp.Connected)
  211. {
  212. modbusTcp.SetUint(DeviceAddress.WeightSet, Value);//写入配方量
  213. modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
  214. }
  215. }
  216. }
  217. }