终端一体化运控平台
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

222 行
8.2 KiB

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