diff --git a/Modbus.Net/Modbus.Net.Modbus/Interfaces.cs b/Modbus.Net/Modbus.Net.Modbus/Interfaces.cs
new file mode 100644
index 0000000..fde2fd6
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.Modbus/Interfaces.cs
@@ -0,0 +1,219 @@
+using System.Threading.Tasks;
+
+namespace Modbus.Net.Modbus
+{
+ ///
+ /// 异常状态获取方法
+ ///
+ public interface IUtilityMethodExceptionStatus
+ {
+ ///
+ /// 获取异常状态
+ ///
+ ///
+ Task> GetExceptionStatusAsync();
+ }
+
+ ///
+ /// 诊断返回数据
+ ///
+ public class DiagnoticsData
+ {
+ ///
+ /// 子方法编号
+ ///
+ public ushort SubFunction { get; set; }
+
+ ///
+ /// 诊断数据
+ ///
+ public ushort[] Data { get; set; }
+ }
+
+ ///
+ /// 诊断获取方法
+ ///
+ public interface IUtilityMethodDiagnotics
+ {
+ ///
+ /// 获取诊断信息
+ ///
+ /// 子方法编号
+ /// 诊断数据
+ ///
+ Task> GetDiagnoticsAsync(ushort subFunction, ushort[] data);
+ }
+
+ ///
+ /// 通讯事件计数器获取数据
+ ///
+ public class CommEventCounterData
+ {
+ ///
+ /// 通讯状态
+ ///
+ public ushort Status { get; set; }
+
+ ///
+ /// 事件计数
+ ///
+ public ushort EventCount { get; set; }
+ }
+
+ ///
+ /// 通讯事件计数器获取方法
+ ///
+ public interface IUtilityMethodCommEventCounter
+ {
+ ///
+ /// 获取通讯事件计数器
+ ///
+ ///
+ Task> GetCommEventCounterAsync();
+ }
+
+ ///
+ /// 通讯事件获取数据
+ ///
+ public class CommEventLogData
+ {
+ ///
+ /// 状态
+ ///
+ public ushort Status { get; set; }
+
+ ///
+ /// 事件内容
+ ///
+ public byte[] Events { get; set; }
+ }
+
+ ///
+ /// 通讯事件获取方法
+ ///
+ public interface IUtilityMethodCommEventLog
+ {
+ ///
+ /// 获取通讯事件
+ ///
+ ///
+ Task> GetCommEventLogAsync();
+ }
+
+ ///
+ /// 获取从站号数据
+ ///
+ public class SlaveIdData
+ {
+ ///
+ /// 从站号
+ ///
+ public byte SlaveId { get; set; }
+
+ ///
+ /// 指示状态
+ ///
+ public byte IndicatorStatus { get; set; }
+
+ ///
+ /// 附加信息
+ ///
+ public byte[] AdditionalData { get; set; }
+ }
+
+ ///
+ /// 获取从站号方法
+ ///
+ public interface IUtilityMethodSlaveId
+ {
+ ///
+ /// 获取从站号
+ ///
+ ///
+ Task> GetSlaveIdAsync();
+ }
+
+ ///
+ /// 文件记录读写方法
+ ///
+ public interface IUtilityMethodFileRecord
+ {
+ ///
+ /// 读文件记录
+ ///
+ /// 读文件记录定义
+ ///
+ Task> GetFileRecordAsync(ReadFileRecordInputDef[] recordDefs);
+ ///
+ /// 写文件记录
+ ///
+ /// 写文件记录定义
+ ///
+ Task> SetFileRecordAsync(WriteFileRecordInputDef[] recordDefs);
+ }
+
+ ///
+ /// 掩码写入数据
+ ///
+ public class MaskRegisterData
+ {
+ ///
+ /// 地址索引
+ ///
+ public ushort ReferenceAddress { get; set; }
+
+ ///
+ /// 与掩码
+ ///
+ public ushort AndMask { get; set; }
+
+ ///
+ /// 或掩码
+ ///
+ public ushort OrMask { get; set; }
+ }
+
+ ///
+ /// 掩码写入方法
+ ///
+ public interface IUtilityMethodMaskRegister
+ {
+ ///
+ /// 写入掩码
+ ///
+ /// 地址索引
+ /// 与掩码
+ /// 或掩码
+ ///
+ Task> SetMaskRegister(ushort referenceAddress, ushort andMask, ushort orMask);
+ }
+
+ ///
+ /// 寄存器读写方法
+ ///
+ public interface IUtilityMethodMultipleRegister
+ {
+ ///
+ /// 读写多寄存器
+ ///
+ /// 读起始地址
+ /// 读数量
+ /// 写寄存器地址
+ /// 写数据
+ ///
+ Task> GetMultipleRegister(ushort readStartingAddress, ushort quantityToRead, ushort writeStartingAddress, ushort[] writeValues);
+ }
+
+ ///
+ /// FIFO队列读取方法
+ ///
+ public interface IUtilityMethodFIFOQueue
+ {
+ ///
+ /// 读FIFO队列
+ ///
+ /// FIFO队列地址
+ ///
+ Task> GetFIFOQueue(ushort fifoPointerAddress);
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs
index 6fee1b8..30c7bde 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs
@@ -77,22 +77,6 @@ namespace Modbus.Net.Modbus
ReadFIFOQueue = 24,
}
- ///
- /// Modbus MEI方式
- ///
- public enum ModbusMEIProtocolFunctionCode : ushort
- {
- ///
- ///
- ///
- CANopenGeneralReferenceRequestandResponsePDU = 0x2B0D,
-
- ///
- /// 读设备信息
- ///
- ReadDeviceIdentification = 0x2B0E
- }
-
///
/// 只能在串口通信中使用的Modbus方法
/// 不能在TCP和UDP通信中使用
@@ -432,6 +416,1400 @@ namespace Modbus.Net.Modbus
#endregion
+ #region 读异常信息
+
+ ///
+ /// 读异常输入
+ ///
+ public class ReadExceptionStatusModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ public ReadExceptionStatusModbusInputStruct(byte slaveAddress)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusSerialPortOnlyFunctionCode.ReadExceptionStatus;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+ }
+
+ ///
+ /// 读异常输出
+ ///
+ public class ReadExceptionStatusModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 异常信息
+ public ReadExceptionStatusModbusOutputStruct(byte slaveAddress, byte functionCode,
+ byte outputData)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ OutputData = outputData;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 异常信息
+ ///
+ public byte OutputData { get; private set; }
+ }
+
+ ///
+ /// 读异常协议
+ ///
+ public class ReadExceptionStatusModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (ReadExceptionStatusModbusInputStruct)message;
+ byte[] formattingBytes;
+
+ formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var outputData = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ return new ReadExceptionStatusModbusOutputStruct(slaveAddress, functionCode, outputData);
+ }
+ }
+
+ #endregion
+
+ #region 诊断
+
+ ///
+ /// 诊断输入
+ ///
+ public class DiagnoticsModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 诊断码
+ /// 诊断内容
+ public DiagnoticsModbusInputStruct(byte slaveAddress, ushort subFunction, ushort[] data)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusSerialPortOnlyFunctionCode.Diagnostics;
+ SubFunction = subFunction;
+ Data = data.Clone() as ushort[];
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// 诊断码
+ ///
+ public ushort SubFunction { get; }
+
+ ///
+ /// 诊断内容
+ ///
+ public ushort[] Data { get; }
+ }
+
+ ///
+ /// 诊断输出
+ ///
+ public class DiagnoticsModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 诊断码
+ /// 诊断内容
+ public DiagnoticsModbusOutputStruct(byte slaveAddress, byte functionCode,
+ ushort subFunction, ushort[] data)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ SubFunction = subFunction;
+ Data = data;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 诊断码
+ ///
+ public ushort SubFunction { get; }
+
+ ///
+ /// 诊断内容
+ ///
+ public ushort[] Data { get; }
+ }
+
+ ///
+ /// 诊断协议
+ ///
+ public class DiagnoticsModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (DiagnoticsModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode,
+ r_message.SubFunction, r_message.Data);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var subFunction = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var dataValueBytes = new byte[subFunction * 2];
+ Array.Copy(messageBytes, 3, dataValueBytes, 0, subFunction * 2);
+ var dataValue = ValueHelper.GetInstance(Endian).ByteArrayToDestinationArray(dataValueBytes, subFunction);
+ return new DiagnoticsModbusOutputStruct(slaveAddress, functionCode, subFunction, dataValue);
+ }
+ }
+
+ #endregion
+
+ #region 读事件计数
+
+ ///
+ /// 读事件计数输入
+ ///
+ public class GetCommEventCounterModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ public GetCommEventCounterModbusInputStruct(byte slaveAddress)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusSerialPortOnlyFunctionCode.GetCommEventCounter;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+ }
+
+ ///
+ /// 读事件计数输出
+ ///
+ public class GetCommEventCounterModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 状态
+ /// 事件个数
+ public GetCommEventCounterModbusOutputStruct(byte slaveAddress, byte functionCode,
+ ushort status, ushort eventCount)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ Status = status;
+ EventCount = eventCount;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 状态
+ ///
+ public ushort Status { get; }
+
+ ///
+ /// 事件个数
+ ///
+ public ushort EventCount { get; }
+ }
+
+ ///
+ /// 读事件计数协议
+ ///
+ public class GetCommEventCounterModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (GetCommEventCounterModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var status = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var eventCount = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ return new GetCommEventCounterModbusOutputStruct(slaveAddress, functionCode, status, eventCount);
+ }
+ }
+
+ #endregion
+
+ #region 读事件
+
+ ///
+ /// 读事件输入
+ ///
+ public class GetCommEventLogModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ public GetCommEventLogModbusInputStruct(byte slaveAddress)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusSerialPortOnlyFunctionCode.GetCommEventLog;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+ }
+
+ ///
+ /// 诊断输出
+ ///
+ public class GetCommEventLogModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 字节个数
+ /// 状态码
+ /// 事件个数
+ /// 消息个数
+ /// 事件信息
+ public GetCommEventLogModbusOutputStruct(byte slaveAddress, byte functionCode,
+ byte byteCount, ushort status, ushort eventCount, ushort messageCount, byte[] events)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ Status = status;
+ EventCount = eventCount;
+ MessageCount = messageCount;
+ Events = events;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 状态码
+ ///
+ public ushort Status { get; private set; }
+
+ ///
+ /// 事件个数
+ ///
+ public ushort EventCount { get; private set; }
+
+ ///
+ /// 消息个数
+ ///
+ public ushort MessageCount { get; private set; }
+
+ ///
+ /// 事件信息
+ ///
+ public byte[] Events { get; private set; }
+ }
+
+ ///
+ /// 诊断协议
+ ///
+ public class GetCommEventLogModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (GetCommEventLogModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var status = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var eventCount = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var messageCount = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var events = new byte[byteCount - 6];
+ Array.Copy(messageBytes, 9, events, 0, byteCount - 6);
+ return new GetCommEventLogModbusOutputStruct(slaveAddress, functionCode, byteCount, status, eventCount, messageCount, events);
+ }
+ }
+
+ #endregion
+
+ #region 报告从站ID
+
+ ///
+ /// 报告从站ID输入
+ ///
+ public class ReportSlaveIdModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ public ReportSlaveIdModbusInputStruct(byte slaveAddress)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusSerialPortOnlyFunctionCode.ReportSlaveID;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+ }
+
+ ///
+ /// 报告从站ID输出
+ ///
+ public class ReportSlaveIdModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 字节个数
+ /// 从站ID
+ /// 运行状态
+ /// 附加信息
+ public ReportSlaveIdModbusOutputStruct(byte slaveAddress, byte functionCode,
+ byte byteCount, byte slaveId, byte runIndicatorStatus, byte[] additionalData)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ SlaveId = slaveId;
+ RunIndicatorStatus = runIndicatorStatus;
+ AdditionalData = additionalData;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 从站ID
+ ///
+ public byte SlaveId { get; private set; }
+
+ ///
+ /// 运行状态
+ ///
+ public byte RunIndicatorStatus { get; private set; }
+
+ ///
+ /// 附加信息
+ ///
+ public byte[] AdditionalData { get; private set; }
+ }
+
+ ///
+ /// 报告从站ID协议
+ ///
+ public class ReportSlaveIdModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (ReportSlaveIdModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var slaveId = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var runIndicatorStatus = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var additionalData = new byte[byteCount - 2];
+ Array.Copy(messageBytes, 5, additionalData, 0, byteCount - 2);
+ return new ReportSlaveIdModbusOutputStruct(slaveAddress, functionCode, byteCount, slaveId, runIndicatorStatus, additionalData);
+ }
+ }
+
+ #endregion
+
+ #region 读文件记录
+
+ ///
+ /// 读文件输入数据定义
+ ///
+ public class ReadFileRecordInputDef
+ {
+ ///
+ /// 引用类型,Modbus里固定为6
+ ///
+ public byte RefrenceType { get; } = 6;
+ ///
+ /// 文件计数
+ ///
+ public ushort FileNumber { get; set; }
+ ///
+ /// 记录计数
+ ///
+ public ushort RecordNumber { get; set; }
+ ///
+ /// 记录长度
+ ///
+ public ushort RecordLength { get; set; }
+ }
+
+ ///
+ /// 读文件输出数据定义
+ ///
+ public class ReadFileRecordOutputDef
+ {
+ ///
+ /// 返回长度
+ ///
+ public byte ResponseLength { get; set; }
+ ///
+ /// 引用类型
+ ///
+ public byte RefrenceType { get; set; }
+ ///
+ /// 记录数据
+ ///
+ public ushort[] RecordData { get; set; }
+ }
+
+ ///
+ /// 读文件记录输入
+ ///
+ public class ReadFileRecordModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 读文件记录定义
+ public ReadFileRecordModbusInputStruct(byte slaveAddress, ReadFileRecordInputDef[] recordDefs)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusProtocolFunctionCode.ReadFileRecord;
+ ByteCount = (byte)(recordDefs.Count() * 7);
+ RecordDefs = recordDefs.Clone() as ReadFileRecordInputDef[];
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// 字节长度
+ ///
+ public byte ByteCount { get; }
+
+ ///
+ /// 记录定义
+ ///
+ public ReadFileRecordInputDef[] RecordDefs { get; }
+ }
+
+ ///
+ /// 读文件记录输出
+ ///
+ public class ReadFileRecordModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 字节个数
+ /// 文件记录返回结果
+ public ReadFileRecordModbusOutputStruct(byte slaveAddress, byte functionCode,
+ byte byteCount, ReadFileRecordOutputDef[] recordDefs)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ RecordDefs = recordDefs;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 输出记录
+ ///
+ public ReadFileRecordOutputDef[] RecordDefs { get; private set; }
+ }
+
+ ///
+ /// 读文件记录协议
+ ///
+ public class ReadFileRecordModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (ReadFileRecordModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode);
+
+ foreach (var def in r_message.RecordDefs)
+ {
+ formattingBytes = Format(formattingBytes, def.RefrenceType, def.FileNumber, def.RecordNumber, def.RecordLength);
+ }
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ List records = new List();
+ for (int i = 0; i < byteCount; i++)
+ {
+ ReadFileRecordOutputDef record = new ReadFileRecordOutputDef();
+ var fileResponseLength = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ record.ResponseLength = fileResponseLength;
+ i++;
+ var fileReferenceType = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ record.RefrenceType = fileReferenceType;
+ i++;
+ var recordLength = (fileResponseLength - 1) / 2;
+ ushort[] recordContent = new ushort[recordLength];
+ for (int j = 0; j < recordLength; j++)
+ {
+ recordContent[j] = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ i += 2;
+ }
+ record.RecordData = recordContent;
+ records.Add(record);
+ }
+ return new ReadFileRecordModbusOutputStruct(slaveAddress, functionCode, byteCount, records.ToArray());
+ }
+ }
+
+ #endregion
+
+ #region 写文件记录
+
+ ///
+ /// 写文件记录输入定义
+ ///
+ public class WriteFileRecordInputDef
+ {
+ ///
+ /// 引用类型,Modbus固定为6
+ ///
+ public byte RefrenceType { get; } = 6;
+ ///
+ /// 文件计数
+ ///
+ public ushort FileNumber { get; set; }
+ ///
+ /// 记录计数
+ ///
+ public ushort RecordNumber { get; set; }
+ ///
+ /// 记录长度
+ ///
+ public ushort RecordLength => RecordData != null ? (ushort)RecordData.Length : (ushort)0;
+ ///
+ /// 记录数据
+ ///
+ public ushort[] RecordData { get; set; }
+ }
+
+ ///
+ /// 写文件记录输出定义
+ ///
+ public class WriteFileRecordOutputDef
+ {
+ ///
+ /// 引用类型
+ ///
+ public byte RefrenceType { get; set; }
+ ///
+ /// 文件计数
+ ///
+ public ushort FileNumber { get; set; }
+ ///
+ /// 记录计数
+ ///
+ public ushort RecordNumber { get; set; }
+ ///
+ /// 记录长度
+ ///
+ public ushort RecordLength { get; set; }
+ ///
+ /// 记录数据
+ ///
+ public ushort[] RecordData { get; set; }
+ }
+
+ ///
+ /// 写文件记录输入
+ ///
+ public class WriteFileRecordModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 写文件记录内容
+ public WriteFileRecordModbusInputStruct(byte slaveAddress, WriteFileRecordInputDef[] writeRecords)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusProtocolFunctionCode.WriteFileRecord;
+ byte count = 0;
+ foreach(var writeRecord in writeRecords)
+ {
+ count += (byte)(writeRecord.RecordData.Length * 2 + 7);
+ }
+ ByteCount = count;
+ WriteRecords = writeRecords.Clone() as WriteFileRecordInputDef[];
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 写记录数据
+ ///
+ public WriteFileRecordInputDef[] WriteRecords { get; private set; }
+ }
+
+ ///
+ /// 写文件记录输出
+ ///
+ public class WriteFileRecordModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 字节个数
+ /// 写文件记录返回
+ public WriteFileRecordModbusOutputStruct(byte slaveAddress, byte functionCode,
+ byte byteCount, WriteFileRecordOutputDef[] writeRecords)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ WriteRecords = writeRecords;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 写记录数据
+ ///
+ public WriteFileRecordOutputDef[] WriteRecords { get; private set; }
+ }
+
+ ///
+ /// 写文件记录协议
+ ///
+ public class WriteFileRecordModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (WriteFileRecordModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.ByteCount);
+
+ foreach (var record in r_message.WriteRecords)
+ {
+ formattingBytes = Format(formattingBytes, record.RefrenceType, record.FileNumber, record.RecordNumber, record.RecordLength, record.RecordData);
+ }
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ List records = new List();
+ for (int i = 0; i < byteCount; i++)
+ {
+ WriteFileRecordOutputDef record = new WriteFileRecordOutputDef();
+ var fileReferenceType = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ record.RefrenceType = fileReferenceType;
+ i++;
+ var fileNumber = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ record.FileNumber = fileNumber;
+ i += 2;
+ var fileRecordNumber = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ record.RecordNumber = fileRecordNumber;
+ i += 2;
+ var fileRecordLength = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ record.RecordLength = fileRecordLength;
+ i += 2;
+ ushort[] recordContent = new ushort[fileRecordLength];
+ for (int j = 0; j < fileRecordLength; j++)
+ {
+ recordContent[j] = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ i += 2;
+ }
+ record.RecordData = recordContent;
+ records.Add(record);
+ }
+ return new WriteFileRecordModbusOutputStruct(slaveAddress, functionCode, byteCount, records.ToArray());
+ }
+ }
+
+ #endregion
+
+ #region 写掩码
+
+ ///
+ /// 写文件记录输入
+ ///
+ public class MaskWriteRegisterModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 地址索引
+ /// 与掩码
+ /// 或掩码
+ public MaskWriteRegisterModbusInputStruct(byte slaveAddress, ushort referenceAddress, ushort andMask, ushort orMask)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusProtocolFunctionCode.MaskWriteRegister;
+ ReferenceAddress = referenceAddress;
+ AndMask = andMask;
+ OrMask = orMask;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// 地址索引
+ ///
+ public ushort ReferenceAddress { get; }
+
+ ///
+ /// 与掩码
+ ///
+ public ushort AndMask { get; }
+
+ ///
+ /// 或掩码
+ ///
+ public ushort OrMask { get; }
+ }
+
+ ///
+ /// 写文件记录输出
+ ///
+ public class MaskWriteRegisterModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 地址索引
+ /// 与掩码
+ /// 或掩码
+ public MaskWriteRegisterModbusOutputStruct(byte slaveAddress, byte functionCode,
+ ushort referenceAddress, ushort andMask, ushort orMask)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ReferenceAddress = referenceAddress;
+ AndMask = andMask;
+ OrMask = orMask;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 地址索引
+ ///
+ public ushort ReferenceAddress { get; }
+
+ ///
+ /// 与掩码
+ ///
+ public ushort AndMask { get; }
+
+ ///
+ /// 或掩码
+ ///
+ public ushort OrMask { get; }
+ }
+
+ ///
+ /// 写文件记录协议
+ ///
+ public class MaskWriteRegisterModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (MaskWriteRegisterModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.ReferenceAddress, r_message.AndMask, r_message.OrMask);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var referenceAddress = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var andMask = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var orMask = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ return new MaskWriteRegisterModbusOutputStruct(slaveAddress, functionCode, referenceAddress, andMask, orMask);
+ }
+ }
+
+ #endregion
+
+ #region 读写多个输入寄存器
+
+ ///
+ /// 读写多个输入寄存器输入
+ ///
+ public class ReadWriteMultipleRegistersModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 读起始地址
+ /// 读个数
+ /// 写起始地址
+ /// 写内容
+ public ReadWriteMultipleRegistersModbusInputStruct(byte slaveAddress, ushort readStartingAddress, ushort quantityToRead, ushort writeStartingAddress, ushort[] writeValues)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusProtocolFunctionCode.ReadWriteMultipleRegister;
+ ReadStartingAddress = readStartingAddress;
+ QuantityToRead = quantityToRead;
+ WriteStartingAddress = writeStartingAddress;
+ QuantityToWrite = (ushort)writeValues.Count();
+ WriteByteCount = (ushort)(QuantityToWrite * 2);
+ WriteValues = writeValues.Clone() as ushort[];
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// 读起始地址
+ ///
+ public ushort ReadStartingAddress { get; }
+
+ ///
+ /// 读个数
+ ///
+ public ushort QuantityToRead { get; }
+
+ ///
+ /// 写起始地址
+ ///
+ public ushort WriteStartingAddress { get; }
+
+ ///
+ /// 写个数
+ ///
+ public ushort QuantityToWrite { get; }
+
+ ///
+ /// 写字节个数
+ ///
+ public ushort WriteByteCount { get; }
+
+ ///
+ /// 写数据
+ ///
+ public ushort[] WriteValues { get; }
+ }
+
+ ///
+ /// 读写多个输入寄存器输出
+ ///
+ public class ReadWriteMultipleRegistersModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 获取的字节数
+ /// 读取的寄存器内容
+ public ReadWriteMultipleRegistersModbusOutputStruct(byte slaveAddress, byte functionCode, byte byteCount, ushort[] readRegisterValues)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ ReadRegisterValues = readRegisterValues;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public byte ByteCount { get; private set; }
+
+ ///
+ /// 读数据内容
+ ///
+ public ushort[] ReadRegisterValues { get; private set; }
+ }
+
+ ///
+ /// 读写多个输入寄存器协议
+ ///
+ public class ReadWriteMultipleRegistersModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (ReadWriteMultipleRegistersModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.ReadStartingAddress,
+ r_message.QuantityToRead, r_message.WriteStartingAddress, r_message.QuantityToWrite,
+ r_message.WriteByteCount, r_message.WriteValues);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ ushort[] readValues= new ushort[byteCount / 2];
+ for (int i = 0; i< byteCount / 2; i++)
+ {
+ readValues[i] = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ }
+ return new ReadWriteMultipleRegistersModbusOutputStruct(slaveAddress, functionCode, byteCount, readValues);
+ }
+ }
+
+ #endregion
+
+ #region 读FIFO队列
+
+ ///
+ /// 读写多个输入寄存器输入
+ ///
+ public class ReadFIFOQueueModbusInputStruct : IInputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// FIFO队列地址索引
+ public ReadFIFOQueueModbusInputStruct(byte slaveAddress, ushort fifoPointerAddress)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = (byte)ModbusProtocolFunctionCode.ReadFIFOQueue;
+ FIFOPointerAddress = fifoPointerAddress;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; }
+
+ ///
+ /// FIFO地址
+ ///
+ public ushort FIFOPointerAddress { get; }
+ }
+
+ ///
+ /// 读写多个输入寄存器输出
+ ///
+ public class ReadFIFOQueueModbusOutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 从站号
+ /// 功能码
+ /// 获取的字节数
+ /// FIFO个数
+ /// FIFO值
+ public ReadFIFOQueueModbusOutputStruct(byte slaveAddress, byte functionCode, ushort byteCount, ushort fifoCount, ushort[] fifoValueRegister)
+ {
+ SlaveAddress = slaveAddress;
+ FunctionCode = functionCode;
+ ByteCount = byteCount;
+ FIFOCount = fifoCount;
+ FIFOValueRegister = fifoValueRegister;
+ }
+
+ ///
+ /// 从站号
+ ///
+ public byte SlaveAddress { get; private set; }
+
+ ///
+ /// 功能码
+ ///
+ public byte FunctionCode { get; private set; }
+
+ ///
+ /// 字节个数
+ ///
+ public ushort ByteCount { get; private set; }
+
+ ///
+ /// FIFO个数
+ ///
+ public ushort FIFOCount { get; private set; }
+
+ ///
+ /// FIFO内容
+ ///
+ public ushort[] FIFOValueRegister { get; private set; }
+ }
+
+ ///
+ /// 读写多个输入寄存器协议
+ ///
+ public class ReadFIFOQueueModbusProtocol : ProtocolUnit
+ {
+ ///
+ /// 格式化
+ ///
+ /// 写寄存器参数
+ /// 写寄存器协议核心
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (ReadFIFOQueueModbusInputStruct)message;
+
+ var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.FIFOPointerAddress);
+
+ return formattingBytes;
+ }
+
+ ///
+ /// 反格式化
+ ///
+ /// 设备返回的信息
+ /// 当前反格式化的位置
+ /// 反格式化的信息
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
+ {
+ var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var functionCode = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag);
+ var byteCount = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ var fifoCount = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ ushort[] readValues = new ushort[fifoCount];
+ for (int i = 0; i < fifoCount; i++)
+ {
+ readValues[i] = ValueHelper.GetInstance(Endian).GetUShort(messageBytes, ref flag);
+ }
+ return new ReadFIFOQueueModbusOutputStruct(slaveAddress, functionCode, byteCount, fifoCount, readValues);
+ }
+ }
+
+ #endregion
+
///
/// Modbus协议错误表
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs
index d1e5365..a19f62a 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs
@@ -53,7 +53,16 @@ namespace Modbus.Net.Modbus
///
/// Modbus基础Api入口
///
- public class ModbusUtility : BaseUtility, PipeUnit>
+ public class ModbusUtility : BaseUtility, PipeUnit>,
+ IUtilityMethodExceptionStatus,
+ IUtilityMethodDiagnotics,
+ IUtilityMethodCommEventCounter,
+ IUtilityMethodCommEventLog,
+ IUtilityMethodSlaveId,
+ IUtilityMethodFileRecord,
+ IUtilityMethodMaskRegister,
+ IUtilityMethodMultipleRegister,
+ IUtilityMethodFIFOQueue
{
private static readonly ILogger logger = LogProvider.CreateLogger();
@@ -242,12 +251,7 @@ namespace Modbus.Net.Modbus
ModbusType = (ModbusType)connectionType;
}
- ///
- /// 读数据
- ///
- /// 起始地址
- /// 获取字节个数
- /// 获取的结果
+ ///
public override async Task> GetDatasAsync(string startAddress, int getByteCount)
{
try
@@ -278,12 +282,7 @@ namespace Modbus.Net.Modbus
}
}
- ///
- /// 写数据
- ///
- /// 起始地址
- /// 需要设置的数据
- /// 设置是否成功
+ ///
public override async Task> SetDatasAsync(string startAddress, object[] setContents)
{
try
@@ -313,5 +312,305 @@ namespace Modbus.Net.Modbus
};
}
}
+
+ ///
+ public async Task> GetExceptionStatusAsync()
+ {
+ try
+ {
+ var inputStruct = new ReadExceptionStatusModbusInputStruct(SlaveAddress);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(ReadExceptionStatusModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = outputStruct.OutputData,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = 0,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetDiagnoticsAsync(ushort subFunction, ushort[] data)
+ {
+ try
+ {
+ var inputStruct = new DiagnoticsModbusInputStruct(SlaveAddress, subFunction, data);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(DiagnoticsModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = new DiagnoticsData() { SubFunction = outputStruct.SubFunction, Data = outputStruct.Data },
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetCommEventCounterAsync()
+ {
+ try
+ {
+ var inputStruct = new GetCommEventCounterModbusInputStruct(SlaveAddress);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(GetCommEventCounterModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = new CommEventCounterData() { EventCount = outputStruct.EventCount, Status = outputStruct.Status },
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetCommEventLogAsync()
+ {
+ try
+ {
+ var inputStruct = new GetCommEventLogModbusInputStruct(SlaveAddress);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(GetCommEventLogModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = new CommEventLogData() { Status = outputStruct.Status, Events = outputStruct.Events},
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetSlaveIdAsync()
+ {
+ try
+ {
+ var inputStruct = new ReportSlaveIdModbusInputStruct(SlaveAddress);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(ReportSlaveIdModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = new SlaveIdData() { SlaveId = outputStruct.SlaveId, IndicatorStatus = outputStruct.RunIndicatorStatus, AdditionalData = outputStruct.AdditionalData},
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetFileRecordAsync(ReadFileRecordInputDef[] recordDefs)
+ {
+ try
+ {
+ var inputStruct = new ReadFileRecordModbusInputStruct(SlaveAddress, recordDefs);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(ReadFileRecordModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = outputStruct.RecordDefs,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> SetFileRecordAsync(WriteFileRecordInputDef[] recordDefs)
+ {
+ try
+ {
+ var inputStruct = new WriteFileRecordModbusInputStruct(SlaveAddress, recordDefs);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(WriteFileRecordModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = outputStruct.WriteRecords,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> SetMaskRegister(ushort referenceAddress, ushort andMask, ushort orMask)
+ {
+ try
+ {
+ var inputStruct = new MaskWriteRegisterModbusInputStruct(SlaveAddress, referenceAddress, andMask, orMask);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(MaskWriteRegisterModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = new MaskRegisterData() { ReferenceAddress = outputStruct.ReferenceAddress, AndMask = outputStruct.AndMask, OrMask = outputStruct.OrMask},
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetMultipleRegister(ushort readStartingAddress, ushort quantityToRead, ushort writeStartingAddress, ushort[] writeValues)
+ {
+ try
+ {
+ var inputStruct = new ReadWriteMultipleRegistersModbusInputStruct(SlaveAddress, readStartingAddress, quantityToRead, writeStartingAddress, writeValues);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(ReadWriteMultipleRegistersModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = outputStruct.ReadRegisterValues,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+
+ ///
+ public async Task> GetFIFOQueue(ushort fifoPointerAddress)
+ {
+ try
+ {
+ var inputStruct = new ReadFIFOQueueModbusInputStruct(SlaveAddress, fifoPointerAddress);
+ var outputStruct = await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(ReadFIFOQueueModbusProtocol)],
+ inputStruct);
+ return new ReturnStruct()
+ {
+ Datas = outputStruct.FIFOValueRegister,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = null
+ };
+ }
+ catch (ModbusProtocolErrorException e)
+ {
+ logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = null,
+ IsSuccess = false,
+ ErrorCode = e.ErrorMessageNumber,
+ ErrorMsg = e.Message
+ };
+ }
+ }
}
}
\ No newline at end of file