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

367 行
17 KiB

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