Several function enchancement
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// 南大奥拓NA200H专用AddressFormater
|
||||
/// </summary>
|
||||
public class AddressFormaterNA200H : AddressFormater
|
||||
public class AddressFormaterNA200H : AddressFormater<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net462</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.Modbus.NA200H</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Modbus.NA200H</RootNamespace>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net462</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.Modbus.SelfDefinedSample</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Modbus.SelfDefinedSample</RootNamespace>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Modbus标准AddressFormater
|
||||
/// </summary>
|
||||
public class AddressFormaterModbus : AddressFormater
|
||||
public class AddressFormaterModbus : AddressFormater<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net462</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.Modbus</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Modbus</RootNamespace>
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Modbus.Net.Modbus
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(TKey id, ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
|
||||
IEnumerable<AddressUnit<TUnitKey, int ,int>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
|
||||
Endian endian)
|
||||
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ namespace Modbus.Net.Modbus
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(TKey id, ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, byte slaveAddress, byte masterAddress,
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, byte slaveAddress, byte masterAddress,
|
||||
Endian endian)
|
||||
: this(id, connectionType, connectionString, getAddresses, true, slaveAddress, masterAddress, endian)
|
||||
{
|
||||
|
||||
@@ -6,16 +6,16 @@ namespace Modbus.Net.Opc
|
||||
/// <summary>
|
||||
/// Opc地址编码器
|
||||
/// </summary>
|
||||
public class AddressFormaterOpc<TMachineKey, TUnitKey> : AddressFormater where TMachineKey : IEquatable<TMachineKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
public class AddressFormaterOpc<TMachineKey, TUnitKey, TAddressKey, TSubAddressKey> : AddressFormater<TAddressKey, TSubAddressKey> where TMachineKey : IEquatable<TMachineKey>
|
||||
where TUnitKey : IEquatable<TUnitKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议构造器
|
||||
/// </summary>
|
||||
/// <param name="tagGeter">如何通过BaseMachine和AddressUnit构造Opc的标签</param>
|
||||
/// <param name="machine">调用这个编码器的设备</param>
|
||||
public AddressFormaterOpc(Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> tagGeter,
|
||||
BaseMachine<TMachineKey, TUnitKey> machine)
|
||||
public AddressFormaterOpc(Func<BaseMachine<TMachineKey, TUnitKey, TAddressKey, TSubAddressKey>, AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>, string> tagGeter,
|
||||
BaseMachine<TMachineKey, TUnitKey, TAddressKey, TSubAddressKey> machine)
|
||||
{
|
||||
Machine = machine;
|
||||
TagGeter = tagGeter;
|
||||
@@ -24,13 +24,13 @@ namespace Modbus.Net.Opc
|
||||
/// <summary>
|
||||
/// 设备
|
||||
/// </summary>
|
||||
public BaseMachine<TMachineKey, TUnitKey> Machine { get; set; }
|
||||
public BaseMachine<TMachineKey, TUnitKey, TAddressKey, TSubAddressKey> Machine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签构造器
|
||||
/// (设备,地址)->不具备分隔符的标签数组
|
||||
/// </summary>
|
||||
protected Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> TagGeter { get; set; }
|
||||
protected Func<BaseMachine<TMachineKey, TUnitKey, TAddressKey, TSubAddressKey>, AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>, string> TagGeter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
@@ -38,15 +38,12 @@ namespace Modbus.Net.Opc
|
||||
/// <param name="area">地址所在的数据区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public override string FormatAddress(string area, int address)
|
||||
public override string FormatAddress(string area, TAddressKey address)
|
||||
{
|
||||
var findAddress = Machine?.GetAddresses.FirstOrDefault(p => p.Area == area && p.Address == address);
|
||||
var findAddress = Machine?.GetAddresses.FirstOrDefault(p => p.Area == area && p.Address.Equals(address));
|
||||
if (findAddress == null) return null;
|
||||
var strings = TagGeter(Machine, findAddress);
|
||||
var ans = "";
|
||||
for (var i = 0; i < strings.Length; i++)
|
||||
ans += strings[i].Trim().Replace(" ", "") + '\r';
|
||||
ans = ans.Substring(0, ans.Length - 1);
|
||||
var ans = TagGeter(Machine, findAddress);
|
||||
ans = ans.Trim().Replace(" ", "");
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -57,7 +54,7 @@ namespace Modbus.Net.Opc
|
||||
/// <param name="address">地址</param>
|
||||
/// <param name="subAddress">子地址(忽略)</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public override string FormatAddress(string area, int address, int subAddress)
|
||||
public override string FormatAddress(string area, TAddressKey address, TSubAddressKey subAddress)
|
||||
{
|
||||
return FormatAddress(area, address);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@ using Hylasoft.Opc.Da;
|
||||
using Hylasoft.Opc.Ua;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using URL = Opc.URL;
|
||||
|
||||
namespace Modbus.Net.Opc
|
||||
{
|
||||
@@ -73,18 +71,11 @@ namespace Modbus.Net.Opc
|
||||
public class MyDaClient : DaClient, IClientExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// UaClient Extend
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="serverUrl">Url address of Opc UA server</param>
|
||||
/// <param name="serverUrl">OpcDa服务端Url</param>
|
||||
public MyDaClient(Uri serverUrl) : base(serverUrl)
|
||||
{
|
||||
var url = new URL(serverUrl.OriginalString)
|
||||
{
|
||||
Scheme = serverUrl.Scheme,
|
||||
HostName = serverUrl.Host
|
||||
};
|
||||
|
||||
typeof(DaClient).GetField("_url", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net462</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.Opc</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Opc</RootNamespace>
|
||||
@@ -23,22 +23,15 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.Opc.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.Opc.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="H.Opc" Version="0.9.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\h-opc\h-opc\h-opc.csproj" />
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Modbus.Net.Opc
|
||||
{
|
||||
var result = await Client.ReadAsync<object>(tag);
|
||||
object resultTrans;
|
||||
if (result.Value.ToString() == "False")
|
||||
if (result.Value?.ToString() == "False")
|
||||
{
|
||||
resultTrans = (byte)0;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Modbus.Net.Opc
|
||||
/// <summary>
|
||||
/// Opc设备
|
||||
/// </summary>
|
||||
public class OpcMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
|
||||
public class OpcMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey, string, string> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,13 +16,12 @@ namespace Modbus.Net.Opc
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的地址</param>
|
||||
public OpcMachine(TKey id, OpcType connectionType, string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
|
||||
/// <param name="tagSpliter">连接各个字段用的符号</param>
|
||||
public OpcMachine(TKey id, OpcType connectionType, string connectionString, IEnumerable<AddressUnit<TUnitKey, string, string>> getAddresses, string tagSpliter)
|
||||
: base(id, getAddresses, true)
|
||||
{
|
||||
BaseUtility = new OpcUtility(connectionType, connectionString);
|
||||
AddressFormater = new AddressFormaterOpc<TKey, TUnitKey>((machine, unit) => { return new string[] { unit.Area }; }, this);
|
||||
AddressCombiner = new AddressCombinerSingle<TUnitKey>();
|
||||
AddressCombinerSet = new AddressCombinerSingle<TUnitKey>();
|
||||
AddressFormater = new AddressFormaterOpc<TKey, TUnitKey, string, string>((machine, unit) => { var ans = unit.Area; if (unit.Address != null) ans += tagSpliter + unit.Address; if (unit.SubAddress != null) ans += tagSpliter + unit.SubAddress; return ans; }, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,6 @@ namespace Modbus.Net.Opc
|
||||
/// </summary>
|
||||
public abstract class OpcProtocolLinker : ProtocolLinker<OpcParamIn, OpcParamOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public override async Task<OpcParamOut> SendReceiveAsync(OpcParamIn content)
|
||||
{
|
||||
var extBytes = BytesExtend(content);
|
||||
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
||||
return receiveBytes == null
|
||||
? null
|
||||
: receiveBytes.Value.Length == 0 ? receiveBytes : BytesDecact(receiveBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
|
||||
/// </summary>
|
||||
@@ -47,6 +33,7 @@ namespace Modbus.Net.Opc
|
||||
public override bool? CheckRight(OpcParamOut content)
|
||||
{
|
||||
if (content == null || !content.Success) return false;
|
||||
if (content.Success && content.Value == null) { content.Value = Encoding.ASCII.GetBytes("Success"); return true; }
|
||||
if (content.Value.Length == 6 && Encoding.ASCII.GetString(content.Value) == "NoData")
|
||||
return null;
|
||||
return base.CheckRight(content);
|
||||
|
||||
@@ -4,4 +4,9 @@
|
||||
|
||||
OPC Implementation of Modbus.Net
|
||||
|
||||
Doc has been moved to wiki.
|
||||
Doc has been moved to wiki.
|
||||
|
||||
## Caution
|
||||
|
||||
Do not use this module in commercial environment.<br>
|
||||
Altered h-opc uses Technosoftware.DaAeHdaSolution that will not abey for non paid commercial use.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Siemens地址格式化(Modbus.Net专用格式)
|
||||
/// </summary>
|
||||
public class AddressFormaterSiemens : AddressFormater
|
||||
public class AddressFormaterSiemens : AddressFormater<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
@@ -32,7 +32,7 @@
|
||||
/// <summary>
|
||||
/// Siemens地址格式化(Siemens格式)
|
||||
/// </summary>
|
||||
public class AddressFormaterSimenseStandard : AddressFormater
|
||||
public class AddressFormaterSimenseStandard : AddressFormater<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net462</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.Siemens</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.Siemens</RootNamespace>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Modbus.Net.Siemens
|
||||
/// <param name="src">本机模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
/// <param name="dst">PLC模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
public SiemensMachine(TKey id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
{
|
||||
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress, src, dst);
|
||||
@@ -45,7 +45,7 @@ namespace Modbus.Net.Siemens
|
||||
/// <param name="src">本机模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
/// <param name="dst">PLC模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
public SiemensMachine(TKey id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
: this(id, connectionType, connectionString, model, getAddresses, true, slaveAddress, masterAddress, src, dst)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,16 +34,6 @@ namespace Modbus.Net.Siemens
|
||||
ProtocolLinker = new SiemensPpiProtocolLinker(_com, SlaveAddress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
/// <param name="content">写入的内容,使用对象数组描述</param>
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
public override PipeUnit SendReceive(params object[] content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FastEnumUtility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
@@ -19,7 +19,7 @@ namespace Modbus.Net.Siemens
|
||||
public SiemensPpiProtocolLinker(string com, int slaveAddress)
|
||||
: base(com, slaveAddress, parity:
|
||||
ConfigurationReader.GetValue("COM:Siemens", "Parity") != null
|
||||
? FastEnum.Parse<Parity>(ConfigurationReader.GetValue("COM:Siemens", "Parity"))
|
||||
? Enum.Parse<Parity>(ConfigurationReader.GetValue("COM:Siemens", "Parity"))
|
||||
: null
|
||||
)
|
||||
{
|
||||
|
||||
@@ -78,16 +78,6 @@ namespace Modbus.Net.Siemens
|
||||
ProtocolLinker = new SiemensTcpProtocolLinker(_ip, _port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据并接收
|
||||
/// </summary>
|
||||
/// <param name="content">发送的数据</param>
|
||||
/// <returns>返回的数据</returns>
|
||||
public override PipeUnit SendReceive(params object[] content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据并接收
|
||||
/// </summary>
|
||||
@@ -100,17 +90,6 @@ namespace Modbus.Net.Siemens
|
||||
return await base.SendReceiveAsync(Endian, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据并接收
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的核心</param>
|
||||
/// <param name="content">协议的参数</param>
|
||||
/// <returns>返回的数据</returns>
|
||||
public override PipeUnit SendReceive(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据并接收
|
||||
/// </summary>
|
||||
|
||||
@@ -34,6 +34,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TripleAdd", "..\Samples\Tri
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.Modbus.SelfDefinedSample", "Modbus.Net.Modbus.SelfDefinedSample\Modbus.Net.Modbus.SelfDefinedSample.csproj", "{C4FA55AF-80ED-4467-948F-8EF865C8A5A5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "h-opc", "..\h-opc\h-opc\h-opc.csproj", "{DC6425E4-1409-488D-A014-4DCC909CF542}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -84,6 +86,10 @@ Global
|
||||
{C4FA55AF-80ED-4467-948F-8EF865C8A5A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4FA55AF-80ED-4467-948F-8EF865C8A5A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4FA55AF-80ED-4467-948F-8EF865C8A5A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DC6425E4-1409-488D-A014-4DCC909CF542}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DC6425E4-1409-488D-A014-4DCC909CF542}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DC6425E4-1409-488D-A014-4DCC909CF542}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DC6425E4-1409-488D-A014-4DCC909CF542}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using FastEnumUtility;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -62,8 +61,19 @@ namespace Modbus.Net
|
||||
}
|
||||
case "addressMap":
|
||||
{
|
||||
paramsSet.Add(AddressReader.ReadAddresses(dic["addressMap"]));
|
||||
break;
|
||||
var machineTypeTemp = Assembly.Load("Modbus.Net." + dic["protocol"]).GetType("Modbus.Net." + dic["protocol"] + "." + dic["protocol"] + "Machine`2");
|
||||
var addressTypes = machineTypeTemp.GetProperty("GetAddresses").PropertyType.GenericTypeArguments[0].GenericTypeArguments;
|
||||
if (addressTypes[1] == typeof(int) && addressTypes[2] == typeof(int))
|
||||
{
|
||||
paramsSet.Add(AddressReader<string, int, int>.ReadAddresses(dic["addressMap"]));
|
||||
break;
|
||||
}
|
||||
else if (addressTypes[1] == typeof(string) && addressTypes[2] == typeof(string))
|
||||
{
|
||||
paramsSet.Add(AddressReader<string, string, string>.ReadAddresses(dic["addressMap"]));
|
||||
break;
|
||||
}
|
||||
throw new NotSupportedException("AddressUnit type not supported for AddressReader");
|
||||
}
|
||||
case "endian":
|
||||
{
|
||||
@@ -105,7 +115,7 @@ namespace Modbus.Net
|
||||
}
|
||||
}
|
||||
|
||||
class AddressReader
|
||||
internal class AddressReader<TUnitKey, TAddressKey, TSubAddressKey> where TUnitKey : IEquatable<TUnitKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
private static readonly IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
@@ -114,14 +124,14 @@ namespace Modbus.Net
|
||||
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true, reloadOnChange: true)
|
||||
.Build();
|
||||
|
||||
public static IEnumerable<AddressUnit<string>> ReadAddresses(string addressMapName)
|
||||
public static IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> ReadAddresses(string addressMapName)
|
||||
{
|
||||
var ans = new List<AddressUnit<string>>();
|
||||
var ans = new List<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>>();
|
||||
var addressesRoot = configuration.GetSection("Modbus.Net").GetSection("AddressMap").GetSection(addressMapName).GetChildren();
|
||||
foreach (var address in addressesRoot)
|
||||
{
|
||||
|
||||
var addressNew = address.Get<AddressUnit<string>>();
|
||||
var addressNew = address.Get<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>>();
|
||||
addressNew.DataType = "System." + address["DataType"] != null ? Type.GetType("System." + address["DataType"]) : throw new ArgumentNullException("DataType is null");
|
||||
if (addressNew.DataType == null) throw new ArgumentNullException(string.Format("DataType define error {0} {1} {2}", addressMapName, addressNew.Id, address["DataType"]));
|
||||
ans.Add(addressNew);
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// AsyncHelper Class
|
||||
/// </summary>
|
||||
public static class AsyncHelper
|
||||
{
|
||||
private static readonly TaskFactory _myTaskFactory = new
|
||||
TaskFactory(CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
TaskContinuationOptions.None,
|
||||
TaskScheduler.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Run async method syncronized
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">Return type</typeparam>
|
||||
/// <param name="func">Async method with return</param>
|
||||
/// <returns>Return value</returns>
|
||||
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
|
||||
{
|
||||
return _myTaskFactory
|
||||
.StartNew(func)
|
||||
.Unwrap()
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run async method syncronized.
|
||||
/// </summary>
|
||||
/// <param name="func">Async method</param>
|
||||
public static void RunSync(Func<Task> func)
|
||||
{
|
||||
_myTaskFactory
|
||||
.StartNew(func)
|
||||
.Unwrap()
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change async task to async task with cancellation token
|
||||
/// </summary>
|
||||
/// <param name="task">Async task</param>
|
||||
/// <param name="token">Cancellation Token</param>
|
||||
/// <returns>Task with Cancellation token</returns>
|
||||
public static Task WithCancellation(this Task task,
|
||||
CancellationToken token)
|
||||
{
|
||||
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a CancellationToken to async task
|
||||
/// </summary>
|
||||
/// <typeparam name="T">type of a task</typeparam>
|
||||
/// <param name="task">Task</param>
|
||||
/// <param name="token">Cancellation token</param>
|
||||
/// <returns>Task with cancellation token</returns>
|
||||
public static Task<T> WithCancellation<T>(this Task<T> task,
|
||||
CancellationToken token)
|
||||
{
|
||||
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,13 +307,27 @@ namespace Modbus.Net
|
||||
/// <returns>对应的ValueHelper实例</returns>
|
||||
public static ValueHelper GetInstance(Endian endian)
|
||||
{
|
||||
if (EndianInstanceCache.ContainsKey(endian.ToString()))
|
||||
{
|
||||
return EndianInstanceCache[endian.ToString()];
|
||||
}
|
||||
foreach (var assembly in AssemblyHelper.GetAllLibraryAssemblies())
|
||||
{
|
||||
var valueHelper = assembly.GetType("Modbus.Net."+endian.ToString() + "ValueHelper")?.GetProperty("Instance")?.GetValue(null, null) as ValueHelper;
|
||||
if (valueHelper != null) return valueHelper;
|
||||
if (valueHelper != null)
|
||||
{
|
||||
EndianInstanceCache[endian.ToString()] = valueHelper;
|
||||
return valueHelper;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
throw new NotImplementedException("ValueHelper " + endian.ToString() + " doesn't exist.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ValueHelper实例的缓存
|
||||
/// </summary>
|
||||
protected static Dictionary<string, ValueHelper> EndianInstanceCache = new Dictionary<string, ValueHelper>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -15,26 +15,12 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public interface IMachineMethodDatas : IMachineMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// 读取数据
|
||||
/// </summary>
|
||||
/// <returns>从设备读取的数据</returns>
|
||||
ReturnStruct<Dictionary<string, ReturnUnit<double>>> GetDatas(MachineDataType getDataType);
|
||||
|
||||
/// <summary>
|
||||
/// 读取数据
|
||||
/// </summary>
|
||||
/// <returns>从设备读取的数据</returns>
|
||||
Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType);
|
||||
|
||||
/// <summary>
|
||||
/// 写入数据
|
||||
/// </summary>
|
||||
/// <param name="setDataType">写入类型</param>
|
||||
/// <param name="values">需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述</param>
|
||||
/// <returns>是否写入成功</returns>
|
||||
ReturnStruct<bool> SetDatas(MachineDataType setDataType, Dictionary<string, double> values);
|
||||
|
||||
/// <summary>
|
||||
/// 写入数据
|
||||
/// </summary>
|
||||
|
||||
@@ -39,13 +39,6 @@ namespace Modbus.Net
|
||||
/// <returns></returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
/// <param name="content">写入的内容,使用对象数组描述</param>
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
TPipeUnit SendReceive(params object[] content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
@@ -53,14 +46,6 @@ namespace Modbus.Net
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
Task<TPipeUnit> SendReceiveAsync(params object[] content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
TPipeUnit SendReceive(TProtocolUnit unit, IInputStruct content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
@@ -69,16 +54,6 @@ namespace Modbus.Net
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
Task<TPipeUnit> SendReceiveAsync(TProtocolUnit unit, IInputStruct content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
|
||||
T SendReceive<T>(
|
||||
TProtocolUnit unit, IInputStruct content) where T : class, IOutputStruct;
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
|
||||
@@ -31,13 +31,6 @@ namespace Modbus.Net
|
||||
/// <returns>设备是否断开成功</returns>
|
||||
bool Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
TParamOut SendReceive(TParamIn content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
@@ -45,13 +38,6 @@ namespace Modbus.Net
|
||||
/// <returns>接收协议的内容</returns>
|
||||
Task<TParamOut> SendReceiveAsync(TParamIn content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
TParamOut SendReceiveWithoutExtAndDec(TParamIn content);
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
|
||||
/// </summary>
|
||||
@@ -65,19 +51,5 @@ namespace Modbus.Net
|
||||
/// <param name="content">接收协议的内容</param>
|
||||
/// <returns>协议是否是正确的</returns>
|
||||
bool? CheckRight(TParamOut content);
|
||||
|
||||
/// <summary>
|
||||
/// 协议内容扩展,发送时根据需要扩展
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的基本协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
TParamIn BytesExtend(TParamIn content);
|
||||
|
||||
/// <summary>
|
||||
/// 协议内容缩减,接收时根据需要缩减
|
||||
/// </summary>
|
||||
/// <param name="content">缩减前的完整协议内容</param>
|
||||
/// <returns>缩减后的协议内容</returns>
|
||||
TParamOut BytesDecact(TParamOut content);
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,6 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public interface IUtilityMethodDatas : IUtilityMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getByteCount">获取字节数个数</param>
|
||||
/// <returns>接收到的byte数据</returns>
|
||||
ReturnStruct<byte[]> GetDatas(string startAddress, int getByteCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -32,14 +24,6 @@ namespace Modbus.Net
|
||||
/// <returns>接收到的byte数据</returns>
|
||||
Task<ReturnStruct<byte[]>> GetDatasAsync(string startAddress, int getByteCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getTypeAndCount">获取类型和个数</param>
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
ReturnStruct<object[]> GetDatas(string startAddress, KeyValuePair<Type, int> getTypeAndCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -48,15 +32,6 @@ namespace Modbus.Net
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
Task<ReturnStruct<object[]>> GetDatasAsync(string startAddress, KeyValuePair<Type, int> getTypeAndCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">需要接收的类型</typeparam>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getByteCount">获取字节数个数</param>
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
ReturnStruct<T[]> GetDatas<T>(string startAddress, int getByteCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -66,14 +41,6 @@ namespace Modbus.Net
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
Task<ReturnStruct<T[]>> GetDatasAsync<T>(string startAddress, int getByteCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getTypeAndCountList">获取类型和个数的队列</param>
|
||||
/// <returns>获取数据的对象数组,请强制转换成相应类型</returns>
|
||||
ReturnStruct<object[]> GetDatas(string startAddress, IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -81,14 +48,6 @@ namespace Modbus.Net
|
||||
/// <param name="getTypeAndCountList">获取类型和个数的队列</param>
|
||||
Task<ReturnStruct<object[]>> GetDatasAsync(string startAddress, IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList);
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="setContents">设置数据</param>
|
||||
/// <returns>是否设置成功</returns>
|
||||
ReturnStruct<bool> SetDatas(string startAddress, object[] setContents);
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FastEnumUtility;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace Modbus.Net
|
||||
@@ -23,11 +23,11 @@ namespace Modbus.Net
|
||||
protected ComProtocolLinker(string com, int slaveAddress, BaudRate? baudRate = null, Parity? parity = null, StopBits? stopBits = null, DataBits? dataBits = null, Handshake? handshake = null,
|
||||
int? connectionTimeout = null, bool? isFullDuplex = null)
|
||||
{
|
||||
baudRate = FastEnum.Parse<BaudRate>(baudRate != null ? baudRate.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "BaudRate"));
|
||||
parity = FastEnum.Parse<Parity>(parity != null ? parity.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "Parity"));
|
||||
stopBits = FastEnum.Parse<StopBits>(stopBits != null ? stopBits.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "StopBits"));
|
||||
dataBits = FastEnum.Parse<DataBits>(dataBits != null ? dataBits.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "DataBits"));
|
||||
handshake = FastEnum.Parse<Handshake>(handshake != null ? handshake.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "Handshake"));
|
||||
baudRate = Enum.Parse<BaudRate>(baudRate != null ? baudRate.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "BaudRate"));
|
||||
parity = Enum.Parse<Parity>(parity != null ? parity.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "Parity"));
|
||||
stopBits = Enum.Parse<StopBits>(stopBits != null ? stopBits.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "StopBits"));
|
||||
dataBits = Enum.Parse<DataBits>(dataBits != null ? dataBits.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "DataBits"));
|
||||
handshake = Enum.Parse<Handshake>(handshake != null ? handshake.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "Handshake"));
|
||||
connectionTimeout = int.Parse(connectionTimeout != null ? connectionTimeout.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "ConnectionTimeout"));
|
||||
isFullDuplex = bool.Parse(isFullDuplex != null ? isFullDuplex.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "FullDuplex"));
|
||||
BaseConnector = new ComConnector(com + ":" + slaveAddress, baudRate.Value, parity.Value, stopBits.Value, dataBits.Value, handshake.Value, connectionTimeout.Value, isFullDuplex.Value);
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 基本的协议连接器
|
||||
/// </summary>
|
||||
public abstract class ProtocolLinker : ProtocolLinker<byte[], byte[]>
|
||||
public abstract class ProtocolLinker : ProtocolLinker<byte[], byte[]>, IProtocolLinkerBytesExtend<byte[], byte[]>
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
@@ -41,7 +41,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的基本协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public override byte[] BytesExtend(byte[] content)
|
||||
public virtual byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
|
||||
var bytesExtend =
|
||||
@@ -56,7 +56,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="content">缩减前的完整协议内容</param>
|
||||
/// <returns>缩减后的协议内容</returns>
|
||||
public override byte[] BytesDecact(byte[] content)
|
||||
public virtual byte[] BytesDecact(byte[] content)
|
||||
{
|
||||
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
|
||||
var bytesExtend =
|
||||
@@ -122,16 +122,6 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public bool IsConnected => BaseConnector != null && BaseConnector.IsConnected;
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public virtual TParamOut SendReceive(TParamIn content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据
|
||||
/// </summary>
|
||||
@@ -139,19 +129,8 @@ namespace Modbus.Net
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public virtual async Task<TParamOut> SendReceiveAsync(TParamIn content)
|
||||
{
|
||||
var extBytes = BytesExtend(content);
|
||||
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
||||
return BytesDecact(receiveBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
|
||||
/// </summary>
|
||||
/// <param name="content">发送协议的内容</param>
|
||||
/// <returns>接收协议的内容</returns>
|
||||
public virtual TParamOut SendReceiveWithoutExtAndDec(TParamIn content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveWithoutExtAndDecAsync(content));
|
||||
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(content);
|
||||
return receiveBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,25 +159,5 @@ namespace Modbus.Net
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议内容扩展,发送时根据需要扩展
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的基本协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public virtual TParamIn BytesExtend(TParamIn content)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议内容缩减,接收时根据需要缩减
|
||||
/// </summary>
|
||||
/// <param name="content">缩减前的完整协议内容</param>
|
||||
/// <returns>缩减后的协议内容</returns>
|
||||
public virtual TParamOut BytesDecact(TParamOut content)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,20 +7,20 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
|
||||
/// </summary>
|
||||
public abstract class AddressCombiner<TKey> where TKey : IEquatable<TKey>
|
||||
public abstract class AddressCombiner<TKey, TAddressKey, TSubAddressKey> where TKey : IEquatable<TKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 组合地址
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要进行组合的地址</param>
|
||||
/// <returns>组合完成后与设备通讯的地址</returns>
|
||||
public abstract IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses);
|
||||
public abstract IEnumerable<CommunicationUnit<TKey, TAddressKey, TSubAddressKey>> Combine(IEnumerable<AddressUnit<TKey, TAddressKey, TSubAddressKey>> addresses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连续的地址将组合成一组,向设备进行通讯
|
||||
/// </summary>
|
||||
public class AddressCombinerContinus<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
|
||||
public class AddressCombinerContinus<TKey> : AddressCombiner<TKey, int, int> where TKey : IEquatable<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@@ -48,7 +48,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要组合的地址</param>
|
||||
/// <returns>组合后的地址</returns>
|
||||
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
|
||||
public override IEnumerable<CommunicationUnit<TKey, int, int>> Combine(IEnumerable<AddressUnit<TKey, int, int>> addresses)
|
||||
{
|
||||
//按从小到大的顺序对地址进行排序
|
||||
var groupedAddresses = from address in addresses
|
||||
@@ -58,7 +58,7 @@ namespace Modbus.Net
|
||||
group address by address.Area
|
||||
into grouped
|
||||
select grouped;
|
||||
var ans = new List<CommunicationUnit<TKey>>();
|
||||
var ans = new List<CommunicationUnit<TKey, int, int>>();
|
||||
foreach (var groupedAddress in groupedAddresses)
|
||||
{
|
||||
var area = groupedAddress.Key;
|
||||
@@ -69,7 +69,7 @@ namespace Modbus.Net
|
||||
//上一个地址类型
|
||||
Type preType = null;
|
||||
//记录一个地址组合当中的所有原始地址
|
||||
var originalAddresses = new List<AddressUnit<TKey>>();
|
||||
var originalAddresses = new List<AddressUnit<TKey, int, int>>();
|
||||
//对组合内地址从小到大进行排序
|
||||
var orderedAddresses =
|
||||
groupedAddress.OrderBy(
|
||||
@@ -114,7 +114,7 @@ namespace Modbus.Net
|
||||
AddressTranslator.GetAreaByteLength(address.Area)))
|
||||
{
|
||||
//上一个地址域压入返回结果,并把当前记录的结果清空。
|
||||
ans.Add(new CommunicationUnit<TKey>
|
||||
ans.Add(new CommunicationUnit<TKey, int, int>
|
||||
{
|
||||
Area = area,
|
||||
Address = (int)Math.Floor(initNum),
|
||||
@@ -144,7 +144,7 @@ namespace Modbus.Net
|
||||
preType = address.DataType;
|
||||
}
|
||||
//最后一个地址域压入返回结果
|
||||
ans.Add(new CommunicationUnit<TKey>
|
||||
ans.Add(new CommunicationUnit<TKey, int, int>
|
||||
{
|
||||
Area = area,
|
||||
Address = (int)Math.Floor(initNum),
|
||||
@@ -167,9 +167,9 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="ans">拆分前的连续地址池</param>
|
||||
/// <returns>拆分后的连续地址池</returns>
|
||||
protected List<CommunicationUnit<TKey>> MaxExclude(List<CommunicationUnit<TKey>> ans)
|
||||
protected List<CommunicationUnit<TKey, int, int>> MaxExclude(List<CommunicationUnit<TKey, int, int>> ans)
|
||||
{
|
||||
var newAns = new List<CommunicationUnit<TKey>>();
|
||||
var newAns = new List<CommunicationUnit<TKey, int, int>>();
|
||||
foreach (var communicationUnit in ans)
|
||||
{
|
||||
var oldByteCount = communicationUnit.GetCount *
|
||||
@@ -178,7 +178,7 @@ namespace Modbus.Net
|
||||
while (oldByteCount * ValueHelper.ByteLength[communicationUnit.DataType.FullName] >
|
||||
MaxLength)
|
||||
{
|
||||
var newOriginalAddresses = new List<AddressUnit<TKey>>();
|
||||
var newOriginalAddresses = new List<AddressUnit<TKey, int, int>>();
|
||||
var newByteCount = 0.0;
|
||||
var newAddressUnitStart = oldOriginalAddresses.First();
|
||||
do
|
||||
@@ -190,7 +190,7 @@ namespace Modbus.Net
|
||||
newOriginalAddresses.Add(currentAddressUnit);
|
||||
oldOriginalAddresses.RemoveAt(0);
|
||||
} while (newByteCount < MaxLength);
|
||||
var newCommunicationUnit = new CommunicationUnit<TKey>
|
||||
var newCommunicationUnit = new CommunicationUnit<TKey, int, int>
|
||||
{
|
||||
Area = newAddressUnitStart.Area,
|
||||
Address = newAddressUnitStart.Address,
|
||||
@@ -225,26 +225,26 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 单个地址变为一组,每一个地址都进行一次查询
|
||||
/// </summary>
|
||||
public class AddressCombinerSingle<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
|
||||
public class AddressCombinerSingle<TKey, TAddressKey, TSubAddressKey> : AddressCombiner<TKey, TAddressKey, TSubAddressKey> where TKey : IEquatable<TKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 组合地址
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要组合的地址</param>
|
||||
/// <returns>组合后的地址</returns>
|
||||
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
|
||||
public override IEnumerable<CommunicationUnit<TKey, TAddressKey, TSubAddressKey>> Combine(IEnumerable<AddressUnit<TKey, TAddressKey, TSubAddressKey>> addresses)
|
||||
{
|
||||
return
|
||||
addresses.Select(
|
||||
address =>
|
||||
new CommunicationUnit<TKey>
|
||||
new CommunicationUnit<TKey, TAddressKey, TSubAddressKey>
|
||||
{
|
||||
Area = address.Area,
|
||||
Address = address.Address,
|
||||
SubAddress = address.SubAddress,
|
||||
DataType = address.DataType,
|
||||
GetCount = 1,
|
||||
OriginalAddresses = new List<AddressUnit<TKey>> { address }
|
||||
OriginalAddresses = new List<AddressUnit<TKey, TAddressKey, TSubAddressKey>> { address }
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
@@ -254,7 +254,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
internal class CommunicationUnitGap<TKey> where TKey : IEquatable<TKey>
|
||||
{
|
||||
public CommunicationUnit<TKey> EndUnit { get; set; }
|
||||
public CommunicationUnit<TKey, int, int> EndUnit { get; set; }
|
||||
public int GapNumber { get; set; }
|
||||
}
|
||||
|
||||
@@ -285,11 +285,11 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要组合的地址</param>
|
||||
/// <returns>组合后的地址</returns>
|
||||
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
|
||||
public override IEnumerable<CommunicationUnit<TKey, int, int>> Combine(IEnumerable<AddressUnit<TKey, int, int>> addresses)
|
||||
{
|
||||
var continusAddresses = base.Combine(addresses).ToList();
|
||||
var addressesGaps = new List<CommunicationUnitGap<TKey>>();
|
||||
CommunicationUnit<TKey> preCommunicationUnit = null;
|
||||
CommunicationUnit<TKey, int, int> preCommunicationUnit = null;
|
||||
foreach (var continusAddress in continusAddresses)
|
||||
{
|
||||
if (preCommunicationUnit == null)
|
||||
@@ -335,7 +335,7 @@ namespace Modbus.Net
|
||||
continusAddresses.RemoveAt(index);
|
||||
continusAddresses.RemoveAt(index);
|
||||
//合并两个已有的地址段,变为一个新的地址段
|
||||
var newAddress = new CommunicationUnit<TKey>
|
||||
var newAddress = new CommunicationUnit<TKey, int, int>
|
||||
{
|
||||
Area = nowAddress.Area,
|
||||
Address = preAddress.Address,
|
||||
@@ -382,9 +382,9 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要组合的地址</param>
|
||||
/// <returns>组合后的地址</returns>
|
||||
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
|
||||
public override IEnumerable<CommunicationUnit<TKey, int, int>> Combine(IEnumerable<AddressUnit<TKey, int, int>> addresses)
|
||||
{
|
||||
var addressUnits = addresses as IList<AddressUnit<TKey>> ?? addresses.ToList();
|
||||
var addressUnits = addresses as IList<AddressUnit<TKey, int, int>> ?? addresses.ToList();
|
||||
var count = addressUnits.Sum(address => ValueHelper.ByteLength[address.DataType.FullName]);
|
||||
return
|
||||
new AddressCombinerNumericJump<TKey>((int)(count * Percentage / 100.0), MaxLength, AddressTranslator)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
namespace Modbus.Net
|
||||
using System;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址编码器
|
||||
/// </summary>
|
||||
public abstract class AddressFormater
|
||||
public abstract class AddressFormater<TAddressKey, TSubAddressKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
@@ -11,7 +13,7 @@
|
||||
/// <param name="area">地址所在的数据区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public abstract string FormatAddress(string area, int address);
|
||||
public abstract string FormatAddress(string area, TAddressKey address);
|
||||
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
@@ -20,13 +22,13 @@
|
||||
/// <param name="address">地址</param>
|
||||
/// <param name="subAddress">子地址</param>
|
||||
/// <returns>编码后的地址</returns>
|
||||
public abstract string FormatAddress(string area, int address, int subAddress);
|
||||
public abstract string FormatAddress(string area, TAddressKey address, TSubAddressKey subAddress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基本的地址编码器
|
||||
/// </summary>
|
||||
public class AddressFormaterBase : AddressFormater
|
||||
public class AddressFormaterBase : AddressFormater<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码地址
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Quartz.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -11,37 +12,12 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey, int, int>, IMachine<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
private static readonly ILogger<BaseMachine<TKey, TUnitKey>> logger = LogProvider.CreateLogger<BaseMachine<TKey, TUnitKey>>();
|
||||
|
||||
private readonly int _maxErrorCount = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
|
||||
: this(id, getAddresses, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
|
||||
{
|
||||
Id = id;
|
||||
GetAddresses = getAddresses;
|
||||
KeepConnect = keepConnect;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
@@ -50,70 +26,18 @@ namespace Modbus.Net
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="slaveAddress">从站地址</param>
|
||||
/// <param name="masterAddress">主站地址</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress,
|
||||
byte masterAddress) : this(id, getAddresses, keepConnect)
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress,
|
||||
byte masterAddress) : base(id, getAddresses, keepConnect)
|
||||
{
|
||||
SlaveAddress = slaveAddress;
|
||||
MasterAddress = masterAddress;
|
||||
}
|
||||
|
||||
|
||||
private readonly int _maxErrorCount = 3;
|
||||
|
||||
private int ErrorCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址编码器
|
||||
/// </summary>
|
||||
public AddressFormater AddressFormater { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取地址组合器
|
||||
/// </summary>
|
||||
public AddressCombiner<TUnitKey> AddressCombiner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入地址组合器
|
||||
/// </summary>
|
||||
public AddressCombiner<TUnitKey> AddressCombinerSet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址转换器
|
||||
/// </summary>
|
||||
public AddressTranslator AddressTranslator
|
||||
{
|
||||
get => BaseUtility.AddressTranslator;
|
||||
set => BaseUtility.AddressTranslator = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 与设备实际通讯的连续地址
|
||||
/// </summary>
|
||||
protected IEnumerable<CommunicationUnit<TUnitKey>> CommunicateAddresses
|
||||
=> GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null;
|
||||
|
||||
/// <summary>
|
||||
/// 描述需要与设备通讯的地址
|
||||
/// </summary>
|
||||
private IEnumerable<AddressUnit<TUnitKey>> getAddresses;
|
||||
|
||||
private object getAddressesLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 描述需要与设备通讯的地址
|
||||
/// </summary>
|
||||
public IEnumerable<AddressUnit<TUnitKey>> GetAddresses
|
||||
{
|
||||
get
|
||||
{
|
||||
return getAddresses;
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (getAddressesLock)
|
||||
{
|
||||
getAddresses = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
@@ -125,20 +49,26 @@ namespace Modbus.Net
|
||||
public byte MasterAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 读取数据
|
||||
/// 与设备实际通讯的连续地址
|
||||
/// </summary>
|
||||
/// <returns>从设备读取的数据</returns>
|
||||
public ReturnStruct<Dictionary<string, ReturnUnit<double>>> GetDatas(MachineDataType getDataType)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => GetDatasAsync(getDataType));
|
||||
}
|
||||
protected IEnumerable<CommunicationUnit<TUnitKey, int, int>> CommunicateAddresses
|
||||
=> GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null;
|
||||
|
||||
/// <summary>
|
||||
/// 获取地址组合器
|
||||
/// </summary>
|
||||
public AddressCombiner<TUnitKey, int, int> AddressCombiner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入地址组合器
|
||||
/// </summary>
|
||||
public AddressCombiner<TUnitKey, int, int> AddressCombinerSet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 读取数据
|
||||
/// </summary>
|
||||
/// <returns>从设备读取的数据</returns>
|
||||
public async Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType)
|
||||
public async override Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -316,18 +246,7 @@ namespace Modbus.Net
|
||||
/// <param name="setDataType">写入类型</param>
|
||||
/// <param name="values">需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述</param>
|
||||
/// <returns>是否写入成功</returns>
|
||||
public ReturnStruct<bool> SetDatas(MachineDataType setDataType, Dictionary<string, double> values)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SetDatasAsync(setDataType, values));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入数据
|
||||
/// </summary>
|
||||
/// <param name="setDataType">写入类型</param>
|
||||
/// <param name="values">需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述</param>
|
||||
/// <returns>是否写入成功</returns>
|
||||
public async Task<ReturnStruct<bool>> SetDatasAsync(MachineDataType setDataType, Dictionary<string, double> values)
|
||||
public async override Task<ReturnStruct<bool>> SetDatasAsync(MachineDataType setDataType, Dictionary<string, double> values)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -342,12 +261,12 @@ namespace Modbus.Net
|
||||
ErrorCode = -1,
|
||||
ErrorMsg = "Connection Error"
|
||||
};
|
||||
var addresses = new List<AddressUnit<TUnitKey>>();
|
||||
var addresses = new List<AddressUnit<TUnitKey, int, int>>();
|
||||
//遍历每个要设置的值
|
||||
foreach (var value in values)
|
||||
{
|
||||
//根据设置类型找到对应的地址描述
|
||||
AddressUnit<TUnitKey> address = null;
|
||||
AddressUnit<TUnitKey, int, int> address = null;
|
||||
switch (setDataType)
|
||||
{
|
||||
case MachineDataType.Address:
|
||||
@@ -550,6 +469,49 @@ namespace Modbus.Net
|
||||
ErrorMsg = ""
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
||||
/// <typeparam name="TAddressKey">设备中使用的AddressUnit的Address类型</typeparam>
|
||||
/// <typeparam name="TSubAddressKey">设备中使用的AddressUnit的SubAddress类型</typeparam>
|
||||
public abstract class BaseMachine<TKey, TUnitKey, TAddressKey, TSubAddressKey> : IMachine<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
where TAddressKey : IEquatable<TAddressKey>
|
||||
where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
private static readonly ILogger<BaseMachine<TKey, TUnitKey, TAddressKey, TSubAddressKey>> logger = LogProvider.CreateLogger<BaseMachine<TKey, TUnitKey, TAddressKey, TSubAddressKey>>();
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses)
|
||||
: this(id, getAddresses, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses, bool keepConnect)
|
||||
{
|
||||
Id = id;
|
||||
GetAddresses = getAddresses;
|
||||
KeepConnect = keepConnect;
|
||||
}
|
||||
|
||||
private readonly int _maxErrorCount = 3;
|
||||
|
||||
private int ErrorCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于连接状态
|
||||
@@ -586,6 +548,383 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public string ConnectionToken => BaseUtility.ConnectionToken;
|
||||
|
||||
/// <summary>
|
||||
/// 描述需要与设备通讯的地址
|
||||
/// </summary>
|
||||
private IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses;
|
||||
|
||||
private object getAddressesLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 描述需要与设备通讯的地址
|
||||
/// </summary>
|
||||
public IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> GetAddresses
|
||||
{
|
||||
get
|
||||
{
|
||||
return getAddresses;
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (getAddressesLock)
|
||||
{
|
||||
getAddresses = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址编码器
|
||||
/// </summary>
|
||||
public AddressFormater<TAddressKey, TSubAddressKey> AddressFormater { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址转换器
|
||||
/// </summary>
|
||||
public AddressTranslator AddressTranslator
|
||||
{
|
||||
get => BaseUtility.AddressTranslator;
|
||||
set => BaseUtility.AddressTranslator = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取数据
|
||||
/// </summary>
|
||||
/// <returns>从设备读取的数据</returns>
|
||||
public async virtual Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ans = new Dictionary<string, ReturnUnit<double>>();
|
||||
//检测并连接设备
|
||||
if (!BaseUtility.IsConnected)
|
||||
await BaseUtility.ConnectAsync();
|
||||
//如果无法连接,终止
|
||||
if (!BaseUtility.IsConnected) return
|
||||
new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -1,
|
||||
ErrorMsg = "Connection Error"
|
||||
};
|
||||
//遍历每一个实际向设备获取数据的连续地址
|
||||
foreach (var address in GetAddresses)
|
||||
{
|
||||
//获取数据
|
||||
var datas =
|
||||
await
|
||||
BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync(
|
||||
AddressFormater.FormatAddress(address.Area, address.Address,
|
||||
address.SubAddress),
|
||||
(int)
|
||||
Math.Ceiling(ValueHelper.ByteLength[
|
||||
address.DataType.FullName]));
|
||||
|
||||
|
||||
//如果没有数据,终止
|
||||
if (datas.IsSuccess == false || datas.Datas == null)
|
||||
{
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = false,
|
||||
ErrorCode = datas.ErrorCode,
|
||||
ErrorMsg = datas.ErrorMsg
|
||||
};
|
||||
}
|
||||
else if (datas.Datas.Length != 0 && datas.Datas.Length <
|
||||
(int)
|
||||
Math.Ceiling(ValueHelper.ByteLength[
|
||||
address.DataType.FullName]))
|
||||
{
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -2,
|
||||
ErrorMsg = "Data length mismatch"
|
||||
};
|
||||
}
|
||||
|
||||
//字节坐标的主地址位置
|
||||
var localMainPos = 0;
|
||||
//字节坐标的子地址位置
|
||||
var localSubPos = 0;
|
||||
|
||||
//根据类型选择返回结果的键是通讯标识还是地址
|
||||
string key;
|
||||
switch (getDataType)
|
||||
{
|
||||
case MachineDataType.CommunicationTag:
|
||||
{
|
||||
key = address.CommunicationTag;
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Address:
|
||||
{
|
||||
key = AddressFormater.FormatAddress(address.Area, address.Address, address.SubAddress);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Name:
|
||||
{
|
||||
key = address.Name;
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Id:
|
||||
{
|
||||
key = address.Id.ToString();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
key = address.CommunicationTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//如果没有数据返回空
|
||||
if (datas.Datas.Length == 0)
|
||||
ans.Add(key, new ReturnUnit<double>
|
||||
{
|
||||
DeviceValue = null,
|
||||
AddressUnit = address.MapAddressUnitTUnitKeyToAddressUnit(),
|
||||
});
|
||||
else
|
||||
ans.Add(key,
|
||||
new ReturnUnit<double>
|
||||
{
|
||||
DeviceValue =
|
||||
Math.Round(Convert.ToDouble(
|
||||
ValueHelper.GetInstance(BaseUtility.Endian)
|
||||
.GetValue(datas.Datas, ref localMainPos, ref localSubPos,
|
||||
address.DataType)) * address.Zoom, address.DecimalPos),
|
||||
AddressUnit = address.MapAddressUnitTUnitKeyToAddressUnit(),
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorCount++;
|
||||
logger.LogError(e, $"BaseMachine -> GetDatas, Id:{Id} Connection:{ConnectionToken} key {key} existing. ErrorCount {ErrorCount}.");
|
||||
|
||||
if (ErrorCount >= _maxErrorCount)
|
||||
Disconnect();
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -3,
|
||||
ErrorMsg = "Data translation mismatch"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//如果不保持连接,断开连接
|
||||
if (!KeepConnect)
|
||||
BaseUtility.Disconnect();
|
||||
//返回数据
|
||||
if (ans.All(p => p.Value.DeviceValue == null)) ans = null;
|
||||
ErrorCount = 0;
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>
|
||||
{
|
||||
Datas = ans,
|
||||
IsSuccess = true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = ""
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorCount++;
|
||||
logger.LogError(e, $"BaseMachine -> GetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}.");
|
||||
|
||||
if (ErrorCount >= _maxErrorCount)
|
||||
Disconnect();
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -100,
|
||||
ErrorMsg = "Unknown Exception"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入数据
|
||||
/// </summary>
|
||||
/// <param name="setDataType">写入类型</param>
|
||||
/// <param name="values">需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述</param>
|
||||
/// <returns>是否写入成功</returns>
|
||||
public async virtual Task<ReturnStruct<bool>> SetDatasAsync(MachineDataType setDataType, Dictionary<string, double> values)
|
||||
{
|
||||
try
|
||||
{
|
||||
//检测并连接设备
|
||||
if (!BaseUtility.IsConnected)
|
||||
await BaseUtility.ConnectAsync();
|
||||
//如果设备无法连接,终止
|
||||
if (!BaseUtility.IsConnected) return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = false,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -1,
|
||||
ErrorMsg = "Connection Error"
|
||||
};
|
||||
var addresses = new List<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>>();
|
||||
//遍历每个要设置的值
|
||||
foreach (var value in values)
|
||||
{
|
||||
//根据设置类型找到对应的地址描述
|
||||
AddressUnit<TUnitKey, TAddressKey, TSubAddressKey> address = null;
|
||||
switch (setDataType)
|
||||
{
|
||||
case MachineDataType.Address:
|
||||
{
|
||||
address =
|
||||
GetAddresses.SingleOrDefault(
|
||||
p =>
|
||||
AddressFormater.FormatAddress(p.Area, p.Address, p.SubAddress) == value.Key ||
|
||||
p.DataType != typeof(bool) &&
|
||||
AddressFormater.FormatAddress(p.Area, p.Address) == value.Key);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.CommunicationTag:
|
||||
{
|
||||
address =
|
||||
GetAddresses.SingleOrDefault(p => p.CommunicationTag == value.Key);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Name:
|
||||
{
|
||||
address = GetAddresses.SingleOrDefault(p => p.Name == value.Key);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Id:
|
||||
{
|
||||
address = GetAddresses.SingleOrDefault(p => p.Id.ToString() == value.Key);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
address =
|
||||
GetAddresses.SingleOrDefault(p => p.CommunicationTag == value.Key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//地址为空报错
|
||||
if (address == null)
|
||||
{
|
||||
logger.LogError($"Machine {ConnectionToken} Address {value.Key} doesn't exist.");
|
||||
continue;
|
||||
}
|
||||
//不能写报错
|
||||
if (!address.CanWrite)
|
||||
{
|
||||
logger.LogError($"Machine {ConnectionToken} Address {value.Key} cannot write.");
|
||||
continue;
|
||||
}
|
||||
addresses.Add(address);
|
||||
}
|
||||
|
||||
//遍历每条通讯的地址
|
||||
|
||||
|
||||
var valueHelper = ValueHelper.GetInstance(BaseUtility.Endian);
|
||||
|
||||
foreach (var addressUnit in addresses)
|
||||
{
|
||||
//协议主地址字符串
|
||||
var address = AddressFormater.FormatAddress(addressUnit.Area,
|
||||
addressUnit.Address, addressUnit.SubAddress);
|
||||
//获取写入类型
|
||||
var dataType = addressUnit.DataType;
|
||||
KeyValuePair<string, double> value;
|
||||
switch (setDataType)
|
||||
{
|
||||
case MachineDataType.Address:
|
||||
{
|
||||
//获取要写入的值
|
||||
value = values.SingleOrDefault(p => p.Key == address);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.CommunicationTag:
|
||||
{
|
||||
value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Name:
|
||||
{
|
||||
value = values.SingleOrDefault(p => p.Key == addressUnit.Name);
|
||||
break;
|
||||
}
|
||||
case MachineDataType.Id:
|
||||
{
|
||||
value = values.SingleOrDefault(p => p.Key == addressUnit.Id.ToString());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//将要写入的值加入队列
|
||||
var data = Convert.ChangeType(value.Value / addressUnit.Zoom, dataType);
|
||||
|
||||
//写入数据
|
||||
await
|
||||
BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().SetDatasAsync(address,
|
||||
new object[] { data });
|
||||
}
|
||||
//如果不保持连接,断开连接
|
||||
if (!KeepConnect)
|
||||
BaseUtility.Disconnect();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorCount++;
|
||||
logger.LogError(e, $"BaseMachine -> SetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}.");
|
||||
|
||||
if (ErrorCount >= _maxErrorCount)
|
||||
Disconnect();
|
||||
return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = false,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -100,
|
||||
ErrorMsg = "Unknown Exception"
|
||||
};
|
||||
}
|
||||
return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = true,
|
||||
IsSuccess = true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = ""
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过Id获取数据字段定义
|
||||
/// </summary>
|
||||
/// <param name="addressUnitId">数据字段Id</param>
|
||||
/// <returns>数据字段</returns>
|
||||
public AddressUnit<TUnitKey, TAddressKey, TSubAddressKey> GetAddressUnitById(TUnitKey addressUnitId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, $"BaseMachine -> GetAddressUnitById Id:{Id} ConnectionToken:{ConnectionToken} addressUnitId:{addressUnitId} Repeated");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备的方法集合
|
||||
/// </summary>
|
||||
@@ -627,24 +966,6 @@ namespace Modbus.Net
|
||||
{
|
||||
return BaseUtility.Disconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过Id获取数据字段定义
|
||||
/// </summary>
|
||||
/// <param name="addressUnitId">数据字段Id</param>
|
||||
/// <returns>数据字段</returns>
|
||||
public AddressUnit<TUnitKey> GetAddressUnitById(TUnitKey addressUnitId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, $"BaseMachine -> GetAddressUnitById Id:{Id} ConnectionToken:{ConnectionToken} addressUnitId:{addressUnitId} Repeated");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
|
||||
@@ -664,7 +985,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 通讯单元
|
||||
/// </summary>
|
||||
public class CommunicationUnit<TKey> where TKey : IEquatable<TKey>
|
||||
public class CommunicationUnit<TKey, TAddressKey, TSubAddressKey> where TKey : IEquatable<TKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 区域
|
||||
@@ -674,12 +995,12 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public int Address { get; set; }
|
||||
public TAddressKey Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子地址
|
||||
/// </summary>
|
||||
public int SubAddress { get; set; } = 0;
|
||||
public TSubAddressKey SubAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取个数
|
||||
@@ -694,7 +1015,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 原始的地址
|
||||
/// </summary>
|
||||
public IEnumerable<AddressUnit<TKey>> OriginalAddresses { get; set; }
|
||||
public IEnumerable<AddressUnit<TKey, TAddressKey, TSubAddressKey>> OriginalAddresses { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -710,20 +1031,13 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 数据定义
|
||||
/// </summary>
|
||||
public AddressUnit AddressUnit { get; set; }
|
||||
public AddressUnit<string, string, string> AddressUnit { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址单元
|
||||
/// </summary>
|
||||
public class AddressUnit : AddressUnit<string>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址单元
|
||||
/// </summary>
|
||||
public class AddressUnit<TKey> : IEquatable<AddressUnit<TKey>> where TKey : IEquatable<TKey>
|
||||
public class AddressUnit<TKey, TAddressKey, TSubAddressKey> : IEquatable<AddressUnit<TKey, TAddressKey, TSubAddressKey>> where TKey : IEquatable<TKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据单元Id
|
||||
@@ -738,12 +1052,12 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public int Address { get; set; }
|
||||
public TAddressKey Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// bit位地址
|
||||
/// </summary>
|
||||
public int SubAddress { get; set; } = 0;
|
||||
public TSubAddressKey SubAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据类型
|
||||
@@ -785,9 +1099,9 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="other">另一个地址</param>
|
||||
/// <returns>是否一致</returns>
|
||||
public bool Equals(AddressUnit<TKey> other)
|
||||
public bool Equals(AddressUnit<TKey, TAddressKey, TSubAddressKey> other)
|
||||
{
|
||||
return Area.ToUpper() == other.Area.ToUpper() && Address == other.Address || Id.Equals(other.Id);
|
||||
return Area.ToUpper() == other.Area.ToUpper() && Address.Equals(other.Address) || Id.Equals(other.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,14 +35,14 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="addressUnit"></param>
|
||||
/// <returns></returns>
|
||||
public static AddressUnit MapAddressUnitTUnitKeyToAddressUnit<TUnitKey>(this AddressUnit<TUnitKey> addressUnit) where TUnitKey : IEquatable<TUnitKey>
|
||||
public static AddressUnit<string, string, string> MapAddressUnitTUnitKeyToAddressUnit<TUnitKey, TAddressKey, TSubAddressKey>(this AddressUnit<TUnitKey, TAddressKey, TSubAddressKey> addressUnit) where TUnitKey : IEquatable<TUnitKey> where TAddressKey : IEquatable<TAddressKey> where TSubAddressKey : IEquatable<TSubAddressKey>
|
||||
{
|
||||
return new AddressUnit()
|
||||
return new AddressUnit<string, string, string>()
|
||||
{
|
||||
Id = addressUnit.Id.ToString(),
|
||||
Area = addressUnit.Area,
|
||||
Address = addressUnit.Address,
|
||||
SubAddress = addressUnit.SubAddress,
|
||||
Address = addressUnit.Address?.ToString(),
|
||||
SubAddress = addressUnit.SubAddress?.ToString(),
|
||||
DataType = addressUnit.DataType,
|
||||
Zoom = addressUnit.Zoom,
|
||||
DecimalPos = addressUnit.DecimalPos,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net462</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net</AssemblyName>
|
||||
<RootNamespace>Modbus.Net</RootNamespace>
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetty.Handlers" Version="0.7.5" />
|
||||
<PackageReference Include="FastEnum" Version="1.8.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
|
||||
@@ -146,18 +146,6 @@ namespace Modbus.Net
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
public virtual TPipeUnit SendReceive(
|
||||
TProtocolUnit unit, IInputStruct content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
@@ -177,16 +165,6 @@ namespace Modbus.Net
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
/// <param name="content">写入的内容,使用对象数组描述</param>
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
public virtual TPipeUnit SendReceive(params object[] content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法(不能使用,如需使用请继承)
|
||||
/// </summary>
|
||||
@@ -197,18 +175,6 @@ namespace Modbus.Net
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
|
||||
public virtual T SendReceive<T>(TProtocolUnit unit, IInputStruct content) where T : class, IOutputStruct
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync<T>(unit, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
|
||||
@@ -45,17 +45,6 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public byte MasterAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getByteCount">获取字节数个数</param>
|
||||
/// <returns>接收到的byte数据</returns>
|
||||
public virtual ReturnStruct<byte[]> GetDatas(string startAddress, int getByteCount)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getByteCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -64,18 +53,6 @@ namespace Modbus.Net
|
||||
/// <returns>接收到的byte数据</returns>
|
||||
public abstract Task<ReturnStruct<byte[]>> GetDatasAsync(string startAddress, int getByteCount);
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getTypeAndCount">获取类型和个数</param>
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
public virtual ReturnStruct<object[]> GetDatas(string startAddress,
|
||||
KeyValuePair<Type, int> getTypeAndCount)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getTypeAndCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -123,19 +100,6 @@ namespace Modbus.Net
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">需要接收的类型</typeparam>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getByteCount">获取字节数个数</param>
|
||||
/// <returns>接收到的对应的类型和数据</returns>
|
||||
public virtual ReturnStruct<T[]> GetDatas<T>(string startAddress,
|
||||
int getByteCount)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => GetDatasAsync<T>(startAddress, getByteCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -181,19 +145,6 @@ namespace Modbus.Net
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getTypeAndCountList">获取类型和个数的队列</param>
|
||||
/// <returns>获取数据的对象数组,请强制转换成相应类型</returns>
|
||||
public virtual ReturnStruct<object[]> GetDatas(string startAddress,
|
||||
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
|
||||
{
|
||||
return
|
||||
AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getTypeAndCountList));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
@@ -244,17 +195,6 @@ namespace Modbus.Net
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="setContents">设置数据</param>
|
||||
/// <returns>是否设置成功</returns>
|
||||
public virtual ReturnStruct<bool> SetDatas(string startAddress, object[] setContents)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SetDatasAsync(startAddress, setContents));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user