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

323 lines
15 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. using System.Collections.ObjectModel;
  16. using BPASmartClient.Model;
  17. namespace BPASmartClient.JXJFoodSmallStation.Model
  18. {
  19. public class DeviceInquire
  20. {
  21. private volatile static DeviceInquire _Instance;
  22. public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire());
  23. private DeviceInquire() { }
  24. string IPSegment = "192.168.0.";
  25. ConcurrentDictionary<string, DeviceStatus> DeviceLists = new ConcurrentDictionary<string, DeviceStatus>();
  26. List<string> InvalidIP = new List<string>();//无效 IP 集合
  27. List<string> IPLists = new List<string>();//启动 Ping 任务IP集合
  28. ConcurrentQueue<string> IPQueues = new ConcurrentQueue<string>();//pincomplete 完成队列
  29. public ObservableCollection<DeviceCurrentStatus> TopDeviceCurrentStatuses { get; set; } = new ObservableCollection<DeviceCurrentStatus>();
  30. public ObservableCollection<DeviceCurrentStatus> BottomDeviceCurrentStatuses { get; set; } = new ObservableCollection<DeviceCurrentStatus>();
  31. public ObservableCollection<Devices> devices { get; set; } = new ObservableCollection<Devices>();
  32. private void DeviceDataInit()
  33. {
  34. ThreadManage.GetInstance().StartLong(new Action(() =>
  35. {
  36. for (int i = 0; i < DeviceLists.Count; i++)
  37. {
  38. string deviceName = DeviceLists.ElementAt(i).Value.DeviceName;
  39. int TopIndex = Array.FindIndex(TopDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName);
  40. int BottomIndex = Array.FindIndex(BottomDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName);
  41. if (TopIndex >= 0 && TopIndex < TopDeviceCurrentStatuses.Count)
  42. {
  43. TopDeviceCurrentStatuses.ElementAt(TopIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback;
  44. TopDeviceCurrentStatuses.ElementAt(TopIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum;
  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. }
  51. int deviceIndex = Array.FindIndex(devices.ToArray(), p => p.IpAddress == DeviceLists.ElementAt(i).Key);
  52. if (deviceIndex >= 0 && deviceIndex < devices.Count)
  53. {
  54. devices.ElementAt(i).DeviceName = DeviceLists.ElementAt(i).Value.DeviceName;
  55. }
  56. }
  57. Thread.Sleep(200);
  58. }), "设备状态监听");
  59. }
  60. public void Init()
  61. {
  62. devices.Add(new Devices() { DeviceName = "测试", IpAddress = "192.168.0.1" });
  63. IpAddressLines();
  64. DeviceDataInit();
  65. ThreadManage.GetInstance().StartLong(new Action(() =>
  66. {
  67. if (IPQueues.Count >= IPLists.Count)
  68. IpAddressLines();
  69. Thread.Sleep(5000);
  70. }), "配料机设备上线监听", true);
  71. }
  72. public void Rescan()
  73. {
  74. InvalidIP.Clear();
  75. }
  76. public DeviceStatus GetDevice(string ip)
  77. {
  78. if (ip != null)
  79. {
  80. var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip);
  81. if (res != null) return res;
  82. }
  83. return new DeviceStatus();
  84. }
  85. public List<DeviceStatus> GetDevice()
  86. {
  87. List<DeviceStatus> deviceStatuses = new List<DeviceStatus>();
  88. foreach (var device in DeviceLists)
  89. {
  90. deviceStatuses.Add(device.Value);
  91. }
  92. return deviceStatuses;
  93. }
  94. private void IpAddressLines()
  95. {
  96. IPLists.Clear();
  97. IPQueues.Clear();
  98. for (int i = 1; i <= 255; i++)
  99. {
  100. if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}"))
  101. {
  102. IPLists.Add($"{IPSegment}{i}");
  103. }
  104. }
  105. IPLists.ForEach((item) =>
  106. {
  107. Ping myPing = new Ping();
  108. myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
  109. myPing.SendAsync(item, 1000, null);
  110. });
  111. }
  112. private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e)
  113. {
  114. if (e.Reply.Status == IPStatus.Success)
  115. {
  116. string ip = e.Reply.Address.ToString();
  117. if (!DeviceLists.ContainsKey(ip))
  118. {
  119. DeviceStatus DS = new DeviceStatus();
  120. DS.modbusTcp.IsReconnect = false;
  121. DS.modbusTcp.ConnectOk = new Action(() =>
  122. {
  123. string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20).Trim()?.Replace(" ", "");//读取设备名称
  124. if (DeviceName.Length > 0)
  125. {
  126. DeviceLists.TryAdd(ip, DS);
  127. DeviceLists[ip].Init(DeviceName);
  128. DeviceLists[ip].modbusTcp.IsReconnect = false;
  129. App.Current.Dispatcher.Invoke(new Action(() =>
  130. {
  131. //DeviceListViewModel.devices.Add(new Devices()
  132. //{
  133. // DeviceName = DeviceName,
  134. // IpAddress = ip
  135. //});//加入连接的(有名称的)设备列表
  136. devices.Add(new Devices() { DeviceName = DeviceName, IpAddress = ip });
  137. if (TopDeviceCurrentStatuses.Count <= 8)
  138. TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  139. else
  140. BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  141. for (int i = 0; i < Json<LocaPar>.Data.Recipes.Count; i++)
  142. {
  143. for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
  144. {
  145. if (Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
  146. {
  147. Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
  148. }
  149. }
  150. }
  151. if (Global.DeviceRawMaterials.Count > 0)
  152. {
  153. if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null)
  154. {
  155. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  156. }
  157. }
  158. else
  159. {
  160. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  161. }
  162. }));
  163. }
  164. else
  165. {
  166. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  167. }
  168. });
  169. DS.modbusTcp.ConnectFail = new Action(() =>
  170. {
  171. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  172. //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败");
  173. });
  174. DS.modbusTcp.Disconnect = new Action(() =>
  175. {
  176. if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip);
  177. //var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip);
  178. var res = devices.FirstOrDefault(P => P.IpAddress == ip);
  179. //if (res != null && DeviceListViewModel.devices.Contains(res))
  180. if (res != null && devices.Contains(res))
  181. {
  182. App.Current.Dispatcher.Invoke(new Action(() =>
  183. {
  184. //DeviceListViewModel.devices.Remove(res);
  185. devices.Remove(res);
  186. var item = Global.DeviceRawMaterials.FirstOrDefault(P => P.RawMaterialName == res.DeviceName);
  187. if (item != null) Global.DeviceRawMaterials.Remove(item);
  188. var topRes = TopDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  189. var bottomRes = BottomDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  190. if (topRes != null) TopDeviceCurrentStatuses.Remove(topRes);
  191. if (bottomRes != null) BottomDeviceCurrentStatuses.Remove(bottomRes);
  192. }));
  193. }
  194. if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose();
  195. });
  196. Task.Run(new Action(() =>
  197. {
  198. DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接
  199. IPQueues.Enqueue(e.Reply.Address.ToString());
  200. }));
  201. }
  202. else IPQueues.Enqueue(e.Reply.Address.ToString());
  203. }
  204. else IPQueues.Enqueue(e.Reply.Address.ToString());
  205. }
  206. }
  207. public class DeviceStatus
  208. {
  209. #region 对象属性声明
  210. public string DeviceName = String.Empty;
  211. public string IpAddress => modbusTcp.IPAdress;
  212. /// <summary>
  213. /// 设备状态
  214. /// </summary>
  215. public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();
  216. public ModbusTcp modbusTcp = new ModbusTcp();
  217. public bool IsConnected => modbusTcp.Connected;
  218. #endregion
  219. public void Init(string DeviceName)
  220. {
  221. this.DeviceName = DeviceName;
  222. AlarmHelper<AlarmInfo>.Init();
  223. if (modbusTcp.Connected)
  224. {
  225. ThreadManage.GetInstance().StartLong(new Action(() =>
  226. {
  227. //获取设备运行状态
  228. //var res = this.modbusTcp.Read(DeviceAddress.RunStatus);
  229. //if (res != null && res is ushort[] ushortValue)
  230. //{
  231. // if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0];
  232. //}
  233. this.DeviceName = modbusTcp.GetString(DeviceAddress.DeviceName, 20).Trim()?.Replace(" ", "");
  234. deviceStatus.RunStatus = (ushort)this.modbusTcp.ReadShort(DeviceAddress.RunStatus); //获取设备运行状态
  235. deviceStatus.WeightFeedback = (float)this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);//获取设备料仓剩余重量
  236. deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号
  237. deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码
  238. AlarmHelper<AlarmInfo>.Alarm.EStop1 = deviceStatus.DeviceAlarmCode.Get16bitValue(1);
  239. AlarmHelper<AlarmInfo>.Alarm.Servo = deviceStatus.DeviceAlarmCode.Get16bitValue(2);
  240. AlarmHelper<AlarmInfo>.Alarm.Inverter = deviceStatus.DeviceAlarmCode.Get16bitValue(3);
  241. AlarmHelper<AlarmInfo>.Alarm.EStop2 = deviceStatus.DeviceAlarmCode.Get16bitValue(7);
  242. AlarmHelper<AlarmInfo>.Alarm.SiloUpperLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(8);
  243. AlarmHelper<AlarmInfo>.Alarm.SiloLowerLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(9);
  244. Thread.Sleep(100);
  245. }), $"{DeviceName} 开始监听", true);
  246. }
  247. }
  248. public void SetDeviceName(string name)
  249. {
  250. this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]);
  251. this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
  252. }
  253. public void StatusReset()
  254. {
  255. this.modbusTcp.Write(DeviceAddress.RunStatus, (ushort)0);
  256. }
  257. public void Dispose()
  258. {
  259. ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听");
  260. }
  261. public void Start(float Value)
  262. {
  263. if (modbusTcp.Connected)
  264. {
  265. modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入配方量
  266. modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
  267. //配料设备参数写入
  268. var res = Json<DevicePar>.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName);
  269. if (res != null)
  270. {
  271. modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight);
  272. modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight);
  273. modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration);
  274. modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration);
  275. modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed);
  276. modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight);
  277. modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo);
  278. modbusTcp.SetUint(DeviceAddress.StirringSpeed, (uint)res.StirringSpeed);
  279. }
  280. }
  281. }
  282. }
  283. }