@@ -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; | |||
} | |||
} | |||
} |
@@ -33,7 +33,9 @@ namespace BPASmart.Model | |||
public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } | |||
private string _mDeviceName; | |||
/// <summary> | |||
/// 通讯模块名称 | |||
/// </summary> | |||
public string ModelName { get { return _mModelName; } set { _mModelName = value; OnPropertyChanged(); } } | |||
private string _mModelName; | |||
@@ -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<PublishModel> PublishModels { get; set; } = new List<PublishModel>(); | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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 | |||
/// </summary> | |||
public string VarName | |||
{ | |||
get { return _mVarName; } | |||
get { return _mVarName.Trim()?.Replace(" ", ""); } | |||
set | |||
{ | |||
_mVarName = value; | |||
@@ -43,9 +49,24 @@ namespace BPASmart.Model | |||
/// <summary> | |||
/// 地址 | |||
/// </summary> | |||
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; | |||
/// <summary> | |||
/// 实际地址 | |||
/// </summary> | |||
public int RealAddress { get; set; } | |||
/// <summary> | |||
/// 数据类型 | |||
/// </summary> | |||
@@ -10,26 +10,165 @@ namespace BPASmart.Server | |||
public void Init() | |||
{ | |||
BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); | |||
Json<CommunicationPar>.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>(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by) | |||
{ | |||
if (arrays != null) | |||
{ | |||
int index = Array.FindIndex(Json<CommunicationPar>.Data.CommunicationDevices.ToArray(), p => p.DeviceName == DeviceName);//获取设备所在集合位置 | |||
if (index >= 0 && index < Json<CommunicationPar>.Data.CommunicationDevices.Count) | |||
{ | |||
case ModbusRtu _modbusRtu: | |||
break; | |||
case ModbusTcp _modbusTcp: | |||
ModbusTcpMaster modbusTcpMaster = new ModbusTcpMaster(); | |||
modbusTcpMaster.ConnectOk = new Action(() => | |||
var tempArray = Json<CommunicationPar>.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<CommunicationPar>.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<EDataType, List<ReadDataModel>> GetReadDataModels(CommunicationModel communicationModel) | |||
{ | |||
Dictionary<EDataType, List<ReadDataModel>> readDataModels = new Dictionary<EDataType, List<ReadDataModel>>(); | |||
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<ReadDataModel> GetDataGroup(IGrouping<string, VariableInfo> variableInfos, int by = 1) | |||
{ | |||
List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | |||
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; | |||
} | |||
} | |||
} |
@@ -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<CommunicationPar>.Data.CommunicationDevices.ToArray(), p => p.DeviceName == o); | |||
if (varialeInfosIndex >= 0 && varialeInfosIndex < Json<CommunicationPar>.Data.CommunicationDevices.Count) | |||
{ | |||
DeviceType = Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(varialeInfosIndex).CommDevice; | |||
varialeInfos = Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(varialeInfosIndex).VarTableModels; | |||
if (varialeInfos.Count <= 0) AddRow(); | |||
} | |||
@@ -42,16 +42,32 @@ namespace BPASmart.VariableManager.ViewModels | |||
DelegationNotifi.GetInstance.VarNameChanged = new Action<int>((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<CommunicationPar>.Data.CommunicationDevices.Count) | |||
{ | |||
varialeInfos.Add(new VariableInfo(DeviceName) { ID = varialeInfos.Count + 1 }); | |||
varialeInfos.Add(new VariableInfo(DeviceType) { ID = varialeInfos.Count + 1 }); | |||
} | |||
})); | |||
@@ -1,14 +1,12 @@ | |||
<UserControl x:Class="BPASmartClient.CustomResource.Pages.View.PermissionConfigurationView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.CustomResource.Pages.View" | |||
Width="800" | |||
Height="450" | |||
mc:Ignorable="d"> | |||
<Grid> | |||
</Grid> | |||
<UserControl | |||
x:Class="BPASmartClient.CustomResource.Pages.View.PermissionConfigurationView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.CustomResource.Pages.View" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
Width="800" | |||
Height="450" | |||
mc:Ignorable="d"> | |||
<Grid /> | |||
</UserControl> |
@@ -1,12 +1,12 @@ | |||
<UserControl x:Class="BPASmartClient.CustomResource.Pages.View.RecipeQueueView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.CustomResource.Pages.View" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
<Grid> | |||
</Grid> | |||
<UserControl | |||
x:Class="BPASmartClient.CustomResource.Pages.View.RecipeQueueView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.CustomResource.Pages.View" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
d:DesignHeight="450" | |||
d:DesignWidth="800" | |||
mc:Ignorable="d"> | |||
<Grid /> | |||
</UserControl> |