diff --git a/BPASmart.Model/CommDeviceModel/AddressConvert.cs b/BPASmart.Model/CommDeviceModel/AddressConvert.cs new file mode 100644 index 00000000..edc897f4 --- /dev/null +++ b/BPASmart.Model/CommDeviceModel/AddressConvert.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmart.Model +{ + public class AddressConvert + { + private volatile static AddressConvert _Instance; + public static AddressConvert GetInstance => _Instance ?? (_Instance = new AddressConvert()); + private AddressConvert() { } + + public int PlcConverter(ICommunicationDevice device, string Address) + { + int address = -1; + if (Address != null && int.TryParse(Address, out int result)) return result; + if (device != null && Address != null && Address.Length > 0) + { + switch (device) + { + case Invoance _tempInvoance: + if (Address.ToUpper().Contains("LW") && Address.Length >= 3) + { + var res = Address.Substring(2); + if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress; + } + break; + case kinco _tempKinco: + if (Address.ToUpper().Contains("M") && Address.Length >= 4) + { + var res = Address.Substring(1).Split('.'); + if (res != null && res.Length == 2) + { + if (int.TryParse(res[0], out int firstAddress) && int.TryParse(res[1], out int ExitAddress)) + { + if (ExitAddress >= 0 && ExitAddress <= 7) + { + return (firstAddress * 8) + 320 + ExitAddress; + } + } + } + } + else if ((Address.ToUpper().Contains("VW") || Address.ToUpper().Contains("VD")) && Address.Length >= 3) + { + var res = Address.Substring(2); + if (res != null && int.TryParse(res, out int tempAddress)) return (tempAddress / 2) + 100; + } + break; + case KincoOneMachine _tempKincoOneMachine: + if (Address.ToUpper().Contains("D") && Address.Length >= 2) + { + var res = Address.Substring(1); + if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress; + } + break; + default: + break; + } + } + return address; + } + + } +} diff --git a/BPASmart.Model/CommunicationModel.cs b/BPASmart.Model/CommunicationModel.cs index 9b70221f..41ce9d46 100644 --- a/BPASmart.Model/CommunicationModel.cs +++ b/BPASmart.Model/CommunicationModel.cs @@ -33,7 +33,9 @@ namespace BPASmart.Model public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } private string _mDeviceName; - + /// + /// 通讯模块名称 + /// public string ModelName { get { return _mModelName; } set { _mModelName = value; OnPropertyChanged(); } } private string _mModelName; diff --git a/BPASmart.Model/PublishInfo.cs b/BPASmart.Model/PublishInfo.cs new file mode 100644 index 00000000..81ee14e4 --- /dev/null +++ b/BPASmart.Model/PublishInfo.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmart.Model +{ + public class PublishInfo + { + public List PublishModels { get; set; } = new List(); + } +} diff --git a/BPASmart.Model/PublishModel.cs b/BPASmart.Model/PublishModel.cs new file mode 100644 index 00000000..6377a3fa --- /dev/null +++ b/BPASmart.Model/PublishModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmart.Model +{ + public class PublishModel + { + public string DeviceName { get; set; } + public string Address { get; set; } + public string Value { get; set; } + public int Sleep { get; set; } + + } +} diff --git a/BPASmart.Model/ReadDataModel.cs b/BPASmart.Model/ReadDataModel.cs new file mode 100644 index 00000000..2ffbc74d --- /dev/null +++ b/BPASmart.Model/ReadDataModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmart.Model +{ + public class ReadDataModel + { + public ushort StartAddress { get; set; } + + public ushort Length { get; set; } + + + } +} diff --git a/BPASmart.Model/VariableInfo.cs b/BPASmart.Model/VariableInfo.cs index 26c62e6c..faf78dae 100644 --- a/BPASmart.Model/VariableInfo.cs +++ b/BPASmart.Model/VariableInfo.cs @@ -11,13 +11,19 @@ using Newtonsoft.Json; using System.Collections.ObjectModel; using System.Windows; using Microsoft.Toolkit.Mvvm.Input; +using System.Reflection; namespace BPASmart.Model { public class VariableInfo : AlarmSet { + private ICommunicationDevice DeviceType; public VariableInfo(params object[] s) { + if (s != null && s.Length >= 0) + { + DeviceType = s[0] as ICommunicationDevice; + } CancelCommand = new RelayCommand(() => { IsOpen = false; }); ConfirmCommand = new RelayCommand(() => { IsOpen = false; }); } @@ -30,7 +36,7 @@ namespace BPASmart.Model /// public string VarName { - get { return _mVarName; } + get { return _mVarName.Trim()?.Replace(" ", ""); } set { _mVarName = value; @@ -43,9 +49,24 @@ namespace BPASmart.Model /// /// 地址 /// - public string Address { get { return _mAddress; } set { _mAddress = value; OnPropertyChanged(); } } + public string Address + { + get { return _mAddress.Trim()?.Replace(" ", "").ToUpper(); } + set + { + _mAddress = value; + OnPropertyChanged(); + int address = AddressConvert.GetInstance.PlcConverter(DeviceType, value); + if (address >= 0) RealAddress = address; + } + } private string _mAddress = string.Empty; + /// + /// 实际地址 + /// + public int RealAddress { get; set; } + /// /// 数据类型 /// diff --git a/BPASmart.Server/CommunicationServer.cs b/BPASmart.Server/CommunicationServer.cs index 2cd030d7..2c3e80f3 100644 --- a/BPASmart.Server/CommunicationServer.cs +++ b/BPASmart.Server/CommunicationServer.cs @@ -10,26 +10,165 @@ namespace BPASmart.Server public void Init() { BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); + Json.Data.CommunicationDevices.ToList()?.ForEach(item => { - switch (item.CommDevice) + #region 数据加载测试 + + #endregion + + ThreadManage.GetInstance().Start(new Action(() => + { + switch (item.CommDevice) + { + case ModbusRtu _modbusRtu: + break; + case ModbusTcp _modbusTcp: + ModbusTcpMaster modbusTcpMaster = new ModbusTcpMaster(); + modbusTcpMaster.ConnectOk = new Action(() => + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + GetReadDataModels(item).ToList()?.ForEach(temp => + { + switch (temp.Key) + { + case EDataType.Bool: + temp.Value?.ForEach(value => + { + var res = modbusTcpMaster.ReadCoils(value.StartAddress, value.Length); + SetValue(res, item.DeviceName, value, 1); + }); + break; + case EDataType.Byte: + break; + case EDataType.Int: + break; + case EDataType.Word: + temp.Value?.ForEach(value => + { + var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); + SetValue(res, item.DeviceName, value, 1); + }); + break; + case EDataType.Dint: + break; + case EDataType.Dword: + temp.Value?.ForEach(value => + { + var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); + SetValue(res, item.DeviceName, value, 2); + }); + break; + case EDataType.Float: + temp.Value?.ForEach(value => + { + var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); + SetValue(res, item.DeviceName, value, 2); + }); + break; + default: + break; + } + }); + + Thread.Sleep(100); + }), $"{item.DeviceName} 设备数据采集"); + var DeviceModel = item; + }); + modbusTcpMaster.IsReconnect = true; + modbusTcpMaster.ModbusTcpConnect(DeviceType.kinco_PLC, _modbusTcp.IP, _modbusTcp.PortNum); + break; + case Siemens _siemens: + break; + default: + break; + } + }), $"{item.DeviceName} 初始化连接"); + }); + + + + } + + private void SetValue(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by) + { + if (arrays != null) + { + int index = Array.FindIndex(Json.Data.CommunicationDevices.ToArray(), p => p.DeviceName == DeviceName);//获取设备所在集合位置 + if (index >= 0 && index < Json.Data.CommunicationDevices.Count) { - case ModbusRtu _modbusRtu: - break; - case ModbusTcp _modbusTcp: - ModbusTcpMaster modbusTcpMaster = new ModbusTcpMaster(); - modbusTcpMaster.ConnectOk = new Action(() => + var tempArray = Json.Data.CommunicationDevices.ElementAt(index).VarTableModels.ToArray(); + for (int i = 0; i < arrays.Length; i++) + { + int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == readDataModel.StartAddress + (i * by)); + if (varIndex >= 0 && varIndex < tempArray.Length) { + Json.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); + } + } - }); - modbusTcpMaster.ModbusTcpConnect(DeviceType.kinco_PLC, _modbusTcp.IP, _modbusTcp.PortNum); - break; - case Siemens _siemens: - break; - default: - break; + } + } + } + + private Dictionary> GetReadDataModels(CommunicationModel communicationModel) + { + Dictionary> readDataModels = new Dictionary>(); + communicationModel.VarTableModels.GroupBy(p => p.DataType)?.ToList()?.ForEach(tempVar => + { + if (tempVar.Key != null && tempVar.Key.Length > 0) + { + int address = tempVar.Min(p => p.RealAddress); + EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); + switch (dataType) + { + case EDataType.Bool: + case EDataType.Byte: + case EDataType.Int: + case EDataType.Word: + if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar)); + break; + case EDataType.Dint: + case EDataType.Dword: + case EDataType.Float: + if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar, 2)); + break; + default: + break; + } } }); + return readDataModels; + } + + private List GetDataGroup(IGrouping variableInfos, int by = 1) + { + List ReturnValue = new List(); + var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); + int count = 0; + if (res != null) + { + int address = variableInfos.Min(p => p.RealAddress); + int startAddress = address; + for (int i = 0; i < res.Count; i++) + { + if (res.ElementAt(i).RealAddress == address) + { + count++; + address += by; + } + else + { + ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); + count = 1; + address = res.ElementAt(i).RealAddress + by; + startAddress = res.ElementAt(i).RealAddress; + } + } + ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); + } + return ReturnValue; } } } \ No newline at end of file diff --git a/BPASmart.VariableManager/ViewModels/VariableConfigViewModel.cs b/BPASmart.VariableManager/ViewModels/VariableConfigViewModel.cs index c3af4469..c6aea29c 100644 --- a/BPASmart.VariableManager/ViewModels/VariableConfigViewModel.cs +++ b/BPASmart.VariableManager/ViewModels/VariableConfigViewModel.cs @@ -20,13 +20,13 @@ namespace BPASmart.VariableManager.ViewModels public class VariableConfigViewModel : NoticeBase { private int varialeInfosIndex = -1; - string DeviceName = string.Empty; + ICommunicationDevice DeviceType; public VariableConfigViewModel(string o) { - DeviceName = o; varialeInfosIndex = Array.FindIndex(Json.Data.CommunicationDevices.ToArray(), p => p.DeviceName == o); if (varialeInfosIndex >= 0 && varialeInfosIndex < Json.Data.CommunicationDevices.Count) { + DeviceType = Json.Data.CommunicationDevices.ElementAt(varialeInfosIndex).CommDevice; varialeInfos = Json.Data.CommunicationDevices.ElementAt(varialeInfosIndex).VarTableModels; if (varialeInfos.Count <= 0) AddRow(); } @@ -42,16 +42,32 @@ namespace BPASmart.VariableManager.ViewModels DelegationNotifi.GetInstance.VarNameChanged = new Action((p) => { - var res = varialeInfos.FirstOrDefault(w => w.ID == p); - var temp = varialeInfos.Where(s => s.VarName == res?.VarName)?.ToList(); - if (temp != null && temp.Count > 1) + var result = varialeInfos.GroupBy(P => P.VarName).ToList(); + if (result != null && result.Count < varialeInfos.Count) { - temp.ForEach(item => + result.ForEach(x => { - int index = Array.FindIndex(varialeInfos.ToArray(), t => t.VarName == item.VarName && t.ID == item.ID); - if (index >= 0 && index < varialeInfos.Count) + if (x.Key.Length > 0) { - varialeInfos.ElementAt(index).IsRedundant = true; + if (x.Count() > 1) + { + x.ToList().ForEach(item => + { + int index = Array.FindIndex(varialeInfos.ToArray(), p => p.VarName == item.VarName && p.ID == item.ID); + if (index >= 0 && index < varialeInfos.Count) + { + varialeInfos.ElementAt(index).IsRedundant = true; + } + }); + } + else if (x.Count() == 1) + { + int index = Array.FindIndex(varialeInfos.ToArray(), p => p.VarName == x.ElementAt(0).VarName && p.ID == x.ElementAt(0).ID); + if (index >= 0 && index < varialeInfos.Count) + { + varialeInfos.ElementAt(index).IsRedundant = false; + } + } } }); } @@ -68,13 +84,13 @@ namespace BPASmart.VariableManager.ViewModels { if (varialeInfos?.Count >= p) { - if (varialeInfos.ElementAt(p - 1).VarName != null) + //if (varialeInfos.ElementAt(p - 1).VarName != null) + //{ + if (varialeInfos.ElementAt(p - 1).VarName?.Length > 0) { - if (varialeInfos.ElementAt(p - 1).VarName.Length > 0) - { - if (varialeInfos.Count == p) AddRow(); - } + if (varialeInfos.Count == p) AddRow(); } + //} } } }); @@ -124,7 +140,7 @@ namespace BPASmart.VariableManager.ViewModels { if (varialeInfosIndex >= 0 && varialeInfosIndex < Json.Data.CommunicationDevices.Count) { - varialeInfos.Add(new VariableInfo(DeviceName) { ID = varialeInfos.Count + 1 }); + varialeInfos.Add(new VariableInfo(DeviceType) { ID = varialeInfos.Count + 1 }); } })); diff --git a/BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml b/BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml index 318d52da..dcb461b2 100644 --- a/BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml +++ b/BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml @@ -1,14 +1,12 @@ - - - - + + diff --git a/BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml b/BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml index 5c7caff1..499e2623 100644 --- a/BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml +++ b/BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml @@ -1,12 +1,12 @@ - - - - + + diff --git a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml index 9c64bfe2..dfba34cc 100644 --- a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml +++ b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml @@ -1,44 +1,46 @@ - + - + - - - + - + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - + + - - - + + +