终端一体化运控平台
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

364 行
17 KiB

  1. using BPASmartClient.CustomResource.Pages.Model;
  2. using BPASmartClient.DosingHKProject.ViewModel;
  3. using BPASmartClient.DosingProject;
  4. using BPASmartClient.Helper;
  5. using BPASmartClient.Modbus;
  6. using BPASmartClient.Model;
  7. using System;
  8. using System.Collections.Concurrent;
  9. using System.Collections.Generic;
  10. using System.Collections.ObjectModel;
  11. using System.Linq;
  12. using System.Net.NetworkInformation;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. namespace BPASmartClient.DosingHKProject.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. 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);
  50. if (deviceIndex >= 0 && deviceIndex < devices.Count)
  51. {
  52. devices.ElementAt(deviceIndex).DeviceName = DeviceLists.ElementAt(i).Value.DeviceName;
  53. }
  54. }
  55. Thread.Sleep(200);
  56. }), "设备状态监听");
  57. }
  58. private void TestData()
  59. {
  60. for (int i = 0; i < 8; i++)
  61. {
  62. TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus()
  63. {
  64. DeviceName = $"测试设备{i + 1}",
  65. DeviceNum = i + 1,
  66. Weight = new Random().Next(100, 10000) / 100.0
  67. });
  68. devices.Add(new Devices()
  69. {
  70. DeviceName = $"测试设备{i + 1}",
  71. IpAddress = $"192.168.1.{i + 1}",
  72. });
  73. }
  74. for (int i = 8; i < 16; i++)
  75. {
  76. BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus()
  77. {
  78. DeviceName = $"测试设备{i + 1}",
  79. DeviceNum = i + 1,
  80. Weight = new Random().Next(100, 10000) / 100.0
  81. });
  82. devices.Add(new Devices()
  83. {
  84. DeviceName = $"测试设备{i + 1}",
  85. IpAddress = $"192.168.1.{i + 1}",
  86. });
  87. }
  88. }
  89. public void Init()
  90. {
  91. //TestData();
  92. IpAddressLines();
  93. DeviceDataInit();
  94. ThreadManage.GetInstance().StartLong(new Action(() =>
  95. {
  96. if (IPQueues.Count >= IPLists.Count)
  97. IpAddressLines();
  98. Thread.Sleep(5000);
  99. }), "配料机设备上线监听", true);
  100. }
  101. public void Rescan()
  102. {
  103. InvalidIP.Clear();
  104. }
  105. public DeviceStatus GetDevice(string ip)
  106. {
  107. if (ip != null)
  108. {
  109. var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip);
  110. if (res != null) return res;
  111. }
  112. return new DeviceStatus();
  113. }
  114. public DeviceStatus GetDevice(int location)
  115. {
  116. if (location > 0 && location < 16)
  117. {
  118. var res = DeviceLists.Values.FirstOrDefault(p => p.deviceStatus.DeviceNum == location);
  119. if (res != null) return res;
  120. }
  121. return new DeviceStatus();
  122. }
  123. public List<DeviceStatus> GetDevice()
  124. {
  125. List<DeviceStatus> deviceStatuses = new List<DeviceStatus>();
  126. foreach (var device in DeviceLists)
  127. {
  128. deviceStatuses.Add(device.Value);
  129. }
  130. return deviceStatuses;
  131. }
  132. private void IpAddressLines()
  133. {
  134. IPLists.Clear();
  135. IPQueues.Clear();
  136. for (int i = 1; i <= 255; i++)
  137. {
  138. if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}"))
  139. {
  140. IPLists.Add($"{IPSegment}{i}");
  141. }
  142. }
  143. IPLists.ForEach((item) =>
  144. {
  145. Ping myPing = new Ping();
  146. myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
  147. myPing.SendAsync(item, 1000, null);
  148. });
  149. }
  150. private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e)
  151. {
  152. if (e.Reply.Status == IPStatus.Success)
  153. {
  154. string ip = e.Reply.Address.ToString();
  155. if (!DeviceLists.ContainsKey(ip))
  156. {
  157. DeviceStatus DS = new DeviceStatus();
  158. DS.modbusTcp.IsReconnect = false;
  159. DS.modbusTcp.ConnectOk = new Action(() =>
  160. {
  161. string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20).Trim()?.Replace(" ", "");//读取设备名称
  162. if (DeviceName.Length > 0)
  163. {
  164. DeviceLists.TryAdd(ip, DS);
  165. DeviceLists[ip].Init(DeviceName);
  166. DeviceLists[ip].modbusTcp.IsReconnect = false;
  167. App.Current.Dispatcher.Invoke(new Action(() =>
  168. {
  169. //DeviceListViewModel.devices.Add(new Devices()
  170. //{
  171. // DeviceName = DeviceName,
  172. // IpAddress = ip
  173. //});//加入连接的(有名称的)设备列表
  174. devices.Add(new Devices() { DeviceName = DeviceName, IpAddress = ip });
  175. if (TopDeviceCurrentStatuses.Count <= 7)
  176. TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  177. else
  178. BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName });
  179. for (int i = 0; i < Json<LocaPar>.Data.Recipes.Count; i++)
  180. {
  181. for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
  182. {
  183. if (Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
  184. {
  185. Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
  186. }
  187. }
  188. }
  189. if (Global.DeviceRawMaterials.Count > 0)
  190. {
  191. if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null)
  192. {
  193. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  194. }
  195. }
  196. else
  197. {
  198. Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 });
  199. }
  200. }));
  201. }
  202. else
  203. {
  204. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  205. }
  206. });
  207. DS.modbusTcp.ConnectFail = new Action(() =>
  208. {
  209. if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
  210. //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败");
  211. });
  212. DS.modbusTcp.Disconnect = new Action(() =>
  213. {
  214. if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip);
  215. //var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip);
  216. var res = devices.FirstOrDefault(P => P.IpAddress == ip);
  217. //if (res != null && DeviceListViewModel.devices.Contains(res))
  218. if (res != null && devices.Contains(res))
  219. {
  220. App.Current.Dispatcher.Invoke(new Action(() =>
  221. {
  222. //DeviceListViewModel.devices.Remove(res);
  223. devices.Remove(res);
  224. var item = Global.DeviceRawMaterials.FirstOrDefault(P => P.RawMaterialName == res.DeviceName);
  225. if (item != null) Global.DeviceRawMaterials.Remove(item);
  226. var topRes = TopDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  227. var bottomRes = BottomDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName);
  228. if (topRes != null) TopDeviceCurrentStatuses.Remove(topRes);
  229. if (bottomRes != null) BottomDeviceCurrentStatuses.Remove(bottomRes);
  230. }));
  231. }
  232. if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose();
  233. });
  234. Task.Run(new Action(() =>
  235. {
  236. DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接
  237. IPQueues.Enqueue(e.Reply.Address.ToString());
  238. }));
  239. }
  240. else IPQueues.Enqueue(e.Reply.Address.ToString());
  241. }
  242. else IPQueues.Enqueue(e.Reply.Address.ToString());
  243. }
  244. }
  245. public class DeviceStatus
  246. {
  247. #region 对象属性声明
  248. public string DeviceName = String.Empty;
  249. public string IpAddress => modbusTcp.IPAdress;
  250. /// <summary>
  251. /// 设备状态
  252. /// </summary>
  253. public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();
  254. public ModbusTcp modbusTcp = new ModbusTcp();
  255. public bool IsConnected => modbusTcp.Connected;
  256. #endregion
  257. public void Init(string DeviceName)
  258. {
  259. this.DeviceName = DeviceName;
  260. AlarmHelper<AlarmInfo>.Init();
  261. if (modbusTcp.Connected)
  262. {
  263. ThreadManage.GetInstance().StartLong(new Action(() =>
  264. {
  265. //获取设备运行状态
  266. //var res = this.modbusTcp.Read(DeviceAddress.RunStatus);
  267. //if (res != null && res is ushort[] ushortValue)
  268. //{
  269. // if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0];
  270. //}
  271. deviceStatus.RunStatus = (ushort)this.modbusTcp.ReadShort(DeviceAddress.RunStatus); //获取设备运行状态
  272. deviceStatus.WeightFeedback = (float)this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);//获取设备料仓剩余重量
  273. deviceStatus.NowWeightFeedback = (float)this.modbusTcp.GetUint(DeviceAddress.CutWeightFeedback);//获取下料重量
  274. deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号
  275. deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码
  276. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).EStop1 = deviceStatus.DeviceAlarmCode.Get16bitValue(1);
  277. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).Servo = deviceStatus.DeviceAlarmCode.Get16bitValue(2);
  278. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).Inverter = deviceStatus.DeviceAlarmCode.Get16bitValue(3);
  279. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).EStop2 = deviceStatus.DeviceAlarmCode.Get16bitValue(7);
  280. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).SiloUpperLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(8);
  281. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).SiloLowerLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(9);
  282. AlarmHelper<AlarmInfo>.GetInstance(DeviceName).EStop1 = true;
  283. Thread.Sleep(10);
  284. }), $"{DeviceName} 开始监听", true);
  285. }
  286. }
  287. public void SetDeviceName(string name)
  288. {
  289. this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]);
  290. this.modbusTcp.SetString(DeviceAddress.DeviceName, name);
  291. }
  292. public void StatusReset()
  293. {
  294. this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1);
  295. //var res = modbusTcp.Read(DeviceAddress.RunStatus);
  296. }
  297. public void Dispose()
  298. {
  299. ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听");
  300. }
  301. public void Start(float Value)
  302. {
  303. if (modbusTcp.Connected)
  304. {
  305. modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入配方量
  306. modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入
  307. MessageNotify.GetInstance.ShowRunLog($"开始配料");
  308. //配料设备参数写入
  309. var res = Json<DevicePar>.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName);
  310. if (res != null)
  311. {
  312. modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight);
  313. modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight);
  314. modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration);
  315. modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration);
  316. modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed);
  317. modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight);
  318. modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo);
  319. modbusTcp.SetUint(DeviceAddress.StirringSpeed, (uint)res.StirringSpeed * 100);
  320. MessageNotify.GetInstance.ShowRunLog($"参数下发完成");
  321. }
  322. }
  323. }
  324. }
  325. }