瀏覽代碼

数据读取模块开发

样式分支
pry 2 年之前
父節點
當前提交
5a11cb2853
共有 11 個文件被更改,包括 905 次插入328 次删除
  1. +66
    -0
      BPASmart.Model/CommDeviceModel/AddressConvert.cs
  2. +3
    -1
      BPASmart.Model/CommunicationModel.cs
  3. +13
    -0
      BPASmart.Model/PublishInfo.cs
  4. +17
    -0
      BPASmart.Model/PublishModel.cs
  5. +17
    -0
      BPASmart.Model/ReadDataModel.cs
  6. +23
    -2
      BPASmart.Model/VariableInfo.cs
  7. +152
    -13
      BPASmart.Server/CommunicationServer.cs
  8. +31
    -15
      BPASmart.VariableManager/ViewModels/VariableConfigViewModel.cs
  9. +11
    -13
      BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml
  10. +11
    -11
      BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml
  11. +561
    -273
      BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml

+ 66
- 0
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;
}

}
}

+ 3
- 1
BPASmart.Model/CommunicationModel.cs 查看文件

@@ -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;



+ 13
- 0
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<PublishModel> PublishModels { get; set; } = new List<PublishModel>();
}
}

+ 17
- 0
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; }

}
}

+ 17
- 0
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; }


}
}

+ 23
- 2
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
/// </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>


+ 152
- 13
BPASmart.Server/CommunicationServer.cs 查看文件

@@ -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;
}
}
}

+ 31
- 15
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<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 });
}
}));



+ 11
- 13
BPASmartClient.CustomResource/Pages/View/PermissionConfigurationView.xaml 查看文件

@@ -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>

+ 11
- 11
BPASmartClient.CustomResource/Pages/View/RecipeQueueView.xaml 查看文件

@@ -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>

+ 561
- 273
BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml
文件差異過大導致無法顯示
查看文件


Loading…
取消
儲存