using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.JXJFoodSmallStation.ViewModel; using BPASmartClient.Helper; using BPASmartClient.Modbus; using BPASmartClient.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.NetworkInformation; using System.Threading; using System.Threading.Tasks; namespace BPASmartClient.JXJFoodSmallStation.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 ObservableCollection TopDeviceCurrentStatuses { get; set; } = new ObservableCollection(); public ObservableCollection BottomDeviceCurrentStatuses { get; set; } = new ObservableCollection(); public ObservableCollection devices { get; set; } = new ObservableCollection(); private void DeviceDataInit() { ThreadManage.GetInstance().StartLong(new Action(() => { for (int i = 0; i < DeviceLists.Count; i++) { string deviceName = DeviceLists.ElementAt(i).Value.DeviceName; int TopIndex = Array.FindIndex(TopDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName); int BottomIndex = Array.FindIndex(BottomDeviceCurrentStatuses.ToArray(), p => p.DeviceName == deviceName); if (TopIndex >= 0 && TopIndex < TopDeviceCurrentStatuses.Count) { TopDeviceCurrentStatuses.ElementAt(TopIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback; TopDeviceCurrentStatuses.ElementAt(TopIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum; TopDeviceCurrentStatuses.ElementAt(TopIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus; } if (BottomIndex >= 0 && BottomIndex < BottomDeviceCurrentStatuses.Count) { BottomDeviceCurrentStatuses.ElementAt(BottomIndex).Weight = DeviceLists.ElementAt(i).Value.deviceStatus.WeightFeedback; BottomDeviceCurrentStatuses.ElementAt(BottomIndex).DeviceNum = DeviceLists.ElementAt(i).Value.deviceStatus.DeviceNum; BottomDeviceCurrentStatuses.ElementAt(BottomIndex).RunStatus = DeviceLists.ElementAt(i).Value.deviceStatus.RunStatus; } int deviceIndex = Array.FindIndex(devices.ToArray(), p => p.IpAddress == DeviceLists.ElementAt(i).Key && p.DeviceName != DeviceLists.ElementAt(i).Value.DeviceName); if (deviceIndex >= 0 && deviceIndex < devices.Count) { devices.ElementAt(deviceIndex).DeviceName = DeviceLists.ElementAt(i).Value.DeviceName; } } Thread.Sleep(200); }), "设备状态监听"); } private void TestData() { for (int i = 0; i < 8; i++) { TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = $"测试设备{i + 1}", DeviceNum = i + 1, RunStatus = 1, Weight = new Random().Next(100, 10000) / 100.0 }); devices.Add(new Devices() { DeviceName = $"测试设备{i + 1}", IpAddress = $"192.168.1.{i + 1}", }); } for (int i = 8; i < 16; i++) { BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = $"测试设备{i + 1}", DeviceNum = i + 1, RunStatus = 1, Weight = new Random().Next(100, 10000) / 100.0 }); devices.Add(new Devices() { DeviceName = $"测试设备{i + 1}", IpAddress = $"192.168.1.{i + 1}", }); } } public void Init() { //AlarmHelper.Init(); //AlarmHelper.Alarm.EStop1 = true; //TestData(); IpAddressLines(); DeviceDataInit(); 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(); } public DeviceStatus GetDevice(int location) { if (location > 0 && location < 16) { var res = DeviceLists.Values.FirstOrDefault(p => p.deviceStatus.DeviceNum == location); if (res != null) return res; } return new DeviceStatus(); } public List GetDevice() { List deviceStatuses = new List(); foreach (var device in DeviceLists) { deviceStatuses.Add(device.Value); } return deviceStatuses; } 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).Trim()?.Replace(" ", "");//读取设备名称 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 //});//加入连接的(有名称的)设备列表 devices.Add(new Devices() { DeviceName = DeviceName, IpAddress = ip }); if (TopDeviceCurrentStatuses.Count <= 7) TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName }); else BottomDeviceCurrentStatuses.Add(new DeviceCurrentStatus() { DeviceName = DeviceName }); 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 (Global.DeviceRawMaterials.Count > 0) { if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == DeviceName) == null) { Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 }); } } else { Global.DeviceRawMaterials.Add(new RawMaterialModel() { RawMaterialName = DeviceName, DeviceIp = ip, RawMaterialSource = 1 }); } })); } 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); var res = devices.FirstOrDefault(P => P.IpAddress == ip); //if (res != null && DeviceListViewModel.devices.Contains(res)) if (res != null && devices.Contains(res)) { App.Current.Dispatcher.Invoke(new Action(() => { //DeviceListViewModel.devices.Remove(res); devices.Remove(res); var item = Global.DeviceRawMaterials.FirstOrDefault(P => P.RawMaterialName == res.DeviceName); if (item != null) Global.DeviceRawMaterials.Remove(item); var topRes = TopDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName); var bottomRes = BottomDeviceCurrentStatuses.FirstOrDefault(p => p.DeviceName == res.DeviceName); if (topRes != null) TopDeviceCurrentStatuses.Remove(topRes); if (bottomRes != null) BottomDeviceCurrentStatuses.Remove(bottomRes); })); } 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) { modbusTcp.Show += new Action((s) => { if (s != null) MessageNotify.GetInstance.ShowRunLog(s); }); modbusTcp.ShowEx += new Action((s) => { if (s != null) MessageNotify.GetInstance.ShowRunLog(s); }); this.DeviceName = DeviceName; AlarmHelper.Init(); 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.RunStatus = (ushort)this.modbusTcp.ReadShort(DeviceAddress.RunStatus); //获取设备运行状态 deviceStatus.WeightFeedback = (Int16)this.modbusTcp.GetUint(DeviceAddress.WeightFeedback);//获取设备料仓剩余重量 deviceStatus.NowWeightFeedback = (float)this.modbusTcp.GetUint(DeviceAddress.CutWeightFeedback);//获取下料重量 deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号 deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码 AlarmHelper.GetInstance(DeviceName).EStop1 = deviceStatus.DeviceAlarmCode.Get16bitValue(1); AlarmHelper.GetInstance(DeviceName).Servo = deviceStatus.DeviceAlarmCode.Get16bitValue(2); AlarmHelper.GetInstance(DeviceName).Inverter = deviceStatus.DeviceAlarmCode.Get16bitValue(3); AlarmHelper.GetInstance(DeviceName).EStop2 = deviceStatus.DeviceAlarmCode.Get16bitValue(7); AlarmHelper.GetInstance(DeviceName).SiloUpperLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(8); AlarmHelper.GetInstance(DeviceName).SiloLowerLimit = deviceStatus.DeviceAlarmCode.Get16bitValue(9); Thread.Sleep(10); }), $"{DeviceName} 开始监听", true); } } public void SetDeviceName(string name) { this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]); this.modbusTcp.SetString(DeviceAddress.DeviceName, name); } public bool StatusReset() { return this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1); //var res = modbusTcp.Read(DeviceAddress.RunStatus); } public void Dispose() { ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听"); } public void Start(float Value) { if (modbusTcp.Connected) { modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入配方量 bool returnValue = modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入 if (returnValue) { MessageNotify.GetInstance.ShowRunLog($"发送成功" + DeviceAddress.Start); } else { MessageNotify.GetInstance.ShowRunLog($"发送失败" + DeviceAddress.Start); } //配料设备参数写入 var res = Json.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName); if (res != null) { modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight); modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight); modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration); modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration); modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed); modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight); modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo); modbusTcp.SetUint(DeviceAddress.StirringSpeed, (uint)res.StirringSpeed * 100); MessageNotify.GetInstance.ShowRunLog($"{res.MaterialName},参数下发完成"); } } } } }