Implement all Modbus function except 43 (Not tested)

This commit is contained in:
luosheng
2023-05-06 13:49:09 +08:00
parent 8bb04dade9
commit 4298dc7a50
3 changed files with 1925 additions and 29 deletions

View File

@@ -0,0 +1,219 @@
using System.Threading.Tasks;
namespace Modbus.Net.Modbus
{
/// <summary>
/// 异常状态获取方法
/// </summary>
public interface IUtilityMethodExceptionStatus
{
/// <summary>
/// 获取异常状态
/// </summary>
/// <returns></returns>
Task<ReturnStruct<byte>> GetExceptionStatusAsync();
}
/// <summary>
/// 诊断返回数据
/// </summary>
public class DiagnoticsData
{
/// <summary>
/// 子方法编号
/// </summary>
public ushort SubFunction { get; set; }
/// <summary>
/// 诊断数据
/// </summary>
public ushort[] Data { get; set; }
}
/// <summary>
/// 诊断获取方法
/// </summary>
public interface IUtilityMethodDiagnotics
{
/// <summary>
/// 获取诊断信息
/// </summary>
/// <param name="subFunction">子方法编号</param>
/// <param name="data">诊断数据</param>
/// <returns></returns>
Task<ReturnStruct<DiagnoticsData>> GetDiagnoticsAsync(ushort subFunction, ushort[] data);
}
/// <summary>
/// 通讯事件计数器获取数据
/// </summary>
public class CommEventCounterData
{
/// <summary>
/// 通讯状态
/// </summary>
public ushort Status { get; set; }
/// <summary>
/// 事件计数
/// </summary>
public ushort EventCount { get; set; }
}
/// <summary>
/// 通讯事件计数器获取方法
/// </summary>
public interface IUtilityMethodCommEventCounter
{
/// <summary>
/// 获取通讯事件计数器
/// </summary>
/// <returns></returns>
Task<ReturnStruct<CommEventCounterData>> GetCommEventCounterAsync();
}
/// <summary>
/// 通讯事件获取数据
/// </summary>
public class CommEventLogData
{
/// <summary>
/// 状态
/// </summary>
public ushort Status { get; set; }
/// <summary>
/// 事件内容
/// </summary>
public byte[] Events { get; set; }
}
/// <summary>
/// 通讯事件获取方法
/// </summary>
public interface IUtilityMethodCommEventLog
{
/// <summary>
/// 获取通讯事件
/// </summary>
/// <returns></returns>
Task<ReturnStruct<CommEventLogData>> GetCommEventLogAsync();
}
/// <summary>
/// 获取从站号数据
/// </summary>
public class SlaveIdData
{
/// <summary>
/// 从站号
/// </summary>
public byte SlaveId { get; set; }
/// <summary>
/// 指示状态
/// </summary>
public byte IndicatorStatus { get; set; }
/// <summary>
/// 附加信息
/// </summary>
public byte[] AdditionalData { get; set; }
}
/// <summary>
/// 获取从站号方法
/// </summary>
public interface IUtilityMethodSlaveId
{
/// <summary>
/// 获取从站号
/// </summary>
/// <returns></returns>
Task<ReturnStruct<SlaveIdData>> GetSlaveIdAsync();
}
/// <summary>
/// 文件记录读写方法
/// </summary>
public interface IUtilityMethodFileRecord
{
/// <summary>
/// 读文件记录
/// </summary>
/// <param name="recordDefs">读文件记录定义</param>
/// <returns></returns>
Task<ReturnStruct<ReadFileRecordOutputDef[]>> GetFileRecordAsync(ReadFileRecordInputDef[] recordDefs);
/// <summary>
/// 写文件记录
/// </summary>
/// <param name="recordDefs">写文件记录定义</param>
/// <returns></returns>
Task<ReturnStruct<WriteFileRecordOutputDef[]>> SetFileRecordAsync(WriteFileRecordInputDef[] recordDefs);
}
/// <summary>
/// 掩码写入数据
/// </summary>
public class MaskRegisterData
{
/// <summary>
/// 地址索引
/// </summary>
public ushort ReferenceAddress { get; set; }
/// <summary>
/// 与掩码
/// </summary>
public ushort AndMask { get; set; }
/// <summary>
/// 或掩码
/// </summary>
public ushort OrMask { get; set; }
}
/// <summary>
/// 掩码写入方法
/// </summary>
public interface IUtilityMethodMaskRegister
{
/// <summary>
/// 写入掩码
/// </summary>
/// <param name="referenceAddress">地址索引</param>
/// <param name="andMask">与掩码</param>
/// <param name="orMask">或掩码</param>
/// <returns></returns>
Task<ReturnStruct<MaskRegisterData>> SetMaskRegister(ushort referenceAddress, ushort andMask, ushort orMask);
}
/// <summary>
/// 寄存器读写方法
/// </summary>
public interface IUtilityMethodMultipleRegister
{
/// <summary>
/// 读写多寄存器
/// </summary>
/// <param name="readStartingAddress">读起始地址</param>
/// <param name="quantityToRead">读数量</param>
/// <param name="writeStartingAddress">写寄存器地址</param>
/// <param name="writeValues">写数据</param>
/// <returns></returns>
Task<ReturnStruct<ushort[]>> GetMultipleRegister(ushort readStartingAddress, ushort quantityToRead, ushort writeStartingAddress, ushort[] writeValues);
}
/// <summary>
/// FIFO队列读取方法
/// </summary>
public interface IUtilityMethodFIFOQueue
{
/// <summary>
/// 读FIFO队列
/// </summary>
/// <param name="fifoPointerAddress">FIFO队列地址</param>
/// <returns></returns>
Task<ReturnStruct<ushort[]>> GetFIFOQueue(ushort fifoPointerAddress);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,16 @@ namespace Modbus.Net.Modbus
/// <summary>
/// Modbus基础Api入口
/// </summary>
public class ModbusUtility : BaseUtility<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>
public class ModbusUtility : BaseUtility<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>,
IUtilityMethodExceptionStatus,
IUtilityMethodDiagnotics,
IUtilityMethodCommEventCounter,
IUtilityMethodCommEventLog,
IUtilityMethodSlaveId,
IUtilityMethodFileRecord,
IUtilityMethodMaskRegister,
IUtilityMethodMultipleRegister,
IUtilityMethodFIFOQueue
{
private static readonly ILogger<ModbusUtility> logger = LogProvider.CreateLogger<ModbusUtility>();
@@ -242,12 +251,7 @@ namespace Modbus.Net.Modbus
ModbusType = (ModbusType)connectionType;
}
/// <summary>
/// 读数据
/// </summary>
/// <param name="startAddress">起始地址</param>
/// <param name="getByteCount">获取字节个数</param>
/// <returns>获取的结果</returns>
/// <inheritdoc />
public override async Task<ReturnStruct<byte[]>> GetDatasAsync(string startAddress, int getByteCount)
{
try
@@ -278,12 +282,7 @@ namespace Modbus.Net.Modbus
}
}
/// <summary>
/// 写数据
/// </summary>
/// <param name="startAddress">起始地址</param>
/// <param name="setContents">需要设置的数据</param>
/// <returns>设置是否成功</returns>
/// <inheritdoc />
public override async Task<ReturnStruct<bool>> SetDatasAsync(string startAddress, object[] setContents)
{
try
@@ -313,5 +312,305 @@ namespace Modbus.Net.Modbus
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<byte>> GetExceptionStatusAsync()
{
try
{
var inputStruct = new ReadExceptionStatusModbusInputStruct(SlaveAddress);
var outputStruct = await
Wrapper.SendReceiveAsync<ReadExceptionStatusModbusOutputStruct>(Wrapper[typeof(ReadExceptionStatusModbusProtocol)],
inputStruct);
return new ReturnStruct<byte>()
{
Datas = outputStruct.OutputData,
IsSuccess = true,
ErrorCode = 0,
ErrorMsg = null
};
}
catch (ModbusProtocolErrorException e)
{
logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
return new ReturnStruct<byte>
{
Datas = 0,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<DiagnoticsData>> GetDiagnoticsAsync(ushort subFunction, ushort[] data)
{
try
{
var inputStruct = new DiagnoticsModbusInputStruct(SlaveAddress, subFunction, data);
var outputStruct = await
Wrapper.SendReceiveAsync<DiagnoticsModbusOutputStruct>(Wrapper[typeof(DiagnoticsModbusProtocol)],
inputStruct);
return new ReturnStruct<DiagnoticsData>()
{
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<DiagnoticsData>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<CommEventCounterData>> GetCommEventCounterAsync()
{
try
{
var inputStruct = new GetCommEventCounterModbusInputStruct(SlaveAddress);
var outputStruct = await
Wrapper.SendReceiveAsync<GetCommEventCounterModbusOutputStruct>(Wrapper[typeof(GetCommEventCounterModbusProtocol)],
inputStruct);
return new ReturnStruct<CommEventCounterData>()
{
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<CommEventCounterData>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<CommEventLogData>> GetCommEventLogAsync()
{
try
{
var inputStruct = new GetCommEventLogModbusInputStruct(SlaveAddress);
var outputStruct = await
Wrapper.SendReceiveAsync<GetCommEventLogModbusOutputStruct>(Wrapper[typeof(GetCommEventLogModbusProtocol)],
inputStruct);
return new ReturnStruct<CommEventLogData>()
{
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<CommEventLogData>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<SlaveIdData>> GetSlaveIdAsync()
{
try
{
var inputStruct = new ReportSlaveIdModbusInputStruct(SlaveAddress);
var outputStruct = await
Wrapper.SendReceiveAsync<ReportSlaveIdModbusOutputStruct>(Wrapper[typeof(ReportSlaveIdModbusProtocol)],
inputStruct);
return new ReturnStruct<SlaveIdData>()
{
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<SlaveIdData>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<ReadFileRecordOutputDef[]>> GetFileRecordAsync(ReadFileRecordInputDef[] recordDefs)
{
try
{
var inputStruct = new ReadFileRecordModbusInputStruct(SlaveAddress, recordDefs);
var outputStruct = await
Wrapper.SendReceiveAsync<ReadFileRecordModbusOutputStruct>(Wrapper[typeof(ReadFileRecordModbusProtocol)],
inputStruct);
return new ReturnStruct<ReadFileRecordOutputDef[]>()
{
Datas = outputStruct.RecordDefs,
IsSuccess = true,
ErrorCode = 0,
ErrorMsg = null
};
}
catch (ModbusProtocolErrorException e)
{
logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
return new ReturnStruct<ReadFileRecordOutputDef[]>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<WriteFileRecordOutputDef[]>> SetFileRecordAsync(WriteFileRecordInputDef[] recordDefs)
{
try
{
var inputStruct = new WriteFileRecordModbusInputStruct(SlaveAddress, recordDefs);
var outputStruct = await
Wrapper.SendReceiveAsync<WriteFileRecordModbusOutputStruct>(Wrapper[typeof(WriteFileRecordModbusProtocol)],
inputStruct);
return new ReturnStruct<WriteFileRecordOutputDef[]>()
{
Datas = outputStruct.WriteRecords,
IsSuccess = true,
ErrorCode = 0,
ErrorMsg = null
};
}
catch (ModbusProtocolErrorException e)
{
logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
return new ReturnStruct<WriteFileRecordOutputDef[]>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<MaskRegisterData>> SetMaskRegister(ushort referenceAddress, ushort andMask, ushort orMask)
{
try
{
var inputStruct = new MaskWriteRegisterModbusInputStruct(SlaveAddress, referenceAddress, andMask, orMask);
var outputStruct = await
Wrapper.SendReceiveAsync<MaskWriteRegisterModbusOutputStruct>(Wrapper[typeof(MaskWriteRegisterModbusProtocol)],
inputStruct);
return new ReturnStruct<MaskRegisterData>()
{
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<MaskRegisterData>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<ushort[]>> GetMultipleRegister(ushort readStartingAddress, ushort quantityToRead, ushort writeStartingAddress, ushort[] writeValues)
{
try
{
var inputStruct = new ReadWriteMultipleRegistersModbusInputStruct(SlaveAddress, readStartingAddress, quantityToRead, writeStartingAddress, writeValues);
var outputStruct = await
Wrapper.SendReceiveAsync<ReadWriteMultipleRegistersModbusOutputStruct>(Wrapper[typeof(ReadWriteMultipleRegistersModbusProtocol)],
inputStruct);
return new ReturnStruct<ushort[]>()
{
Datas = outputStruct.ReadRegisterValues,
IsSuccess = true,
ErrorCode = 0,
ErrorMsg = null
};
}
catch (ModbusProtocolErrorException e)
{
logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
return new ReturnStruct<ushort[]>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
/// <inheritdoc />
public async Task<ReturnStruct<ushort[]>> GetFIFOQueue(ushort fifoPointerAddress)
{
try
{
var inputStruct = new ReadFIFOQueueModbusInputStruct(SlaveAddress, fifoPointerAddress);
var outputStruct = await
Wrapper.SendReceiveAsync<ReadFIFOQueueModbusOutputStruct>(Wrapper[typeof(ReadFIFOQueueModbusProtocol)],
inputStruct);
return new ReturnStruct<ushort[]>()
{
Datas = outputStruct.FIFOValueRegister,
IsSuccess = true,
ErrorCode = 0,
ErrorMsg = null
};
}
catch (ModbusProtocolErrorException e)
{
logger.LogError(e, $"ModbusUtility -> SetDatas: {ConnectionString} error: {e.Message}");
return new ReturnStruct<ushort[]>
{
Datas = null,
IsSuccess = false,
ErrorCode = e.ErrorMessageNumber,
ErrorMsg = e.Message
};
}
}
}
}