using BPASmartClient.Helper; using BPASmartClient.Modbus; using BPASmartClient.DosingSystem.ViewModel; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; using BPASmartClient.CustomResource.UserControls.MessageShow; using BPASmartClient.CustomResource.Pages.Model; namespace BPASmartClient.DosingSystem.Model { public class DeviceInquire { private volatile static DeviceInquire _Instance; public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire()); private DeviceInquire() { } string IPSegment = "192.168.0."; ConcurrentDictionary DeviceLists = new ConcurrentDictionary(); List InvalidIP = new List();//无效 IP 集合 List IPLists = new List();//启动 Ping 任务IP集合 ConcurrentQueue IPQueues = new ConcurrentQueue();//pincomplete 完成队列 public void Init() { IpAddressLines(); ThreadManage.GetInstance().StartLong(new Action(() => { if (IPQueues.Count >= IPLists.Count) IpAddressLines(); Thread.Sleep(5000); }), "配料机设备上线监听", true); } public void Rescan() { InvalidIP.Clear(); } public DeviceStatus GetDevice(string ip) { if (ip != null) { var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip); if (res != null) return res; } return new DeviceStatus(); } private void IpAddressLines() { IPLists.Clear(); IPQueues.Clear(); for (int i = 1; i <= 255; i++) { if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}")) { IPLists.Add($"{IPSegment}{i}"); } } IPLists.ForEach((item) => { Ping myPing = new Ping(); myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted); myPing.SendAsync(item, 1000, null); }); } private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e) { if (e.Reply.Status == IPStatus.Success) { string ip = e.Reply.Address.ToString(); if (!DeviceLists.ContainsKey(ip)) { DeviceStatus DS = new DeviceStatus(); DS.modbusTcp.IsReconnect = false; DS.modbusTcp.ConnectOk = new Action(() => { string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20);//读取设备名称 if (DeviceName.Length > 0) { DeviceLists.TryAdd(ip, DS); DeviceLists[ip].Init(DeviceName); DeviceLists[ip].modbusTcp.IsReconnect = false; App.Current.Dispatcher.Invoke(new Action(() => { DeviceListViewModel.devices.Add(new Devices() { DeviceName = DeviceName, IpAddress = ip });//加入连接的(有名称的)设备列表 for (int i = 0; i < Json.Data.Recipes.Count; i++) { for (int m = 0; m < Json.Data.Recipes.ElementAt(i).RawMaterials.Count; m++) { if (Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip) { Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName; } } } if (!NewRecipeViewModel.RawMaterialNames.Contains(DeviceName)) NewRecipeViewModel.RawMaterialNames.Add(DeviceName); })); } else { if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); } }); DS.modbusTcp.ConnectFail = new Action(() => { if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败"); }); DS.modbusTcp.Disconnect = new Action(() => { if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip); var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip); if (res != null && DeviceListViewModel.devices.Contains(res)) App.Current.Dispatcher.Invoke(new Action(() => { DeviceListViewModel.devices.Remove(res); if (NewRecipeViewModel.RawMaterialNames.Contains(res.DeviceName)) NewRecipeViewModel.RawMaterialNames.Remove(res.DeviceName); })); if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose(); }); Task.Run(new Action(() => { DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接 IPQueues.Enqueue(e.Reply.Address.ToString()); })); } else IPQueues.Enqueue(e.Reply.Address.ToString()); } else IPQueues.Enqueue(e.Reply.Address.ToString()); } } public class DeviceStatus { #region 对象属性声明 public string DeviceName = String.Empty; public string IpAddress => modbusTcp.IPAdress; /// /// 设备状态 /// public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus(); public ModbusTcp modbusTcp = new ModbusTcp(); public bool IsConnected => modbusTcp.Connected; #endregion public void Init(string DeviceName) { this.DeviceName = DeviceName; if (modbusTcp.Connected) { ThreadManage.GetInstance().StartLong(new Action(() => { //获取设备运行状态 var res = this.modbusTcp.Read(DeviceAddress.RunStatus); if (res != null && res is ushort[] ushortValue) { if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0]; } //获取设备料仓剩余重量 deviceStatus.WeightFeedback = this.modbusTcp.GetUint(DeviceAddress.WeightFeedback) * 10; deviceStatus.CutWeightFeedback = this.modbusTcp.GetUint(DeviceAddress.CutWeightFeedback) * 10; Thread.Sleep(100); }), $"{DeviceName} 开始监听", true); } } public void SetDeviceName(string name) { this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]); this.modbusTcp.SetString(DeviceAddress.DeviceName, name); } public void StatusReset() { this.modbusTcp.Write(DeviceAddress.RunStatus, (ushort)0); } public void Dispose() { ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听"); } public void Start(uint Value) { if (modbusTcp.Connected) { modbusTcp.SetUint(DeviceAddress.WeightSet, Value);//写入配方量 modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入 } } } }