using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.JXJFoodSmallStation.ViewModel; using BPA.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; using System.Configuration; using System.Diagnostics; namespace BPASmartClient.JXJFoodSmallStation.Model { public class DeviceInquire { private volatile static DeviceInquire _Instance; public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire()); private DeviceInquire() { } string IPSegment = "107.107.2."; 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() { TaskManage.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; } if (!TaskManage.GetInstance.IsContainsKey($"{deviceName} 开始监听")) { DeviceLists[DeviceLists.ElementAt(i).Key].Init(deviceName); } } Thread.Sleep(200); }), "设备状态监听", true); } 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; //IPSegment = ConfigurationManager.AppSettings["RawMaterial_IP"]; //TestData(); IpAddressLines(); DeviceDataInit(); TaskManage.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}"); } }*/ //吉香居特定IP for (int i = 0; i < 15; i++) { IPLists.Add($"{IPSegment}{i + 69}"); } 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 != null && 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.RemoteRecipes.Count; i++) { for (int m = 0; m < Json.Data.RemoteRecipes.ElementAt(i).RawMaterials.Count; m++) { if (Json.Data.RemoteRecipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip) { Json.Data.RemoteRecipes.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); if (DeviceLists.ContainsKey(ip)) { DeviceLists[ip].Dispose(); var res11 = DeviceLists[ip]; DeviceLists.TryRemove(ip, out res11); } } }); DS.modbusTcp.ConnectFail = new Action(() => { //if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败"); if (DeviceLists.ContainsKey(ip)) { DeviceLists[ip].Dispose(); var res11 = DeviceLists[ip]; DeviceLists.TryRemove(ip, out res11); } }); DS.modbusTcp.Disconnect = new Action(() => { if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip); var res = devices.FirstOrDefault(P => P.IpAddress == ip); if (res != null && devices.Contains(res)) { App.Current.Dispatcher.Invoke(new Action(() => { 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(); var res11 = DeviceLists[ip]; DeviceLists.TryRemove(ip, out res11); } }); Task.Run(new Action(() => { DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接 IPQueues.Enqueue(e.Reply.Address.ToString()); })); } else { IPQueues.Enqueue(e.Reply.Address.ToString()); } } else { if (e.Reply != null) 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) { TaskManage.GetInstance.StartLong(new Action(() => { if (modbusTcp.Connected) { deviceStatus.RunStatus = (ushort)this.modbusTcp.ReadShort(DeviceAddress.RunStatus); //获取设备运行状态 deviceStatus.WeightFeedback = this.modbusTcp.ReadShort(DeviceAddress.WeightFeedback);//获取设备料仓剩余重量 deviceStatus.NowWeightFeedback = this.modbusTcp.GetReal(DeviceAddress.CutWeightFeedback);//获取下料重量 deviceStatus.DeviceNum = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceNum);//获取设备编号 deviceStatus.DeviceAlarmCode = (ushort)this.modbusTcp.ReadShort(DeviceAddress.DeviceAlarmCode);//获取设备故障编码 AlarmHelper.GetInstance(DeviceName).EStop1 = deviceStatus.DeviceAlarmCode.GetBitValue(1); AlarmHelper.GetInstance(DeviceName).Servo = deviceStatus.DeviceAlarmCode.GetBitValue(2); AlarmHelper.GetInstance(DeviceName).Inverter = deviceStatus.DeviceAlarmCode.GetBitValue(3); AlarmHelper.GetInstance(DeviceName).EStop2 = deviceStatus.DeviceAlarmCode.GetBitValue(7); AlarmHelper.GetInstance(DeviceName).SiloUpperLimit = deviceStatus.DeviceAlarmCode.GetBitValue(8); AlarmHelper.GetInstance(DeviceName).SiloLowerLimit = deviceStatus.DeviceAlarmCode.GetBitValue(9); //允许配料即产线气缸抬起,发送给味魔方 if (deviceStatus.DeviceNum >= 1 && deviceStatus.DeviceNum <= 15) { if (GVL_SmallStation.GetInstance.plcReadDataDB3.StockBinAllowIssue[deviceStatus.DeviceNum - 1]) { this.modbusTcp.Write("LW41", (ushort)1); GVL_SmallStation.GetInstance.StockBinCylinderStatus.SetBitValue((byte)(deviceStatus.DeviceNum), true); } else { this.modbusTcp.Write("LW41", (ushort)0); GVL_SmallStation.GetInstance.StockBinCylinderStatus.SetBitValue((byte)(deviceStatus.DeviceNum), false); } } 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 void OpenLid() { //modbusTcp.Write(DeviceAddress.OpenLid, (ushort)1); } /// /// 关盖 /// public void CloseLid() { //modbusTcp.Write(DeviceAddress.CloseLid, (ushort)1); } public bool StatusReset() { return this.modbusTcp.Write(DeviceAddress.FinfishStatus, (ushort)1); //var res = modbusTcp.Read(DeviceAddress.RunStatus); } public void Dispose() { TaskManage.GetInstance.StopTask($"{DeviceName} 开始监听"); } public void Start(float Value) { //if (modbusTcp.Connected) //{ // var res = Json.Data.deviceParModels.FirstOrDefault(p => p.MaterialName == DeviceName); // if (res != null) // { // prop1: // modbusTcp.SetReal(DeviceAddress.SlowlyAddWeight, res.SlowlyAddWeight); // var Value1 = (float)this.modbusTcp.GetReal(DeviceAddress.SlowlyAddWeight); // if (Value1 != null && Value1.ToString() != res.SlowlyAddWeight.ToString()) goto prop1; // prop2: // modbusTcp.SetReal(DeviceAddress.PreCloseValveWeight, res.PreCloseValveWeight); // var Value2 = (float)this.modbusTcp.GetReal(DeviceAddress.PreCloseValveWeight); // if (Value2 != null && Value2.ToString() != res.PreCloseValveWeight.ToString()) goto prop2; // prop3: // modbusTcp.SetUint(DeviceAddress.RapidAcceleration, (uint)res.RapidAcceleration); // var Value3 = this.modbusTcp.GetUint(DeviceAddress.RapidAcceleration); // if (Value3 != null && Value3.ToString() != res.RapidAcceleration.ToString()) goto prop3; // prop4: // modbusTcp.SetUint(DeviceAddress.SlowAcceleration, (uint)res.SlowAcceleration); // var Value4 = this.modbusTcp.GetUint(DeviceAddress.SlowAcceleration); // if (Value4 != null && Value4.ToString() != res.SlowAcceleration.ToString()) goto prop4; // prop5: // modbusTcp.SetUint(DeviceAddress.ServoManualSpeed, (uint)res.ServoManualSpeed); // var Value5 = this.modbusTcp.GetUint(DeviceAddress.ServoManualSpeed); // if (Value5 != null && Value5.ToString() != res.ServoManualSpeed.ToString()) goto prop5; // prop6: // modbusTcp.SetUint(DeviceAddress.SiloUpperLimitWeight, (uint)res.SiloUpperLimitWeight); // var Value6 = this.modbusTcp.GetUint(DeviceAddress.SiloUpperLimitWeight); // if (Value6 != null && Value6.ToString() != res.SiloUpperLimitWeight.ToString()) goto prop6; // prop7: // modbusTcp.SetUint(DeviceAddress.LowerLimitWeightOfSilo, (uint)res.LowerLimitWeightOfSilo); // var Value7 = this.modbusTcp.GetUint(DeviceAddress.LowerLimitWeightOfSilo); // if (Value7 != null && Value7.ToString() != res.LowerLimitWeightOfSilo.ToString()) goto prop7; // /*prop8: // var Value8 = this.modbusTcp.GetUint(DeviceAddress.StirringSpeed); // if (Value8 != null && Value8.ToString() != num.ToString()) goto prop8;*/ // uint num = (uint)res.StirringSpeed * 100; // modbusTcp.SetUint(DeviceAddress.StirringSpeed, num); // MessageNotify.GetInstance.ShowRunLog($"{res.MaterialName},参数下发完成"); // } // int Count = 0; //Start: // Count++; // modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入原料重量 // modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入 // MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},下发次数{Count},柔性味魔方开始配料"); // Thread.Sleep(200); // if (this.modbusTcp.ReadShort(DeviceAddress.DosingStatusFeedback) == (short)0 && Count <=10) goto Start; //} if (modbusTcp.Connected) { 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},参数下发完成"); } modbusTcp.SetReal(DeviceAddress.WeightSet, Value);//写入原料重量 if (!modbusTcp.Write(DeviceAddress.Start, (ushort)1))//设备启动写入 { MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},启动信号写入失败"); } MessageNotify.GetInstance.ShowRunLog($"{DeviceName},设置重量:{Value},柔性味魔方开始配料"); } } } }