Fix 2 Add Full Comments And name Fix.

This commit is contained in:
parallelbgls
2017-05-04 12:00:07 +08:00
parent 99ab0bb261
commit 2581cbb74b
22 changed files with 596 additions and 139 deletions

View File

@@ -27,7 +27,7 @@ namespace Modbus.Net.Modbus
/// <summary>
/// Modbus基础Api入口
/// </summary>
public class ModbusUtility : BaseUtility, IUtilityTime
public class ModbusUtility : BaseUtility, IUtilityMethodTime
{
/// <summary>
/// Modbus协议类型

View File

@@ -7,11 +7,26 @@ namespace Modbus.Net
/// </summary>
public abstract class ComProtocalLinker : ProtocalLinker
{
/// <summary>
/// 构造器
/// </summary>
/// <param name="baudRate">波特率</param>
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits)
: this(ConfigurationManager.COM, baudRate, parity, stopBits, dataBits)
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="com">串口端口号</param>
/// <param name="baudRate">波特率</param>
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits)
{
//初始化连对象

View File

@@ -29,6 +29,11 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerContinus : AddressCombinerContinus<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="addressTranslator">地址转换器</param>
/// <param name="maxLength">单个发送协议允许的数据最长长度(字节)</param>
public AddressCombinerContinus(AddressTranslator addressTranslator, int maxLength) : base(addressTranslator, maxLength)
{
}
@@ -39,16 +44,32 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerContinus<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 协议的数据最长长度(字节)
/// </summary>
protected int MaxLength { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="addressTranslator">地址转换器</param>
/// <param name="maxLength">单个发送协议允许的数据最长长度(字节)</param>
public AddressCombinerContinus(AddressTranslator addressTranslator, int maxLength)
{
AddressTranslator = addressTranslator;
MaxLength = maxLength;
}
/// <summary>
/// 地址转换器
/// </summary>
protected AddressTranslator AddressTranslator { get; set; }
/// <summary>
/// 组合地址
/// </summary>
/// <param name="addresses">需要组合的地址</param>
/// <returns>组合后的地址</returns>
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
//按从小到大的顺序对地址进行排序
@@ -218,6 +239,11 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerSingle<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 组合地址
/// </summary>
/// <param name="addresses">需要组合的地址</param>
/// <returns>组合后的地址</returns>
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
return
@@ -249,6 +275,12 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerNumericJump : AddressCombinerNumericJump<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="jumpByteCount">需要跳过的字节个数</param>
/// <param name="maxLength">单个协议允许的数据最长长度(字节)</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerNumericJump(int jumpByteCount, int maxLength, AddressTranslator addressTranslator)
: base(jumpByteCount, maxLength, addressTranslator)
{
@@ -260,14 +292,28 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerNumericJump<TKey> : AddressCombinerContinus<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="jumpByteCount">需要跳过的字节个数</param>
/// <param name="maxLength">单个协议允许的数据最长长度(字节)</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerNumericJump(int jumpByteCount, int maxLength, AddressTranslator addressTranslator)
: base(addressTranslator, maxLength)
{
JumpNumber = jumpByteCount;
}
/// <summary>
/// 跳过的地址长度
/// </summary>
private int JumpNumber { get; }
/// <summary>
/// 组合地址
/// </summary>
/// <param name="addresses">需要组合的地址</param>
/// <returns>组合后的地址</returns>
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
var continusAddresses = base.Combine(addresses).ToList();
@@ -339,6 +385,12 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerPercentageJump : AddressCombinerPercentageJump<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="percentage">允许跳过的字节数除以待组合的地址的字节数的百分比</param>
/// <param name="maxLength">单个协议允许的数据最大长度</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerPercentageJump(double percentage, int maxLength, AddressTranslator addressTranslator)
: base(percentage, maxLength, addressTranslator)
{
@@ -350,6 +402,12 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerPercentageJump<TKey> : AddressCombinerContinus<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="percentage">允许跳过的字节数除以待组合的地址的字节数的百分比</param>
/// <param name="maxLength">单个协议允许的数据最大长度</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerPercentageJump(double percentage, int maxLength, AddressTranslator addressTranslator)
: base(addressTranslator, maxLength)
{
@@ -357,8 +415,16 @@ namespace Modbus.Net
Percentage = percentage;
}
/// <summary>
/// 跳过的百分比
/// </summary>
private double Percentage { get; }
/// <summary>
/// 组合地址
/// </summary>
/// <param name="addresses">需要组合的地址</param>
/// <returns>组合后的地址</returns>
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
var addressUnits = addresses as IList<AddressUnit<TKey>> ?? addresses.ToList();

View File

@@ -5,6 +5,12 @@
/// </summary>
public abstract class AddressFormater
{
/// <summary>
/// 编码地址
/// </summary>
/// <param name="area">地址所在的数据区域</param>
/// <param name="address">地址</param>
/// <returns>编码后的地址</returns>
public abstract string FormatAddress(string area, int address);
/// <summary>
@@ -22,11 +28,24 @@
/// </summary>
public class AddressFormaterBase : AddressFormater
{
/// <summary>
/// 编码地址
/// </summary>
/// <param name="area">地址所在的数据区域</param>
/// <param name="address">地址</param>
/// <returns>编码后的地址</returns>
public override string FormatAddress(string area, int address)
{
return area + ":" + address;
}
/// <summary>
/// 编码地址
/// </summary>
/// <param name="area">地址所在的数据区域</param>
/// <param name="address">地址</param>
/// <param name="subAddress">子地址</param>
/// <returns>编码后的地址</returns>
public override string FormatAddress(string area, int address, int subAddress)
{
return area + ":" + address + ":" + subAddress;

View File

@@ -7,18 +7,36 @@ namespace Modbus.Net
/// </summary>
public class AddressDef
{
/// <summary>
/// 地址区域的字符串描述
/// </summary>
public string AreaString { get; set; }
/// <summary>
/// 地址区域的数字描述
/// </summary>
public int Area { get; set; }
/// <summary>
/// 地址
/// </summary>
public int Address { get; set; }
/// <summary>
/// 子地址
/// </summary>
public int SubAddress { get; set; }
}
/// <summary>
/// 区域数据定义类
/// 地址区域数据定义类
/// </summary>
public class AreaOutputDef
{
/// <summary>
/// 地址区域的编码
/// </summary>
public int Code { get; set; }
/// <summary>
/// 地址区域的单个地址占用的字节数
/// </summary>
public double AreaWidth { get; set; }
}
@@ -48,6 +66,12 @@ namespace Modbus.Net
/// </summary>
public class AddressTranslatorBase : AddressTranslator
{
/// <summary>
/// 地址转换
/// </summary>
/// <param name="address">地址前地址</param>
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
/// <returns>Key为转换后的地址Value为辅助码</returns>
public override AddressDef AddressTranslate(string address, bool isRead)
{
int num1, num2, num3;
@@ -79,6 +103,11 @@ namespace Modbus.Net
throw new FormatException();
}
/// <summary>
/// 获取区域中的单个地址占用的字节长度
/// </summary>
/// <param name="area">区域名称</param>
/// <returns>字节长度</returns>
public override double GetAreaByteLength(string area)
{
return 1;

View File

@@ -84,24 +84,48 @@ namespace Modbus.Net
Id
}
/// <summary>
/// 设备
/// </summary>
public abstract class BaseMachine : BaseMachine<string, string>
{
/// <summary>
/// 构造器
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses) : base(getAddresses)
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress,
byte masterAddress) : base(getAddresses, keepConnect, slaveAddress, masterAddress)
{
}
}
public abstract class BaseMachine<TKey, TUnitKey> : IMachineData, IMachineProperty<TKey> where TKey : IEquatable<TKey>
/// <summary>
/// 设备
/// </summary>
/// <typeparam name="TKey">设备的Id类型</typeparam>
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
public abstract class BaseMachine<TKey, TUnitKey> : IMachineMethodData, IMachineProperty<TKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
private readonly int _maxErrorCount = 3;
@@ -254,7 +278,7 @@ namespace Modbus.Net
//获取数据
var datas =
await
BaseUtility.InvokeUtilityMethod<IUtilityData, Task<byte[]>>("GetDatasAsync",
BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<byte[]>>("GetDatasAsync",
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address,
communicateAddress.SubAddress),
(int)
@@ -454,7 +478,7 @@ namespace Modbus.Net
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address);
var datasReturn = await BaseUtility.InvokeUtilityMethod<IUtilityData, Task<byte[]>>("GetDatasAsync",
var datasReturn = await BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<byte[]>>("GetDatasAsync",
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount*
@@ -544,7 +568,7 @@ namespace Modbus.Net
}
//写入数据
await
BaseUtility.InvokeUtilityMethod<IUtilityData, Task<bool>>("SetDatasAsync",addressStart,
BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<bool>>("SetDatasAsync",addressStart,
valueHelper.ByteArrayToObjectArray(datas,
new KeyValuePair<Type, int>(communicateAddress.DataType, communicateAddress.GetCount)));
}
@@ -639,7 +663,7 @@ namespace Modbus.Net
}
}
public class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
where TKey : IEquatable<TKey>
{
public bool Equals(IMachineProperty<TKey> x, IMachineProperty<TKey> y)
@@ -793,10 +817,7 @@ namespace Modbus.Net
public UnitExtend UnitExtend { get; set; }
}
/// <summary>
/// AddressUnit大小比较
/// </summary>
public struct AddressUnitEqualityComparer<TKey> : IEqualityComparer<AddressUnit<TKey>> where TKey : IEquatable<TKey>
internal struct AddressUnitEqualityComparer<TKey> : IEqualityComparer<AddressUnit<TKey>> where TKey : IEquatable<TKey>
{
public bool Equals(AddressUnit<TKey> x, AddressUnit<TKey> y)
{

View File

@@ -22,16 +22,6 @@ namespace Modbus.Net
{
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
public virtual byte[] SendReceive(params object[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content));
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
@@ -54,7 +44,7 @@ namespace Modbus.Net
/// <summary>
/// 基本协议
/// </summary>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> : IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
{
/// <summary>
/// 构造器
@@ -67,9 +57,18 @@ namespace Modbus.Net
MasterAddress = masterAddress;
}
/// <summary>
/// 协议的端格式
/// </summary>
protected Endian Endian { get; set; }
/// <summary>
/// 从站地址
/// </summary>
public byte SlaveAddress { get; set; }
/// <summary>
/// 主站地址
/// </summary>
public byte MasterAddress { get; set; }
/// <summary>
@@ -181,7 +180,22 @@ namespace Modbus.Net
return null;
}
public virtual async Task<byte[]> SendReceiveAsync(params object[] content)
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
public virtual byte[] SendReceive(params object[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
public virtual Task<byte[]> SendReceiveAsync(params object[] content)
{
throw new NotImplementedException();
}

View File

@@ -48,7 +48,7 @@ namespace Modbus.Net
/// <summary>
/// 基础Api入口
/// </summary>
public abstract class BaseUtility<TParamIn, TParamOut> : IUtilityProperty, IUtilityData
public abstract class BaseUtility<TParamIn, TParamOut> : IUtilityProperty, IUtilityMethodData
{
/// <summary>
/// 协议收发主体

View File

@@ -7,15 +7,27 @@ using System;
namespace Modbus.Net
{
/// <summary>
/// CRC-LRC校验工具
/// </summary>
public class Crc16
{
private static Crc16 _crc16;
private Crc16()
{
}
/// <summary>
/// CRC验证表
/// </summary>
public byte[] crc_table = new byte[512];
private byte[] crc_table = new byte[512];
/// <summary>
/// 获取校验工具实例
/// </summary>
/// <returns></returns>
public static Crc16 GetInstance()
{
if (_crc16 == null)
@@ -88,12 +100,14 @@ namespace Modbus.Net
#endregion
#region LRC验证
/// <summary>
/// 取模FF(255)
/// 取反+1
/// </summary>
/// <param name="writeUncheck"></param>
/// <returns></returns>
/// <param name="message">待验证的LRC消息</param>
/// <returns>LRC校验是否正确</returns>
public bool LrcEfficacy(string message)
{
var index = message.IndexOf(Environment.NewLine, StringComparison.Ordinal);
@@ -176,6 +190,15 @@ namespace Modbus.Net
return hexTotal == checkString;
}
#endregion
#region LRC码
/// <summary>
/// 生成LRC校验码
/// </summary>
/// <param name="code">需要生成的信息</param>
/// <returns>生成的校验码</returns>
public string GetLRC(byte[] code)
{
byte sum = 0;
@@ -183,9 +206,12 @@ namespace Modbus.Net
{
sum += b;
}
sum = (byte) (~sum + 1); //取反+1
sum = (byte)(~sum + 1); //取反+1
var lrc = sum.ToString("X2");
return lrc;
}
#endregion
}
}

View File

@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// Machine读写方法接口
/// </summary>
public interface IMachineMethod
{
@@ -14,7 +17,7 @@ namespace Modbus.Net
/// <summary>
/// Machine的数据读写接口
/// </summary>
public interface IMachineData : IMachineMethod
public interface IMachineMethodData : IMachineMethod
{
/// <summary>
/// 读取数据

View File

@@ -6,23 +6,27 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
public interface IProtocal
/// <summary>
/// 协议接口
/// </summary>
/// <typeparam name="TParamIn">向Connector传入的类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的类型</typeparam>
/// <typeparam name="TProtocalUnit">协议单元的类型</typeparam>
public interface IProtocal<TParamIn, TParamOut, in TProtocalUnit> where TProtocalUnit : IProtocalFormatting<TParamIn, TParamOut>
{
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="isLittleEndian">是否是小端格式</param>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
byte[] SendReceive(bool isLittleEndian, params object[] content);
byte[] SendReceive(params object[] content);
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="isLittleEndian">是否是小端格式</param>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
Task<byte[]> SendReceiveAsync(bool isLittleEndian, params object[] content);
Task<byte[]> SendReceiveAsync(params object[] content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -30,7 +34,7 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content);
IOutputStruct SendReceive(TProtocalUnit unit, IInputStruct content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -38,6 +42,6 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
Task<IOutputStruct> SendReceiveAsync(ProtocalUnit unit, IInputStruct content);
Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content);
}
}

View File

@@ -11,6 +11,8 @@
/// <summary>
/// 协议转换的接口
/// </summary>
/// <typeparam name="TParamIn">向Connector传入的数据类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的数据类型</typeparam>
public interface IProtocalFormatting<out TParamIn, in TParamOut>
{
/// <summary>

View File

@@ -6,55 +6,60 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
public interface IProtocalLinker
/// <summary>
/// 协议连接器接口
/// </summary>
/// <typeparam name="TParamIn">向Connector传入的数据类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的数据类型</typeparam>
public interface IProtocalLinker<TParamIn, TParamOut>
{
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
byte[] SendReceive(byte[] content);
TParamOut SendReceive(TParamIn content);
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
Task<byte[]> SendReceiveAsync(byte[] content);
Task<TParamOut> SendReceiveAsync(TParamIn content);
/// <summary>
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
byte[] SendReceiveWithoutExtAndDec(byte[] content);
TParamOut SendReceiveWithoutExtAndDec(TParamIn content);
/// <summary>
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
Task<byte[]> SendReceiveWithoutExtAndDecAsync(byte[] content);
Task<TParamOut> SendReceiveWithoutExtAndDecAsync(TParamIn content);
/// <summary>
/// 检查接收的数据是否正确
/// </summary>
/// <param name="content">接收协议的内容</param>
/// <returns>协议是否是正确的</returns>
bool? CheckRight(byte[] content);
bool? CheckRight(TParamOut content);
/// <summary>
/// 协议内容扩展,发送时根据需要扩展
/// </summary>
/// <param name="content">扩展前的基本协议内容</param>
/// <returns>扩展后的协议内容</returns>
byte[] BytesExtend(byte[] content);
TParamIn BytesExtend(TParamIn content);
/// <summary>
/// 协议内容缩减,接收时根据需要缩减
/// </summary>
/// <param name="content">缩减前的完整协议内容</param>
/// <returns>缩减后的协议内容</returns>
byte[] BytesDecact(byte[] content);
TParamOut BytesDecact(TParamOut content);
}
}

View File

@@ -3,20 +3,28 @@
/// <summary>
/// 协议字节伸缩
/// </summary>
public interface IProtocalLinkerBytesExtend
public interface IProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend<byte[], byte[]>
{
}
/// <summary>
/// 协议字节伸缩
/// </summary>
public interface IProtocalLinkerBytesExtend<TParamIn, TParamOut>
{
/// <summary>
/// 协议扩展,协议内容发送前调用
/// </summary>
/// <param name="content">扩展前的原始协议内容</param>
/// <returns>扩展后的协议内容</returns>
byte[] BytesExtend(byte[] content);
TParamIn BytesExtend(TParamIn content);
/// <summary>
/// 协议收缩,协议内容接收后调用
/// </summary>
/// <param name="content">收缩前的完整协议内容</param>
/// <returns>收缩后的协议内容</returns>
byte[] BytesDecact(byte[] content);
TParamOut BytesDecact(TParamOut content);
}
}

View File

@@ -6,15 +6,18 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// Utility方法读写接口
/// </summary>
public interface IUtilityMethod
{
}
/// <summary>
/// Utility的数据读写接口
/// Utility的数据读写接口
/// </summary>
public interface IUtilityData : IUtilityMethod
public interface IUtilityMethodData : IUtilityMethod
{
/// <summary>
/// 获取数据
@@ -91,19 +94,19 @@ namespace Modbus.Net
}
/// <summary>
/// Utility的时间读写接口
/// Utility的时间读写接口
/// </summary>
public interface IUtilityTime : IUtilityMethod
public interface IUtilityMethodTime : IUtilityMethod
{
/// <summary>
/// 获取PLC时间
/// 获取PLC时间
/// </summary>
/// <returns>PLC时间</returns>
Task<DateTime> GetTimeAsync();
/// <summary>
/// 设置PLC时间
/// 设置PLC时间
/// </summary>
/// <param name="setTime">设置PLC时间</param>
/// <returns>设置是否成功</returns>

View File

@@ -9,6 +9,9 @@ namespace Modbus.Net
/// </summary>
public abstract class ProtocalLinker : ProtocalLinker<byte[], byte[]>
{
/// <summary>
/// 传输连接器
/// </summary>
protected new BaseConnector BaseConnector;
/// <summary>
@@ -70,10 +73,16 @@ namespace Modbus.Net
/// <summary>
/// 基本的协议连接器
/// </summary>
public abstract class ProtocalLinker<TParamIn, TParamOut>
public abstract class ProtocalLinker<TParamIn, TParamOut> : IProtocalLinker<TParamIn, TParamOut>
{
/// <summary>
/// 传输连接器
/// </summary>
protected BaseConnector<TParamIn, TParamOut> BaseConnector;
/// <summary>
/// 通讯字符串
/// </summary>
public string ConnectionToken => BaseConnector.ConnectionToken;
/// <summary>

View File

@@ -95,6 +95,10 @@ namespace Modbus.Net
/// </summary>
public class ProtocalErrorException : Exception
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="message"></param>
public ProtocalErrorException(string message)
: base(message)
{

View File

@@ -725,7 +725,7 @@ namespace Modbus.Net
machine = _machines.FirstOrDefault(p => p.ConnectionToken == connectionToken);
}
if (machine == null) return false;
return await machine.InvokeMachineMethod<IMachineData, Task<bool>>("SetDatasAsync", SetDataType, values);
return await machine.InvokeMachineMethod<IMachineMethodData, Task<bool>>("SetDatasAsync", SetDataType, values);
}
/// <summary>
@@ -799,7 +799,7 @@ namespace Modbus.Net
cts.CancelAfter(TimeSpan.FromSeconds(_getCycle));
//读取数据
var ans =
await machine.InvokeMachineMethod<IMachineData, Task<Dictionary<string, ReturnUnit>>>("GetDatasAsync",
await machine.InvokeMachineMethod<IMachineMethodData, Task<Dictionary<string, ReturnUnit>>>("GetDatasAsync",
GetDataType).WithCancellation(cts.Token);
if (!machine.IsConnected)
{

View File

@@ -10,12 +10,19 @@ namespace Modbus.Net
/// </summary>
public class SocketMessageEventArgs : EventArgs
{
/// <summary>
/// 构造器
/// </summary>
/// <param name="message">需要返回的信息</param>
public SocketMessageEventArgs(byte[] message)
{
Message = message;
}
public byte[] Message { get; set; }
/// <summary>
/// 返回的信息
/// </summary>
public byte[] Message { get; }
}
/// <summary>
@@ -39,6 +46,12 @@ namespace Modbus.Net
private bool m_disposed;
/// <summary>
/// 构造器
/// </summary>
/// <param name="ipaddress">Ip地址</param>
/// <param name="port">端口</param>
/// <param name="timeoutTime">超时时间</param>
public TcpConnector(string ipaddress, int port, int timeoutTime)
{
_host = ipaddress;
@@ -46,8 +59,14 @@ namespace Modbus.Net
TimeoutTime = timeoutTime;
}
/// <summary>
/// 连接关键字
/// </summary>
public override string ConnectionToken => _host;
/// <summary>
/// 超时时间
/// </summary>
public int TimeoutTime
{
get { return _timeoutTime; }
@@ -61,6 +80,9 @@ namespace Modbus.Net
}
}
/// <summary>
/// 是否已经连接
/// </summary>
public override bool IsConnected => _socketClient?.Client != null && _socketClient.Connected;
/// <summary>
@@ -106,11 +128,19 @@ namespace Modbus.Net
Dispose(false);
}
/// <summary>
/// 连接
/// </summary>
/// <returns>是否连接成功</returns>
public override bool Connect()
{
return AsyncHelper.RunSync(ConnectAsync);
}
/// <summary>
/// 连接
/// </summary>
/// <returns>是否连接成功</returns>
public override async Task<bool> ConnectAsync()
{
if (_socketClient != null)
@@ -150,6 +180,10 @@ namespace Modbus.Net
}
}
/// <summary>
/// 断开
/// </summary>
/// <returns>是否断开成功</returns>
public override bool Disconnect()
{
if (_socketClient == null)
@@ -183,6 +217,11 @@ namespace Modbus.Net
Console.WriteLine(message);
}
/// <summary>
/// 发送数据,不需要返回任何值
/// </summary>
/// <param name="message">发送的信息</param>
/// <returns>是否发送成功</returns>
public override bool SendMsgWithoutReturn(byte[] message)
{
return AsyncHelper.RunSync(() => SendMsgWithoutReturnAsync(message));
@@ -219,6 +258,11 @@ namespace Modbus.Net
}
}
/// <summary>
/// 发送数据,需要返回
/// </summary>
/// <param name="message">发送的数据</param>
/// <returns>是否发送成功</returns>
public override byte[] SendMsg(byte[] message)
{
return AsyncHelper.RunSync(() => SendMsgAsync(message));
@@ -256,6 +300,11 @@ namespace Modbus.Net
}
}
/// <summary>
/// 接收返回消息
/// </summary>
/// <param name="stream">Network Stream</param>
/// <returns>返回的消息</returns>
protected async Task<byte[]> ReceiveAsync(NetworkStream stream)
{
try

View File

@@ -5,10 +5,18 @@
/// </summary>
public abstract class TcpProtocalLinker : ProtocalLinker
{
/// <summary>
/// 构造器
/// </summary>
protected TcpProtocalLinker() : this(ConfigurationManager.IP, int.Parse(ConfigurationManager.ModbusPort))
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="ip">Ip地址</param>
/// <param name="port">端口</param>
protected TcpProtocalLinker(string ip, int port)
{
//初始化连接对象

View File

@@ -7,10 +7,13 @@ using System.Text;
namespace Modbus.Net
{
/// <summary>
/// 值与字节数组之间转换的辅助类这是一个Singleton类
/// 值与字节数组之间转换的辅助类(小端格式)这是一个Singleton类
/// </summary>
public class ValueHelper
{
/// <summary>
/// 兼容数据类型对应的字节长度
/// </summary>
public Dictionary<string, double> ByteLength = new Dictionary<string, double>
{
{"System.Boolean", 0.125},
@@ -25,6 +28,9 @@ namespace Modbus.Net
{"System.Double", 8}
};
/// <summary>
/// 构造器
/// </summary>
protected ValueHelper()
{
}
@@ -34,6 +40,9 @@ namespace Modbus.Net
/// </summary>
public static bool LittleEndian => true;
/// <summary>
/// 协议中的比特位内容构造是否小端的,默认是小端构造协议。
/// </summary>
public static bool LittleEndianBit => true;
/// <summary>
@@ -49,8 +58,8 @@ namespace Modbus.Net
/// <summary>
/// 将short数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(short value)
{
return BitConverter.GetBytes(value);
@@ -59,8 +68,8 @@ namespace Modbus.Net
/// <summary>
/// 将int数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(int value)
{
return BitConverter.GetBytes(value);
@@ -69,8 +78,8 @@ namespace Modbus.Net
/// <summary>
/// 将long数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(long value)
{
return BitConverter.GetBytes(value);
@@ -79,8 +88,8 @@ namespace Modbus.Net
/// <summary>
/// 将ushort数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(ushort value)
{
return BitConverter.GetBytes(value);
@@ -89,8 +98,8 @@ namespace Modbus.Net
/// <summary>
/// 将uint数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(uint value)
{
return BitConverter.GetBytes(value);
@@ -99,8 +108,8 @@ namespace Modbus.Net
/// <summary>
/// 将ulong数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(ulong value)
{
return BitConverter.GetBytes(value);
@@ -109,8 +118,8 @@ namespace Modbus.Net
/// <summary>
/// 将float数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(float value)
{
return BitConverter.GetBytes(value);
@@ -119,8 +128,8 @@ namespace Modbus.Net
/// <summary>
/// 将double数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(double value)
{
return BitConverter.GetBytes(value);
@@ -129,9 +138,9 @@ namespace Modbus.Net
/// <summary>
/// 将object数字转换为byte数组
/// </summary>
/// <param name="value"></param>
/// <param name="type"></param>
/// <returns></returns>
/// <param name="value">待转换的值</param>
/// <param name="type">待转换的值的类型</param>
/// <returns>转换后的byte数组</returns>
public virtual byte[] GetBytes(object value, Type type)
{
switch (type.FullName)
@@ -191,11 +200,11 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为对应类型的数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <param name="subPos"></param>
/// <param name="t"></param>
/// <returns></returns>
/// <param name="data">待转换的字节数组</param>
/// <param name="pos">转换数字的位置</param>
/// <param name="subPos">转换数字的比特位置仅Type为bool的时候有效</param>
/// <param name="t">转换的类型</param>
/// <returns>转换出的数字</returns>
public virtual object GetValue(byte[] data, ref int pos, ref int subPos, Type t)
{
switch (t.FullName)
@@ -260,9 +269,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为byte数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual byte GetByte(byte[] data, ref int pos)
{
var t = data[pos];
@@ -273,9 +282,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为short数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual short GetShort(byte[] data, ref int pos)
{
var t = BitConverter.ToInt16(data, pos);
@@ -286,9 +295,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为int数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual int GetInt(byte[] data, ref int pos)
{
var t = BitConverter.ToInt32(data, pos);
@@ -299,9 +308,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为long数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual long GetLong(byte[] data, ref int pos)
{
var t = BitConverter.ToInt64(data, pos);
@@ -312,9 +321,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为ushort数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual ushort GetUShort(byte[] data, ref int pos)
{
var t = BitConverter.ToUInt16(data, pos);
@@ -325,9 +334,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为uint数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual uint GetUInt(byte[] data, ref int pos)
{
var t = BitConverter.ToUInt32(data, pos);
@@ -338,9 +347,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为ulong数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual ulong GetULong(byte[] data, ref int pos)
{
var t = BitConverter.ToUInt64(data, pos);
@@ -351,9 +360,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为float数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual float GetFloat(byte[] data, ref int pos)
{
var t = BitConverter.ToSingle(data, pos);
@@ -364,9 +373,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为double数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public virtual double GetDouble(byte[] data, ref int pos)
{
var t = BitConverter.ToDouble(data, pos);
@@ -377,11 +386,11 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为字符串
/// </summary>
/// <param name="data"></param>
/// <param name="count"></param>
/// <param name="pos"></param>
/// <param name="encoding"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="count">转换的个数</param>
/// <param name="pos">转换数字的位置</param>
/// <param name="encoding">编码方法</param>
/// <returns>转换出的字符串</returns>
public virtual string GetString(byte[] data, int count, ref int pos, Encoding encoding)
{
var t = encoding.GetString(data, pos, count);
@@ -392,9 +401,9 @@ namespace Modbus.Net
/// <summary>
/// 将byte数组中相应的位置转换为8个bit数字
/// </summary>
/// <param name="data"></param>
/// <param name="pos"></param>
/// <returns></returns>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的位数组</returns>
public virtual bool[] GetBits(byte[] data, ref int pos)
{
var t = new bool[8];
@@ -438,10 +447,10 @@ namespace Modbus.Net
/// <summary>
/// 获取一个字节数组中某个Bit位的数据
/// </summary>
/// <param name="number"></param>
/// <param name="pos"></param>
/// <param name="subPos"></param>
/// <returns></returns>
/// <param name="number">byte数字</param>
/// <param name="pos">bit数组中的对应位置</param>
/// <param name="subPos">小数位</param>
/// <returns>对应位置的bit元素</returns>
public virtual bool GetBit(byte[] number, ref int pos, ref int subPos)
{
return GetBit(number[pos], ref pos, ref subPos);
@@ -450,8 +459,8 @@ namespace Modbus.Net
/// <summary>
/// 反转一个字节的8个Bit位
/// </summary>
/// <param name="originalByte"></param>
/// <returns></returns>
/// <param name="originalByte">原始bit数组</param>
/// <returns>反转的bit数组</returns>
public virtual byte ReverseByte(byte originalByte)
{
byte result = 0;
@@ -467,8 +476,8 @@ namespace Modbus.Net
/// <summary>
/// 将待转换的对象数组转换为需要发送的byte数组
/// </summary>
/// <param name="contents"></param>
/// <returns></returns>
/// <param name="contents">object数组</param>
/// <returns>byte数组</returns>
public virtual byte[] ObjectArrayToByteArray(object[] contents)
{
var b = false;
@@ -606,10 +615,10 @@ namespace Modbus.Net
/// <summary>
/// 将一个byte数组转换成用户指定类型的数组使用模板参数确定需要转换的类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="contents"></param>
/// <param name="getCount"></param>
/// <returns></returns>
/// <typeparam name="T">目标数组类型</typeparam>
/// <param name="contents">待转换的数组</param>
/// <param name="getCount">转换的个数</param>
/// <returns>以T为类型的数组</returns>
public virtual T[] ByteArrayToDestinationArray<T>(byte[] contents, int getCount)
{
var objectArray = _Instance.ByteArrayToObjectArray(contents,
@@ -733,6 +742,14 @@ namespace Modbus.Net
return array;
}
/// <summary>
/// 在一个数组中写一个值
/// </summary>
/// <param name="contents">待写入的字节数组</param>
/// <param name="setPos">设置的位置</param>
/// <param name="subPos">设置的比特位位置仅setValue为bit的时候有效</param>
/// <param name="setValue">写入的值</param>
/// <returns>写入是否成功</returns>
public bool SetValue(byte[] contents, int setPos, int subPos, object setValue)
{
var type = setValue.GetType();
@@ -802,7 +819,7 @@ namespace Modbus.Net
/// <param name="contents">待设置的byte数组</param>
/// <param name="pos">设置的位置</param>
/// <param name="setValue">要设置的值</param>
/// <returns></returns>
/// <returns>设置是否成功</returns>
public virtual bool SetValue(byte[] contents, int pos, object setValue)
{
try
@@ -823,7 +840,7 @@ namespace Modbus.Net
/// <param name="number">byte数子</param>
/// <param name="subPos">设置位置</param>
/// <param name="setBit">设置bit大小true为1false为0</param>
/// <returns></returns>
/// <returns>设置是否成功</returns>
protected byte SetBit(byte number, int subPos, bool setBit)
{
var creation = 0;
@@ -851,7 +868,7 @@ namespace Modbus.Net
/// <param name="pos">位置</param>
/// <param name="subPos">bit位置</param>
/// <param name="setValue">bit数</param>
/// <returns></returns>
/// <returns>设置是否成功</returns>
public virtual bool SetBit(byte[] contents, int pos, int subPos, bool setValue)
{
try
@@ -869,6 +886,9 @@ namespace Modbus.Net
private static ValueHelper _instance;
/// <summary>
/// 实例,继承时请把它覆写掉
/// </summary>
protected virtual ValueHelper _Instance => _instance;
/// <summary>
@@ -876,6 +896,11 @@ namespace Modbus.Net
/// </summary>
public static ValueHelper Instance => _instance ?? (_instance = new ValueHelper());
/// <summary>
/// 根据端格式获取ValueHelper实例
/// </summary>
/// <param name="endian">端格式</param>
/// <returns>对应的ValueHelper实例</returns>
public static ValueHelper GetInstance(Endian endian)
{
switch (endian)
@@ -902,61 +927,123 @@ namespace Modbus.Net
#endregion
}
/// <summary>
/// 值与字节数组之间转换的辅助类大端格式这是一个Singleton类
/// </summary>
public class BigEndianValueHelper : ValueHelper
{
private static BigEndianValueHelper _bigEndianInstance;
/// <summary>
/// 构造器
/// </summary>
protected BigEndianValueHelper()
{
}
/// <summary>
/// 覆写的实例获取
/// </summary>
protected override ValueHelper _Instance => _bigEndianInstance;
/// <summary>
/// 是否为大端
/// </summary>
protected new bool LittleEndian => false;
/// <summary>
/// 覆盖的获取实例的方法
/// </summary>
public new static BigEndianValueHelper Instance
=> _bigEndianInstance ?? (_bigEndianInstance = new BigEndianValueHelper());
/// <summary>
/// 将short数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(short value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将int数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(int value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将long数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
/// <returns>转换出的数字</returns>
public override byte[] GetBytes(long value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将ushort数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(ushort value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将uint数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(uint value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将ulong数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(ulong value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将float数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(float value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将double数字转换为byte数组
/// </summary>
/// <param name="value">待转换的值</param>
/// <returns>转换后的byte数组</returns>
public override byte[] GetBytes(double value)
{
return Reverse(BitConverter.GetBytes(value));
}
/// <summary>
/// 将byte数组中相应的位置转换为short数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override short GetShort(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 2);
@@ -966,6 +1053,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为int数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override int GetInt(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
@@ -975,6 +1068,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为long数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override long GetLong(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
@@ -984,6 +1083,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为ushort数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override ushort GetUShort(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 2);
@@ -993,6 +1098,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为uint数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override uint GetUInt(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
@@ -1002,6 +1113,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为ulong数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override ulong GetULong(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
@@ -1011,6 +1128,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为float数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override float GetFloat(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
@@ -1020,6 +1143,12 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 将byte数组中相应的位置转换为double数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的数字</returns>
public override double GetDouble(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
@@ -1029,6 +1158,11 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 反转一个byte数组
/// </summary>
/// <param name="data">待反转的数组</param>
/// <returns>反转后的数组</returns>
private byte[] Reverse(byte[] data)
{
Array.Reverse(data);
@@ -1036,23 +1170,48 @@ namespace Modbus.Net
}
}
/// <summary>
/// 值与字节数组之间转换的辅助类(大端-大端位格式这是一个Singleton类
/// </summary>
public class BigEndianMsbValueHelper : BigEndianValueHelper
{
private static BigEndianValueHelper _bigEndianInstance;
/// <summary>
/// 构造函数
/// </summary>
protected BigEndianMsbValueHelper()
{
}
/// <summary>
/// 覆写的实例获取方法
/// </summary>
protected override ValueHelper _Instance => _bigEndianInstance;
/// <summary>
/// 是否为小端
/// </summary>
protected new bool LittleEndian => false;
/// <summary>
/// 是否为小端位
/// </summary>
protected new bool LittleEndianBit => false;
/// <summary>
/// 覆盖的实例获取方法
/// </summary>
public new static BigEndianValueHelper Instance
=> _bigEndianInstance ?? (_bigEndianInstance = new BigEndianMsbValueHelper());
/// <summary>
/// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。
/// </summary>
/// <param name="number">byte数字</param>
/// <param name="pos">bit数组中的对应位置</param>
/// <param name="subPos">小数位</param>
/// <returns>对应位置的bit元素</returns>
public override bool GetBit(byte[] number, ref int pos, ref int subPos)
{
if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();
@@ -1068,6 +1227,12 @@ namespace Modbus.Net
return bit;
}
/// <summary>
/// 将byte数组中相应的位置转换为8个bit数字
/// </summary>
/// <param name="data">待转换的数组</param>
/// <param name="pos">转换数字的位置</param>
/// <returns>转换出的位数组</returns>
public override bool[] GetBits(byte[] data, ref int pos)
{
var t = base.GetBits(data, ref pos);
@@ -1075,6 +1240,13 @@ namespace Modbus.Net
return t;
}
/// <summary>
/// 设置对应数字中相应位置的bit的值
/// </summary>
/// <param name="number">byte数子</param>
/// <param name="subPos">设置位置</param>
/// <param name="setBit">设置bit大小true为1false为0</param>
/// <returns>设置是否成功</returns>
public override bool SetBit(byte[] number, int pos, int subPos, bool setBit)
{
return base.SetBit(number, pos, 7 - subPos, setBit);

View File

@@ -15,7 +15,7 @@ namespace Modbus.Net.Tests
public void GetUtility()
{
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
var utility = baseMachine.GetUtility<IUtilityTime>();
var utility = baseMachine.GetUtility<IUtilityMethodTime>();
var methods = utility.GetType().GetRuntimeMethods();
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetTimeAsync") != null, true);
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "SetTimeAsync") != null, true);
@@ -25,9 +25,9 @@ namespace Modbus.Net.Tests
public async Task InvokeUtility()
{
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
var success = await baseMachine.BaseUtility.InvokeUtilityMethod<IUtilityTime, Task<bool>>("SetTimeAsync", DateTime.Now);
var success = await baseMachine.BaseUtility.InvokeUtilityMethod<IUtilityMethodTime, Task<bool>>("SetTimeAsync", DateTime.Now);
Assert.AreEqual(success, true);
var time = await baseMachine.BaseUtility.InvokeUtilityMethod<IUtilityTime, Task<DateTime>>("GetTimeAsync");
var time = await baseMachine.BaseUtility.InvokeUtilityMethod<IUtilityMethodTime, Task<DateTime>>("GetTimeAsync");
Assert.AreEqual((time.ToUniversalTime() - DateTime.Now.ToUniversalTime()).Seconds < 10, true);
}
@@ -46,7 +46,7 @@ namespace Modbus.Net.Tests
DataType = typeof(bool)
}
}, true, 2, 0);
var success = await baseMachine.InvokeMachineMethod<IMachineData, Task<bool>>("SetDatasAsync",
var success = await baseMachine.InvokeMachineMethod<IMachineMethodData, Task<bool>>("SetDatasAsync",
MachineSetDataType.Address,
new Dictionary<string, double>
{
@@ -55,9 +55,9 @@ namespace Modbus.Net.Tests
}
});
Assert.AreEqual(success, true);
var datas = await baseMachine.InvokeMachineMethod<IMachineData, Task<Dictionary<string, ReturnUnit>>>("GetDatasAsync", MachineGetDataType.Address);
var datas = await baseMachine.InvokeMachineMethod<IMachineMethodData, Task<Dictionary<string, ReturnUnit>>>("GetDatasAsync", MachineGetDataType.Address);
Assert.AreEqual(datas["0X 1.0"].PlcValue, 1);
success = await baseMachine.InvokeMachineMethod<IMachineData, Task<bool>>("SetDatasAsync",
success = await baseMachine.InvokeMachineMethod<IMachineMethodData, Task<bool>>("SetDatasAsync",
MachineSetDataType.Address,
new Dictionary<string, double>
{