diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs index ffe8813..1de8840 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs @@ -5,11 +5,24 @@ /// public class AddressFormaterNA200H : AddressFormater { + /// + /// 格式化地址 + /// + /// 地址区域 + /// 地址 + /// 格式化的地址字符串 public override string FormatAddress(string area, int address) { return area + " " + address; } + /// + /// 格式化地址 + /// + /// 地址区域 + /// 地址 + /// 比特位地址 + /// 格式化的地址字符串 public override string FormatAddress(string area, int address, int subAddress) { return area + " " + address + "." + subAddress; @@ -21,11 +34,24 @@ /// public class AddressFormaterModbus : AddressFormater { + /// + /// 格式化地址 + /// + /// 地址区域 + /// 地址 + /// 格式化的地址字符串 public override string FormatAddress(string area, int address) { return area + " " + address; } + /// + /// 格式化地址 + /// + /// 地址区域 + /// 地址 + /// 比特位地址 + /// 格式化的地址字符串 public override string FormatAddress(string area, int address, int subAddress) { return area + " " + address + "." + subAddress; diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs index 3edcd80..b4b6ec4 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs @@ -23,6 +23,9 @@ namespace Modbus.Net.Modbus /// protected Dictionary WriteFunctionCodeDictionary; + /// + /// 构造器 + /// public AddressTranslatorNA200H() { TransDictionary = new Dictionary @@ -154,6 +157,12 @@ namespace Modbus.Net.Modbus }; } + /// + /// 地址转换 + /// + /// 格式化的地址 + /// 是否为读取,是为读取,否为写入 + /// 翻译后的地址 public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); @@ -188,6 +197,11 @@ namespace Modbus.Net.Modbus }; } + /// + /// 获取区域中的单个地址占用的字节长度 + /// + /// 区域名称 + /// 字节长度 public override double GetAreaByteLength(string area) { return ReadFunctionCodeDictionary[area].AreaWidth; @@ -209,6 +223,9 @@ namespace Modbus.Net.Modbus /// protected Dictionary WriteFunctionCodeDictionary; + /// + /// 构造器 + /// public AddressTranslatorModbus() { ReadFunctionCodeDictionary = new Dictionary @@ -259,6 +276,12 @@ namespace Modbus.Net.Modbus }; } + /// + /// 地址转换 + /// + /// 格式化的地址 + /// 是否为读取,是为读取,否为写入 + /// 翻译后的地址 public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); @@ -293,6 +316,11 @@ namespace Modbus.Net.Modbus }; } + /// + /// 获取区域中的单个地址占用的字节长度 + /// + /// 区域名称 + /// 字节长度 public override double GetAreaByteLength(string area) { return ReadFunctionCodeDictionary[area].AreaWidth; diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs index bf93d71..22c5b58 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs @@ -7,11 +7,24 @@ namespace Modbus.Net.Modbus /// public class ModbusAsciiProtocal : ModbusProtocal { + /// + /// 构造函数 + /// + /// 从站号 + /// 主站号 + /// 端格式 public ModbusAsciiProtocal(byte slaveAddress, byte masterAddress, Endian endian) : this(ConfigurationManager.AppSettings["COM"], slaveAddress, masterAddress, endian) { } + /// + /// 构造函数 + /// + /// 串口地址 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusAsciiProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian) { diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs index a37c55a..1b45171 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs @@ -8,13 +8,24 @@ namespace Modbus.Net.Modbus /// public class ModbusAsciiProtocalLinker : ComProtocalLinker { + /// + /// 构造函数 + /// + /// 串口地址 + /// 从站号 public ModbusAsciiProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress) { } + /// + /// 校验返回数据是否正确 + /// + /// 返回的数据 + /// 校验是否正确 public override bool? CheckRight(byte[] content) { + //ProtocalLinker不会返回null if (!base.CheckRight(content).Value) return false; //CRC校验失败 var contentString = Encoding.ASCII.GetString(content); diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs index 450a12d..85b2d81 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs @@ -9,6 +9,16 @@ namespace Modbus.Net.Modbus public class ModbusMachine : BaseMachine where TKey : IEquatable where TUnitKey : IEquatable { + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 读写的地址 + /// 是否保持连接 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusMachine(ModbusType connectionType, string connectionString, IEnumerable> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) @@ -20,6 +30,15 @@ namespace Modbus.Net.Modbus AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100); } + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 读写的地址 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusMachine(ModbusType connectionType, string connectionString, IEnumerable> getAddresses, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) @@ -33,6 +52,16 @@ namespace Modbus.Net.Modbus /// public class ModbusMachine : BaseMachine { + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 读写的地址 + /// 是否保持连接 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusMachine(ModbusType connectionType, string connectionString, IEnumerable getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) @@ -44,6 +73,15 @@ namespace Modbus.Net.Modbus AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100); } + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 读写的地址 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusMachine(ModbusType connectionType, string connectionString, IEnumerable getAddresses, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs index f261609..9f2a763 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs @@ -9,7 +9,14 @@ namespace Modbus.Net.Modbus /// internal enum ModbusProtocalVariableFunctionCode : byte { + /// + /// 读变量 + /// ReadVariable = 20, + + /// + /// 写变量 + /// WriteVariable = 21 } @@ -18,7 +25,14 @@ namespace Modbus.Net.Modbus /// public enum ModbusProtocalTimeFunctionCode : byte { + /// + /// 读时间 + /// GetSystemTime = 3, + + /// + /// 写时间 + /// SetSystemTime = 16 } @@ -27,9 +41,24 @@ namespace Modbus.Net.Modbus /// public enum ModbusProtocalReadDataFunctionCode : byte { + /// + /// 读线圈 + /// ReadCoilStatus = 1, + + /// + /// 读输入线圈 + /// ReadInputStatus = 2, + + /// + /// 读保持寄存器 + /// ReadHoldRegister = 3, + + /// + /// 读输入寄存器 + /// ReadInputRegister = 4 } @@ -38,7 +67,24 @@ namespace Modbus.Net.Modbus /// internal enum ModbusProtocalWriteDataFunctionCode : byte { + /// + /// 写单个线圈 + /// + WriteSingleCoil = 5, + + /// + /// 写单个寄存器 + /// + WriteSingleRegister = 6, + + /// + /// 写多个线圈 + /// WriteMultiCoil = 15, + + /// + /// 写多个寄存器 + /// WriteMultiRegister = 16 } @@ -47,16 +93,30 @@ namespace Modbus.Net.Modbus /// public abstract class ModbusProtocal : BaseProtocal { + /// + /// 构造函数 + /// + /// 从站地址 + /// 主站地址 + /// 端格式 protected ModbusProtocal(byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian) { } + /// + /// 连接 + /// + /// 是否连接成功 public override bool Connect() { return ProtocalLinker.Connect(); } + /// + /// 连接 + /// + /// 是否连接成功 public override async Task ConnectAsync() { return await ProtocalLinker.ConnectAsync(); @@ -65,8 +125,18 @@ namespace Modbus.Net.Modbus #region 读PLC数据 + /// + /// 读数据输入 + /// public class ReadDataModbusInputStruct : IInputStruct { + /// + /// 构造函数 + /// + /// 从站地址 + /// 开始地址 + /// 读取个数 + /// 地址翻译器 public ReadDataModbusInputStruct(byte slaveAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator) { @@ -78,17 +148,39 @@ namespace Modbus.Net.Modbus (ushort) Math.Ceiling(getCount / addressTranslator.GetAreaByteLength(translateAddress.AreaString)); } + /// + /// 从站地址 + /// public byte SlaveAddress { get; } + /// + /// 功能码 + /// public byte FunctionCode { get; } + /// + /// 开始地址 + /// public ushort StartAddress { get; } + /// + /// 获取个数 + /// public ushort GetCount { get; } } + /// + /// 读数据输出 + /// public class ReadDataModbusOutputStruct : IOutputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 功能码 + /// 数据个数 + /// 读取的数据值 public ReadDataModbusOutputStruct(byte slaveAddress, byte functionCode, int dataCount, byte[] dataValue) { @@ -98,17 +190,37 @@ namespace Modbus.Net.Modbus DataValue = dataValue.Clone() as byte[]; } + /// + /// 从站号 + /// public byte SlaveAddress { get; private set; } + /// + /// 功能码 + /// public byte FunctionCode { get; private set; } + /// + /// 数据个数 + /// public int DataCount { get; private set; } + /// + /// 数据值 + /// public byte[] DataValue { get; private set; } } + /// + /// 读数据协议 + /// public class ReadDataModbusProtocal : ProtocalUnit { + /// + /// 格式化 + /// + /// 读取参数 + /// 读取数据的协议核心 public override byte[] Format(IInputStruct message) { var r_message = (ReadDataModbusInputStruct) message; @@ -116,6 +228,12 @@ namespace Modbus.Net.Modbus r_message.StartAddress, r_message.GetCount); } + /// + /// 反格式化 + /// + /// 设备返回的信息 + /// 当前反格式化的位置 + /// 反格式化的信息 public override IOutputStruct Unformat(byte[] messageBytes, ref int pos) { var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref pos); @@ -131,8 +249,19 @@ namespace Modbus.Net.Modbus #region 写PLC数据 + /// + /// 写数据输入 + /// public class WriteDataModbusInputStruct : IInputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 开始地址 + /// 写入的数据 + /// 地址翻译器 + /// 端格式 public WriteDataModbusInputStruct(byte slaveAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator, Endian endian) { @@ -147,21 +276,49 @@ namespace Modbus.Net.Modbus WriteValue = writeByteValue; } + /// + /// 从站号 + /// public byte SlaveAddress { get; } + /// + /// 功能码 + /// public byte FunctionCode { get; } + /// + /// 开始地址 + /// public ushort StartAddress { get; } + /// + /// 写入个数 + /// public ushort WriteCount { get; } + /// + /// 写入字节个数 + /// public byte WriteByteCount { get; } + /// + /// 写入的数据 + /// public byte[] WriteValue { get; } } + /// + /// 写数据输出 + /// public class WriteDataModbusOutputStruct : IOutputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 功能码 + /// 开始地址 + /// 写入个数 public WriteDataModbusOutputStruct(byte slaveAddress, byte functionCode, ushort startAddress, ushort writeCount) { @@ -171,20 +328,37 @@ namespace Modbus.Net.Modbus WriteCount = writeCount; } + /// + /// 从站号 + /// public byte SlaveAddress { get; private set; } + /// + /// 功能码 + /// public byte FunctionCode { get; private set; } + /// + /// 开始地址 + /// public ushort StartAddress { get; private set; } + /// + /// 写入个数 + /// public ushort WriteCount { get; private set; } } /// - /// 写多个寄存器状态 + /// 写多个寄存器协议 /// public class WriteDataModbusProtocal : ProtocalUnit { + /// + /// 格式化 + /// + /// 写寄存器参数 + /// 写寄存器协议核心 public override byte[] Format(IInputStruct message) { var r_message = (WriteDataModbusInputStruct) message; @@ -194,6 +368,12 @@ namespace Modbus.Net.Modbus return formattingBytes; } + /// + /// 反格式化 + /// + /// 设备返回的信息 + /// 当前反格式化的位置 + /// 反格式化的信息 public override IOutputStruct Unformat(byte[] messageBytes, ref int flag) { var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag); @@ -209,8 +389,15 @@ namespace Modbus.Net.Modbus #region 读PLC时间 + /// + /// 读时间输入 + /// public class GetSystemTimeModbusInputStruct : IInputStruct { + /// + /// 构造函数 + /// + /// 从站号 public GetSystemTimeModbusInputStruct(byte slaveAddress) { SlaveAddress = slaveAddress; @@ -219,17 +406,45 @@ namespace Modbus.Net.Modbus GetCount = 5; } + /// + /// 从站号 + /// public byte SlaveAddress { get; } + /// + /// 功能码 + /// public byte FunctionCode { get; } + /// + /// 开始地址 + /// public ushort StartAddress { get; } + /// + /// 获取个数 + /// public ushort GetCount { get; } } + /// + /// 读时间输出 + /// public class GetSystemTimeModbusOutputStruct : IOutputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 功能码 + /// 写入个数 + /// 年 + /// 日 + /// 月 + /// 时 + /// 秒 + /// 分 + /// 毫秒 public GetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode, byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute, ushort millisecond) @@ -240,20 +455,37 @@ namespace Modbus.Net.Modbus Time = new DateTime(year, month, day, hour, minute, second, millisecond); } + /// + /// 从站号 + /// public byte SlaveAddress { get; private set; } + /// + /// 功能码 + /// public byte FunctionCode { get; private set; } + /// + /// 写入个数 + /// public byte WriteByteCount { get; private set; } + /// + /// 时间 + /// public DateTime Time { get; private set; } } /// - /// 读系统时间 + /// 读系统时间协议 /// public class GetSystemTimeModbusProtocal : ProtocalUnit { + /// + /// 格式化 + /// + /// 写系统时间参数 + /// 写系统时间的核心 public override byte[] Format(IInputStruct message) { var r_message = (GetSystemTimeModbusInputStruct) message; @@ -261,6 +493,12 @@ namespace Modbus.Net.Modbus r_message.StartAddress, r_message.GetCount); } + /// + /// 反格式化 + /// + /// 获取的信息 + /// 当前反格式化的位置 + /// 反格式化的信息 public override IOutputStruct Unformat(byte[] messageBytes, ref int flag) { var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag); @@ -282,8 +520,16 @@ namespace Modbus.Net.Modbus #region 写PLC时间 + /// + /// 写时间输入 + /// public class SetSystemTimeModbusInputStruct : IInputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 时间 public SetSystemTimeModbusInputStruct(byte slaveAddress, DateTime time) { SlaveAddress = slaveAddress; @@ -300,33 +546,79 @@ namespace Modbus.Net.Modbus Millisecond = (ushort) time.Millisecond; } + /// + /// 从站号 + /// public byte SlaveAddress { get; } + /// + /// 功能码 + /// public byte FunctionCode { get; } + /// + /// 开始地址 + /// public ushort StartAddress { get; } + /// + /// 写入个数 + /// public ushort WriteCount { get; } + /// + /// 写入字节个数 + /// public byte WriteByteCount { get; } + /// + /// 年 + /// public ushort Year { get; } + /// + /// 日 + /// public byte Day { get; } + /// + /// 月 + /// public byte Month { get; } + /// + /// 时 + /// public ushort Hour { get; } + /// + /// 秒 + /// public byte Second { get; } + /// + /// 分 + /// public byte Minute { get; } + /// + /// 毫秒 + /// public ushort Millisecond { get; } } + /// + /// 写时间输出 + /// public class SetSystemTimeModbusOutputStruct : IOutputStruct { + /// + /// 构造函数 + /// + /// 从站号 + /// 功能码 + /// 开始地址 + /// 写入个数 public SetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode, ushort startAddress, ushort writeCount) { @@ -336,20 +628,37 @@ namespace Modbus.Net.Modbus WriteCount = writeCount; } + /// + /// 从站号 + /// public byte SlaveAddress { get; private set; } + /// + /// 功能码 + /// public byte FunctionCode { get; private set; } + /// + /// 开始地址 + /// public ushort StartAddress { get; private set; } + /// + /// 写入个数 + /// public ushort WriteCount { get; private set; } } /// - /// 写系统时间 + /// 写系统时间协议 /// public class SetSystemTimeModbusProtocal : ProtocalUnit { + /// + /// 格式化 + /// + /// 写系统时间的参数 + /// 写系统时间的核心 public override byte[] Format(IInputStruct message) { var r_message = (SetSystemTimeModbusInputStruct) message; @@ -359,6 +668,12 @@ namespace Modbus.Net.Modbus r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond); } + /// + /// 反格式化 + /// + /// 获取的信息 + /// 当前反格式化的位置 + /// 反格式化的信息 public override IOutputStruct Unformat(byte[] messageBytes, ref int flag) { var slaveAddress = ValueHelper.GetInstance(Endian).GetByte(messageBytes, ref flag); @@ -388,12 +703,19 @@ namespace Modbus.Net.Modbus {501, "RTU_ILLEGAL_CRC"} }; + /// + /// Modbus错误 + /// + /// Modbus错误号 public ModbusProtocalErrorException(int messageNumber) : base(ProtocalErrorDictionary[messageNumber]) { ErrorMessageNumber = messageNumber; } + /// + /// Modbus错误号 + /// public int ErrorMessageNumber { get; private set; } } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs index ae67594..83a9cca 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs @@ -10,6 +10,11 @@ namespace Modbus.Net.Modbus /// public class ModbusTcpProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend { + /// + /// 协议扩展,协议内容发送前调用 + /// + /// 扩展前的原始协议内容 + /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { //Modbus/Tcp协议扩张,前面加6个字节,前面4个为0,后面两个为协议整体内容的长度 @@ -22,6 +27,11 @@ namespace Modbus.Net.Modbus return newFormat; } + /// + /// 协议收缩,协议内容接收后调用 + /// + /// 收缩前的完整协议内容 + /// 收缩后的协议内容 public byte[] BytesDecact(byte[] content) { //Modbus/Tcp协议收缩,抛弃前面6个字节的内容 @@ -31,8 +41,16 @@ namespace Modbus.Net.Modbus } } + /// + /// Rtu协议字节伸缩 + /// public class ModbusRtuProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend { + /// + /// 协议扩展,协议内容发送前调用 + /// + /// 扩展前的原始协议内容 + /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { var crc = new byte[2]; @@ -44,6 +62,11 @@ namespace Modbus.Net.Modbus return newFormat; } + /// + /// 协议收缩,协议内容接收后调用 + /// + /// 收缩前的完整协议内容 + /// 收缩后的协议内容 public byte[] BytesDecact(byte[] content) { //Modbus/Rtu协议收缩,抛弃后面2个字节的内容 @@ -53,8 +76,16 @@ namespace Modbus.Net.Modbus } } + /// + /// Ascii协议字节伸缩 + /// public class ModbusAsciiProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend { + /// + /// 协议扩展,协议内容发送前调用 + /// + /// 扩展前的原始协议内容 + /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { //Modbus/Ascii协议扩张,前面增加:,后面增加LRC校验和尾字符 @@ -68,6 +99,11 @@ namespace Modbus.Net.Modbus return newContent.ToArray(); } + /// + /// 协议收缩,协议内容接收后调用 + /// + /// 收缩前的完整协议内容 + /// 收缩后的协议内容 public byte[] BytesDecact(byte[] content) { //Modbus/Ascii协议收缩,抛弃头尾。 diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs index aace433..46a7b17 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs @@ -7,11 +7,24 @@ namespace Modbus.Net.Modbus /// public class ModbusRtuProtocal : ModbusProtocal { + /// + /// 构造函数 + /// + /// 从站号 + /// 主站号 + /// 端格式 public ModbusRtuProtocal(byte slaveAddress, byte masterAddress, Endian endian) : this(ConfigurationManager.AppSettings["COM"], slaveAddress, masterAddress, endian) { } + /// + /// 构造函数 + /// + /// 串口 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusRtuProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian) { diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs index 6fa4466..7c58088 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs @@ -7,13 +7,24 @@ namespace Modbus.Net.Modbus /// public class ModbusRtuProtocalLinker : ComProtocalLinker { + /// + /// 构造函数 + /// + /// 串口地址 + /// 从站号 public ModbusRtuProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress) { } + /// + /// 校验返回数据 + /// + /// 设备返回的数据 + /// 数据是否正确 public override bool? CheckRight(byte[] content) { + //ProtocalLinker的CheckRight不会返回null if (!base.CheckRight(content).Value) return false; //CRC校验失败 if (!Crc16.GetInstance().CrcEfficacy(content)) diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs index a15b339..2822c8f 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs @@ -7,17 +7,38 @@ namespace Modbus.Net.Modbus /// public class ModbusTcpProtocal : ModbusProtocal { + /// + /// 构造函数 + /// + /// 从站号 + /// 主站号 + /// 端格式 public ModbusTcpProtocal(byte slaveAddress, byte masterAddress, Endian endian) : this(ConfigurationManager.AppSettings["IP"], slaveAddress, masterAddress, endian) { } + /// + /// 构造函数 + /// + /// ip地址 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusTcpProtocal(string ip, byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian) { ProtocalLinker = new ModbusTcpProtocalLinker(ip); } + /// + /// 构造函数 + /// + /// ip地址 + /// 端口 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusTcpProtocal(string ip, int port, byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian) { diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs index f0cfe6e..18b4744 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs @@ -7,17 +7,32 @@ namespace Modbus.Net.Modbus /// public class ModbusTcpProtocalLinker : TcpProtocalLinker { + /// + /// 构造函数 + /// + /// IP地址 public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"] ?? "502")) { } + /// + /// 构造函数 + /// + /// IP地址 + /// 端口 public ModbusTcpProtocalLinker(string ip, int port) : base(ip, port) { } + /// + /// 校验返回数据 + /// + /// 设备返回的数据 + /// 数据是否正确 public override bool? CheckRight(byte[] content) { + //ProtocalLinker的CheckRight不会返回null if (!base.CheckRight(content).Value) return false; //长度校验失败 if (content[5] != content.Length - 6) diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs index 95a751f..8aba0ad 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Serilog; namespace Modbus.Net.Modbus { @@ -34,6 +35,13 @@ namespace Modbus.Net.Modbus /// private ModbusType _modbusType; + /// + /// 构造函数 + /// + /// 协议类型 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) : base(slaveAddress, masterAddress) @@ -44,6 +52,14 @@ namespace Modbus.Net.Modbus AddressTranslator = new AddressTranslatorModbus(); } + /// + /// 构造函数 + /// + /// 协议类型 + /// 连接地址 + /// 从站号 + /// 主站号 + /// 端格式 public ModbusUtility(ModbusType connectionType, string connectionString, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb) : base(slaveAddress, masterAddress) @@ -54,8 +70,14 @@ namespace Modbus.Net.Modbus AddressTranslator = new AddressTranslatorModbus(); } + /// + /// 端格式 + /// public override Endian Endian { get; } + /// + /// Ip地址 + /// protected string ConnectionStringIp { get @@ -65,6 +87,9 @@ namespace Modbus.Net.Modbus } } + /// + /// 端口 + /// protected int? ConnectionStringPort { get @@ -76,13 +101,17 @@ namespace Modbus.Net.Modbus { return connectionStringSplit.Length < 2 ? (int?) null : int.Parse(connectionStringSplit[1]); } - catch + catch (Exception e) { + Log.Error(e, $"ModbusUtility: {ConnectionString} format error"); return null; } } } + /// + /// 协议类型 + /// public ModbusType ModbusType { get { return _modbusType; } @@ -136,8 +165,9 @@ namespace Modbus.Net.Modbus Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct); return outputStruct?.Time ?? DateTime.MinValue; } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> GetTime: {ConnectionString} error"); return DateTime.MinValue; } } @@ -157,12 +187,17 @@ namespace Modbus.Net.Modbus Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct); return outputStruct?.WriteCount > 0; } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> SetTime: {ConnectionString} error"); return false; } } + /// + /// 设置协议类型 + /// + /// 协议类型 public override void SetConnectionType(int connectionType) { ModbusType = (ModbusType) connectionType; @@ -185,8 +220,9 @@ namespace Modbus.Net.Modbus inputStruct); return outputStruct?.DataValue; } - catch + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> GetDatas: {ConnectionString} error"); return null; } } @@ -208,8 +244,9 @@ namespace Modbus.Net.Modbus inputStruct); return outputStruct?.WriteCount == setContents.Length; } - catch + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> SetDatas: {ConnectionString} error"); return false; } } diff --git a/Modbus.Net/Modbus.Net.OPC/OpcConnector.cs b/Modbus.Net/Modbus.Net.OPC/OpcConnector.cs index 6c10bc7..b4281d5 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcConnector.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcConnector.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Hylasoft.Opc.Common; +using Serilog; namespace Modbus.Net.OPC { @@ -28,12 +29,12 @@ namespace Modbus.Net.OPC Client?.Dispose(); Client = null; _connect = false; - AddInfo("client disconnected successfully."); + Log.Information("opc client {ConnectionToken} disconnected success", ConnectionToken); return true; } catch (Exception ex) { - AddInfo("client disconnected exception: " + ex.Message); + Log.Error(ex, "opc client {ConnectionToken} disconnected error", ConnectionToken); _connect = false; return false; } @@ -125,7 +126,7 @@ namespace Modbus.Net.OPC } catch (Exception e) { - AddInfo("opc write exception:" + e.Message); + Log.Error(e, "opc client {ConnectionToken} write exception", ConnectionToken); return new OpcParamOut { Success = false @@ -144,7 +145,7 @@ namespace Modbus.Net.OPC } catch (Exception e) { - AddInfo("opc client exception:" + e.Message); + Log.Error(e, "opc client {ConnectionToken} read exception", ConnectionToken); return new OpcParamOut { Success = false, @@ -180,13 +181,12 @@ namespace Modbus.Net.OPC { Client.Connect(); _connect = true; - AddInfo("client connected."); + Log.Information("opc client {ConnectionToken} connect success", ConnectionToken); return true; } catch (Exception ex) { - AddInfo("client connected exception: " + ex.Message); - AddInfo("connect failed."); + Log.Error(ex, "opc client {ConnectionToken} connected failed", ConnectionToken); _connect = false; return false; } diff --git a/Modbus.Net/Modbus.Net.OPC/OpcUtility.cs b/Modbus.Net/Modbus.Net.OPC/OpcUtility.cs index 5b8f454..8da536b 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcUtility.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcUtility.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Serilog; namespace Modbus.Net.OPC { @@ -34,8 +35,9 @@ namespace Modbus.Net.OPC readRequestOpcInputStruct); return readRequestOpcOutputStruct?.GetValue; } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"OpcUtility -> GetDatas: {ConnectionString} error"); return null; } } @@ -54,6 +56,7 @@ namespace Modbus.Net.OPC } catch (Exception e) { + Log.Error(e, $"OpcUtility -> SetDatas: {ConnectionString} error"); return false; } } diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs index 923e4c1..e2ba25b 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs @@ -5,11 +5,24 @@ /// public class AddressFormaterSiemens : AddressFormater { + /// + /// 编码地址 + /// + /// 地址所在的数据区域 + /// 地址 + /// 编码后的地址 public override string FormatAddress(string area, int address) { return area + " " + address; } + /// + /// 编码地址 + /// + /// 地址所在的数据区域 + /// 地址 + /// 子地址 + /// 编码后的地址 public override string FormatAddress(string area, int address, int subAddress) { return area + " " + address + "." + subAddress; @@ -21,6 +34,12 @@ /// public class AddressFormaterSimenseStandard : AddressFormater { + /// + /// 编码地址 + /// + /// 地址所在的数据区域 + /// 地址 + /// 编码后的地址 public override string FormatAddress(string area, int address) { if (area.Length > 1 && @@ -29,6 +48,13 @@ return area.ToUpper() + address; } + /// + /// 编码地址 + /// + /// 地址所在的数据区域 + /// 地址 + /// 子地址 + /// 编码后的地址 public override string FormatAddress(string area, int address, int subAddress) { if (area.Length > 1 && diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs index b19dbb2..fd69247 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs @@ -9,8 +9,14 @@ namespace Modbus.Net.Siemens /// public class AddressTranslatorSiemens : AddressTranslator { + /// + /// 区域的翻译字典 + /// protected Dictionary AreaCodeDictionary; + /// + /// 构造函数 + /// public AddressTranslatorSiemens() { AreaCodeDictionary = new Dictionary @@ -30,6 +36,12 @@ namespace Modbus.Net.Siemens }; } + /// + /// 地址转换 + /// + /// 格式化的地址 + /// 是否为读取,是为读取,否为写入 + /// 翻译后的地址 public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); @@ -68,6 +80,11 @@ namespace Modbus.Net.Siemens }; } + /// + /// 获取区域中的单个地址占用的字节长度 + /// + /// 区域名称 + /// 字节长度 public override double GetAreaByteLength(string area) { return 1; @@ -79,8 +96,14 @@ namespace Modbus.Net.Siemens /// public class AddressTranslatorSimenseStandard : AddressTranslator { + /// + /// 区域的翻译字典 + /// protected Dictionary AreaCodeDictionary; + /// + /// 构造函数 + /// public AddressTranslatorSimenseStandard() { AreaCodeDictionary = new Dictionary @@ -100,6 +123,12 @@ namespace Modbus.Net.Siemens }; } + /// + /// 地址转换 + /// + /// 格式化的地址 + /// 是否为读取,是为读取,否为写入 + /// 翻译后的地址 public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); @@ -134,6 +163,11 @@ namespace Modbus.Net.Siemens }; } + /// + /// 获取区域中的单个地址占用的字节长度 + /// + /// 区域名称 + /// 字节长度 public override double GetAreaByteLength(string area) { return 1; diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs index f91495c..3a5fb32 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs @@ -9,6 +9,16 @@ namespace Modbus.Net.Siemens public class SiemensMachine : BaseMachine where TKey : IEquatable where TUnitKey : IEquatable { + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 设备类型 + /// 读写的地址 + /// 是否保持连接 + /// 从站号 + /// 主站号 public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, IEnumerable> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress) : base(getAddresses, keepConnect, slaveAddress, masterAddress) @@ -19,6 +29,15 @@ namespace Modbus.Net.Siemens AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100); } + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 设备类型 + /// 读写的地址 + /// 从站号 + /// 主站号 public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, IEnumerable> getAddresses, byte slaveAddress, byte masterAddress) : this(connectionType, connectionString, model, getAddresses, false, slaveAddress, masterAddress) @@ -31,6 +50,16 @@ namespace Modbus.Net.Siemens /// public class SiemensMachine : BaseMachine { + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 设备类型 + /// 读写的地址 + /// 是否保持连接 + /// 从站号 + /// 主站号 public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, IEnumerable getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress) : base(getAddresses, keepConnect, slaveAddress, masterAddress) @@ -41,6 +70,15 @@ namespace Modbus.Net.Siemens AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100); } + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接地址 + /// 设备类型 + /// 读写的地址 + /// 从站号 + /// 主站号 public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, IEnumerable getAddresses, byte slaveAddress, byte masterAddress) : this(connectionType, connectionString, model, getAddresses, false, slaveAddress, masterAddress) diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs index a14fc97..269bcd0 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs @@ -10,22 +10,43 @@ namespace Modbus.Net.Siemens { private readonly string _com; + /// + /// 构造函数 + /// + /// 从站号 + /// 主站号 public SiemensPpiProtocal(byte slaveAddress, byte masterAddress) : this(ConfigurationManager.AppSettings["COM"], slaveAddress, masterAddress) { } + /// + /// 构造函数 + /// + /// 串口地址 + /// 从站号 + /// 主站号 public SiemensPpiProtocal(string com, byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { _com = com; } + /// + /// 发送协议内容并接收,一般方法 + /// + /// 写入的内容,使用对象数组描述 + /// 从设备获取的字节流 public override byte[] SendReceive(params object[] content) { return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content)); } + /// + /// 发送协议内容并接收,一般方法 + /// + /// 写入的内容,使用对象数组描述 + /// 从设备获取的字节流 public override async Task SendReceiveAsync(params object[] content) { if (ProtocalLinker == null || !ProtocalLinker.IsConnected) @@ -33,16 +54,30 @@ namespace Modbus.Net.Siemens return await base.SendReceiveAsync(Endian, content); } + /// + /// 强行发送,不检测连接状态 + /// + /// 协议核心 + /// 协议的参数 + /// 设备返回的信息 private async Task ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content) { return await base.SendReceiveAsync(unit, content); } + /// + /// 连接设备 + /// + /// 是否连接成功 public override bool Connect() { - return AsyncHelper.RunSync(() => ConnectAsync()); + return AsyncHelper.RunSync(ConnectAsync); } + /// + /// 连接设备 + /// + /// 是否连接成功 public override async Task ConnectAsync() { ProtocalLinker = new SiemensPpiProtocalLinker(_com, SlaveAddress); diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs index 6c8c0e0..01a6ef2 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs @@ -9,11 +9,21 @@ namespace Modbus.Net.Siemens /// public class SiemensPpiProtocalLinker : ComProtocalLinker { + /// + /// 构造函数 + /// + /// 串口地址 + /// 从站号 public SiemensPpiProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.Even, StopBits.One, 8, slaveAddress) { } + /// + /// 发送协议内容并接收返回 + /// + /// 发送的报文 + /// 接收的报文 public override async Task SendReceiveAsync(byte[] content) { var extBytes = BytesExtend(content); @@ -36,6 +46,11 @@ namespace Modbus.Net.Siemens return BytesDecact(receiveBytes); } + /// + /// 发送协议内容并接收返回,不进行协议扩展和收缩 + /// + /// 发送的报文 + /// 接收的报文 public override async Task SendReceiveWithoutExtAndDecAsync(byte[] content) { var ans = await base.SendReceiveWithoutExtAndDecAsync(content); @@ -60,6 +75,11 @@ namespace Modbus.Net.Siemens return ans; } + /// + /// 校验报文 + /// + /// 设备返回的信息 + /// 报文是否正确 public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs index 64af6bd..d5ae066 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs @@ -7,6 +7,11 @@ namespace Modbus.Net.Siemens /// public class SiemensTcpProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend { + /// + /// 协议扩展,协议内容发送前调用 + /// + /// 扩展前的原始协议内容 + /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { Array.Copy(new byte[] {0x03, 0x00, 0x00, 0x00, 0x02, 0xf0, 0x80}, 0, content, 0, 7); @@ -14,6 +19,11 @@ namespace Modbus.Net.Siemens return content; } + /// + /// 协议收缩,协议内容接收后调用 + /// + /// 收缩前的完整协议内容 + /// 收缩后的协议内容 public byte[] BytesDecact(byte[] content) { var newContent = new byte[content.Length - 7]; @@ -27,6 +37,11 @@ namespace Modbus.Net.Siemens /// public class SiemensPpiProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend { + /// + /// 协议扩展,协议内容发送前调用 + /// + /// 扩展前的原始协议内容 + /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { var newContent = new byte[content.Length + 2]; @@ -42,6 +57,11 @@ namespace Modbus.Net.Siemens return newContent; } + /// + /// 协议收缩,协议内容接收后调用 + /// + /// 收缩前的完整协议内容 + /// 收缩后的协议内容 public byte[] BytesDecact(byte[] content) { var newContent = new byte[content.Length - 9]; diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs index fc1d577..c5d8c09 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs @@ -18,12 +18,31 @@ namespace Modbus.Net.Siemens private readonly ushort _tsapDst; private int _connectTryCount; + /// + /// 构造函数 + /// + /// + /// + /// + /// + /// + /// public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.AppSettings["IP"]) { } + /// + /// 构造函数 + /// + /// + /// + /// + /// + /// + /// + /// IP地址 public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip) : this( @@ -32,6 +51,17 @@ namespace Modbus.Net.Siemens { } + /// + /// 构造函数 + /// + /// + /// + /// + /// + /// + /// + /// IP地址 + /// 端口 public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip, int port) : base(0, 0) { @@ -46,11 +76,21 @@ namespace Modbus.Net.Siemens _connectTryCount = 0; } + /// + /// 发送数据并接收 + /// + /// 发送的数据 + /// 返回的数据 public override byte[] SendReceive(params object[] content) { return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content)); } + /// + /// 发送数据并接收 + /// + /// 发送的数据 + /// 返回的数据 public override async Task SendReceiveAsync(params object[] content) { if (ProtocalLinker == null || !ProtocalLinker.IsConnected) @@ -58,11 +98,23 @@ namespace Modbus.Net.Siemens return await base.SendReceiveAsync(Endian, content); } + /// + /// 发送数据并接收 + /// + /// 协议的核心 + /// 协议的参数 + /// 返回的数据 public override IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content) { return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content)); } + /// + /// 发送数据并接收 + /// + /// 发送的数据 + /// 协议的参数 + /// 返回的数据 public override async Task SendReceiveAsync(ProtocalUnit unit, IInputStruct content) { if (ProtocalLinker != null && ProtocalLinker.IsConnected) return await base.SendReceiveAsync(unit, content); @@ -74,16 +126,30 @@ namespace Modbus.Net.Siemens .ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null); } + /// + /// 强制发送数据并接收 + /// + /// 发送的数据 + /// 协议的参数 + /// 返回的数据 private async Task ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content) { return await base.SendReceiveAsync(unit, content); } + /// + /// 连接设备 + /// + /// 设备是否连接成功 public override bool Connect() { return AsyncHelper.RunSync(ConnectAsync); } + /// + /// 连接设备 + /// + /// 设备是否连接成功 public override async Task ConnectAsync() { _connectTryCount++; diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs index ffbeabf..14be570 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs @@ -8,16 +8,30 @@ namespace Modbus.Net.Siemens /// public class SiemensTcpProtocalLinker : TcpProtocalLinker { + /// + /// 构造函数 + /// + /// IP地址 public SiemensTcpProtocalLinker(string ip) : this(ip, int.Parse(ConfigurationManager.AppSettings["SiemensPort"] ?? "102")) { } + /// + /// 构造函数 + /// + /// IP地址 + /// 端口 public SiemensTcpProtocalLinker(string ip, int port) : base(ip, port) { } + /// + /// 校验报文 + /// + /// 设备返回的信息 + /// 报文是否正确 public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs index 4d81d49..aeeb360 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs @@ -1,22 +1,56 @@ using System; using System.Threading.Tasks; +using Serilog; namespace Modbus.Net.Siemens { + /// + /// 西门子协议类型 + /// public enum SiemensType { + /// + /// PPI + /// Ppi = 0, + /// + /// MPI + /// Mpi = 1, + /// + /// 以太网 + /// Tcp = 2 } + /// + /// 西门子设备类型 + /// public enum SiemensMachineModel { + /// + /// S7-200 + /// S7_200 = 0, + /// + /// S7-200 Smart + /// S7_200_Smart = 1, + /// + /// S7-300 + /// S7_300 = 2, + /// + /// S7-400 + /// S7_400 = 3, + /// + /// S7-1200 + /// S7_1200 = 4, + /// + /// S7-1500 + /// S7_1500 = 5 } @@ -34,6 +68,14 @@ namespace Modbus.Net.Siemens private SiemensType _siemensType; + /// + /// 构造函数 + /// + /// 连接类型 + /// 连接字符串 + /// 设备类型 + /// 从站地址 + /// 主站地址 public SiemensUtility(SiemensType connectionType, string connectionString, SiemensMachineModel model, byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { @@ -84,15 +126,21 @@ namespace Modbus.Net.Siemens } default: { - throw new NotImplementedException("没有相应的西门子类型"); + throw new NotImplementedException("Siemens PLC Model not Supported"); } } ConnectionType = connectionType; AddressTranslator = new AddressTranslatorSiemens(); } + /// + /// 端格式 + /// public override Endian Endian => Endian.BigEndianLsb; + /// + /// IP地址 + /// protected string ConnectionStringIp { get @@ -102,6 +150,9 @@ namespace Modbus.Net.Siemens } } + /// + /// 端口 + /// protected int? ConnectionStringPort { get @@ -113,8 +164,9 @@ namespace Modbus.Net.Siemens { return connectionStringSplit.Length < 2 ? (int?) null : int.Parse(connectionStringSplit[1]); } - catch + catch (Exception e) { + Log.Error(e, $"SiemensUtility: {ConnectionString} format error"); return null; } } @@ -188,8 +240,9 @@ namespace Modbus.Net.Siemens readRequestSiemensInputStruct); return readRequestSiemensOutputStruct?.GetValue; } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"SiemensUtility -> GetDatas: {ConnectionString} error"); return null; } } @@ -213,8 +266,9 @@ namespace Modbus.Net.Siemens writeRequestSiemensInputStruct); return writeRequestSiemensOutputStruct?.AccessResult == SiemensAccessResult.NoError; } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> SetDatas: {ConnectionString} error"); return false; } } diff --git a/Modbus.Net/Modbus.Net/ComConnector.cs b/Modbus.Net/Modbus.Net/ComConnector.cs index 3454532..71ab2d2 100644 --- a/Modbus.Net/Modbus.Net/ComConnector.cs +++ b/Modbus.Net/Modbus.Net/ComConnector.cs @@ -61,15 +61,16 @@ namespace Modbus.Net /// private readonly int _timeoutTime; + private int _errorCount; + private int _receiveCount; + + private int _sendCount; + /// /// Dispose是否执行 /// private bool m_disposed; - private int _sendCount; - private int _receiveCount; - private int _errorCount; - /// /// 构造器 /// @@ -144,7 +145,7 @@ namespace Modbus.Net /// 字节间隔最大时间 /// 串口实际读入数据个数 public int ReadComm(out byte[] readBuf, int bufRoom, int howTime, int byteTime) - { + { readBuf = new byte[1023]; Array.Clear(readBuf, 0, readBuf.Length); @@ -283,7 +284,7 @@ namespace Modbus.Net { SerialPort.Close(); } - catch (Exception) + catch { //ignore } @@ -308,6 +309,24 @@ namespace Modbus.Net Dispose(false); } + private void RefreshSendCount() + { + _sendCount++; + Log.Verbose("Tcp client {ConnectionToken} send count: {SendCount}", ConnectionToken, _sendCount); + } + + private void RefreshReceiveCount() + { + _receiveCount++; + Log.Verbose("Tcp client {ConnectionToken} receive count: {SendCount}", ConnectionToken, _receiveCount); + } + + private void RefreshErrorCount() + { + _errorCount++; + Log.Verbose("Tcp client {ConnectionToken} error count: {ErrorCount}", ConnectionToken, _errorCount); + } + #region 发送接收数据 /// @@ -381,7 +400,8 @@ namespace Modbus.Net Log.Error(e, "Com client {ConnectionToken} disconnect error", ConnectionToken); return false; } - Log.Error(new Exception("Linkers or Connectors Dictionary not found"), "Com client {ConnectionToken} disconnect error", ConnectionToken); + Log.Error(new Exception("Linkers or Connectors Dictionary not found"), + "Com client {ConnectionToken} disconnect error", ConnectionToken); return false; } @@ -436,7 +456,8 @@ namespace Modbus.Net { try { - Log.Verbose("Com client {ConnectionToken} send msg length: {Length}", ConnectionToken, sendbytes.Length); + Log.Verbose("Com client {ConnectionToken} send msg length: {Length}", ConnectionToken, + sendbytes.Length); Log.Verbose("Com client {ConnectionToken} send msg: {SendBytes}", ConnectionToken, sendbytes); SerialPort.Write(sendbytes, 0, sendbytes.Length); } @@ -450,8 +471,10 @@ namespace Modbus.Net try { returnBytes = ReadMsg(); - Log.Verbose("Com client {ConnectionToken} receive msg length: {Length}", ConnectionToken, returnBytes.Length); - Log.Verbose("Com client {ConnectionToken} receive msg: {SendBytes}", ConnectionToken, returnBytes); + Log.Verbose("Com client {ConnectionToken} receive msg length: {Length}", ConnectionToken, + returnBytes.Length); + Log.Verbose("Com client {ConnectionToken} receive msg: {SendBytes}", ConnectionToken, + returnBytes); } catch (Exception e) { @@ -504,7 +527,8 @@ namespace Modbus.Net { try { - Log.Verbose("Com client {ConnectionToken} send msg length: {Length}", ConnectionToken, sendbytes.Length); + Log.Verbose("Com client {ConnectionToken} send msg length: {Length}", ConnectionToken, + sendbytes.Length); Log.Verbose("Com client {ConnectionToken} send msg: {SendBytes}", ConnectionToken, sendbytes); SerialPort.Write(sendbytes, 0, sendbytes.Length); } @@ -513,7 +537,7 @@ namespace Modbus.Net Log.Error(err, "Com client {ConnectionToken} send msg error", ConnectionToken); Dispose(); return false; - } + } RefreshSendCount(); } return true; @@ -549,23 +573,5 @@ namespace Modbus.Net } #endregion - - private void RefreshSendCount() - { - _sendCount++; - Log.Verbose("Tcp client {ConnectionToken} send count: {SendCount}", ConnectionToken, _sendCount); - } - - private void RefreshReceiveCount() - { - _receiveCount++; - Log.Verbose("Tcp client {ConnectionToken} receive count: {SendCount}", ConnectionToken, _receiveCount); - } - - private void RefreshErrorCount() - { - _errorCount++; - Log.Verbose("Tcp client {ConnectionToken} error count: {ErrorCount}", ConnectionToken, _errorCount); - } } } \ No newline at end of file diff --git a/Modbus.Net/src/Base.Common/AddressTranslator.cs b/Modbus.Net/src/Base.Common/AddressTranslator.cs index 98553a3..f5f07eb 100644 --- a/Modbus.Net/src/Base.Common/AddressTranslator.cs +++ b/Modbus.Net/src/Base.Common/AddressTranslator.cs @@ -52,9 +52,9 @@ namespace Modbus.Net /// /// 地址转换 /// - /// 地址前地址 + /// 格式化的地址 /// 是否为读取,是为读取,否为写入 - /// Key为转换后的地址,Value为辅助码 + /// 翻译后的地址 public abstract AddressDef AddressTranslate(string address, bool isRead); /// diff --git a/Modbus.Net/src/Base.Common/BaseConnector.cs b/Modbus.Net/src/Base.Common/BaseConnector.cs index 0d32421..1232ac8 100644 --- a/Modbus.Net/src/Base.Common/BaseConnector.cs +++ b/Modbus.Net/src/Base.Common/BaseConnector.cs @@ -7,7 +7,6 @@ namespace Modbus.Net /// public abstract class BaseConnector : BaseConnector { - } /// diff --git a/Modbus.Net/src/Base.Common/BaseMachine.cs b/Modbus.Net/src/Base.Common/BaseMachine.cs index 3cfabb5..8331af7 100644 --- a/Modbus.Net/src/Base.Common/BaseMachine.cs +++ b/Modbus.Net/src/Base.Common/BaseMachine.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using Serilog; namespace Modbus.Net { @@ -333,8 +334,9 @@ namespace Modbus.Net } catch (Exception e) { - Console.WriteLine(ConnectionToken + " " + e.Message); ErrorCount++; + Log.Error(e, $"BaseMachine -> GetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}."); + if (ErrorCount >= _maxErrorCount) Disconnect(); return null; @@ -532,7 +534,11 @@ namespace Modbus.Net } catch (Exception e) { - Console.WriteLine(ConnectionToken + " " + e.Message); + ErrorCount++; + Log.Error(e, $"BaseMachine -> SetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}."); + + if (ErrorCount >= _maxErrorCount) + Disconnect(); return false; } return true; @@ -591,7 +597,7 @@ namespace Modbus.Net .Invoke(this, parameters); return (TReturnType) returnValue; } - throw new InvalidCastException($"Machine未实现{typeof(TMachineMethod).Name}的接口"); + throw new InvalidCastException($"Machine interface {nameof(TMachineMethod)} not implemented"); } /// @@ -641,9 +647,9 @@ namespace Modbus.Net { return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId)); } - catch (Exception) + catch (Exception e) { - Console.WriteLine("Id重复,请检查"); + Log.Error(e, $"BaseMachine -> GetAddressUnitById Id:{Id} ConnectionToken:{ConnectionToken} addressUnitId:{addressUnitId} Repeated"); return null; } } diff --git a/Modbus.Net/src/Base.Common/BaseProtocal.cs b/Modbus.Net/src/Base.Common/BaseProtocal.cs index 5b7b5f7..2d90475 100644 --- a/Modbus.Net/src/Base.Common/BaseProtocal.cs +++ b/Modbus.Net/src/Base.Common/BaseProtocal.cs @@ -85,7 +85,8 @@ namespace Modbus.Net //自动寻找存在的协议并将其加载 var protocalUnit = Activator.CreateInstance(type.GetTypeInfo().Assembly.GetType(protocalName)) as TProtocalUnit; - if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容"); + if (protocalUnit == null) + throw new InvalidCastException($"No ProtocalUnit {nameof(TProtocalUnit)} implemented"); protocalUnit.Endian = Endian; Register(protocalUnit); return Protocals[protocalName]; diff --git a/Modbus.Net/src/Base.Common/BaseUtility.cs b/Modbus.Net/src/Base.Common/BaseUtility.cs index 09a4dde..ddb7331 100644 --- a/Modbus.Net/src/Base.Common/BaseUtility.cs +++ b/Modbus.Net/src/Base.Common/BaseUtility.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Serilog; /// /// 端格式 @@ -124,8 +125,9 @@ namespace Modbus.Net var getBytes = getReturnValue; return ValueHelper.GetInstance(Endian).ByteArrayToObjectArray(getBytes, getTypeAndCount); } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> GetDatas: {ConnectionString} error"); return null; } } @@ -159,8 +161,9 @@ namespace Modbus.Net new KeyValuePair(typeof(T), getByteCount)); return ValueHelper.GetInstance(Endian).ObjectArrayToDestinationArray(getBytes); } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> GetDatas Generic: {ConnectionString} error"); return null; } } @@ -199,8 +202,9 @@ namespace Modbus.Net var getBytes = getReturnValue; return ValueHelper.GetInstance(Endian).ByteArrayToObjectArray(getBytes, translateTypeAndCount); } - catch (Exception) + catch (Exception e) { + Log.Error(e, $"ModbusUtility -> GetDatas pair: {ConnectionString} error"); return null; } } @@ -290,7 +294,7 @@ namespace Modbus.Net .Invoke(this, parameters); return (TReturnType) returnValue; } - throw new InvalidCastException($"Utility未实现{typeof(TUtilityMethod).Name}的接口"); + throw new InvalidCastException($"Utility interface {nameof(TUtilityMethod)} not implemented"); } /// diff --git a/Modbus.Net/src/Base.Common/TaskManager.cs b/Modbus.Net/src/Base.Common/TaskManager.cs index 3169381..22305db 100644 --- a/Modbus.Net/src/Base.Common/TaskManager.cs +++ b/Modbus.Net/src/Base.Common/TaskManager.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Nito.AsyncEx; +using Serilog; namespace Modbus.Net { @@ -864,7 +865,7 @@ namespace Modbus.Net } catch (Exception e) { - Console.WriteLine($"设备返回错误 {e.Message}"); + Log.Error(e, $"Device {id} return error"); return null; } } @@ -889,7 +890,7 @@ namespace Modbus.Net } catch (Exception e) { - Console.WriteLine($"设备返回错误 {e.Message}"); + Log.Error(e, $"Device {connectionToken} return error"); return null; } } diff --git a/Modbus.Net/src/Base.Common/TcpConnector.cs b/Modbus.Net/src/Base.Common/TcpConnector.cs index 8f1a56e..2e71893 100644 --- a/Modbus.Net/src/Base.Common/TcpConnector.cs +++ b/Modbus.Net/src/Base.Common/TcpConnector.cs @@ -40,9 +40,10 @@ namespace Modbus.Net /// private readonly byte[] _receiveBuffer = new byte[1024]; - private int _sendCount; - private int _receiveCount; private int _errorCount; + private int _receiveCount; + + private int _sendCount; private TcpClient _socketClient; @@ -73,7 +74,8 @@ namespace Modbus.Net /// public int TimeoutTime { - get => _timeoutTime; + get => + _timeoutTime; set { _timeoutTime = value; @@ -122,7 +124,7 @@ namespace Modbus.Net #endif Log.Debug("Tcp client {ConnectionToken} Disposed", ConnectionToken); } - m_disposed = true; + m_disposed = true; } } @@ -242,7 +244,7 @@ namespace Modbus.Net await stream.WriteAsync(datagram, 0, datagram.Length); RefreshSendCount(); - + return true; } catch (Exception err) @@ -282,11 +284,12 @@ namespace Modbus.Net Log.Verbose("Tcp client {ConnectionToken} send text len = {Length}", ConnectionToken, datagram.Length); Log.Verbose("Tcp client {ConnectionToken} send: {Datagram}", ConnectionToken, datagram); await stream.WriteAsync(datagram, 0, datagram.Length); - + RefreshSendCount(); var receiveBytes = await ReceiveAsync(stream); - Log.Verbose("Tcp client {ConnectionToken} receive text len = {Length}", ConnectionToken, receiveBytes.Length); + Log.Verbose("Tcp client {ConnectionToken} receive text len = {Length}", ConnectionToken, + receiveBytes.Length); Log.Verbose("Tcp client {ConnectionToken} receive: {Datagram}", ConnectionToken, receiveBytes); return receiveBytes; @@ -332,7 +335,7 @@ namespace Modbus.Net var replyMessage = new byte[len]; Array.Copy(_receiveBuffer, replyMessage, len); - Log.Verbose("Tcp client {ConnectionToken} reply: {replyMessage}",ConnectionToken, replyMessage); + Log.Verbose("Tcp client {ConnectionToken} reply: {replyMessage}", ConnectionToken, replyMessage); RefreshReceiveCount(); if (len <= 0) diff --git a/Modbus.Net/src/Base.Common/TcpProtocalLinker.cs b/Modbus.Net/src/Base.Common/TcpProtocalLinker.cs index 6a86707..17b7c91 100644 --- a/Modbus.Net/src/Base.Common/TcpProtocalLinker.cs +++ b/Modbus.Net/src/Base.Common/TcpProtocalLinker.cs @@ -1,6 +1,6 @@ - -#if NET40||NET45||NET451||NET452||NET46||NET461||NET462||NET47 +#if NET40||NET45||NET451||NET452||NET46||NET461||NET462||NET47 using System.Configuration; + #endif namespace Modbus.Net diff --git a/Modbus.Net/src/Base.Common/TypeExtensions.cs b/Modbus.Net/src/Base.Common/TypeExtensions.cs index b81436f..25a197e 100644 --- a/Modbus.Net/src/Base.Common/TypeExtensions.cs +++ b/Modbus.Net/src/Base.Common/TypeExtensions.cs @@ -36,7 +36,7 @@ namespace Modbus.Net throw new NullReferenceException("The type has not been specified."); if (string.IsNullOrEmpty(methodName)) - throw new ArgumentNullException("methodName", "The name of the method has not been specified."); + throw new ArgumentNullException(nameof(methodName), "The name of the method has not been specified."); var methods = diff --git a/Modbus.Net/src/Base.Common/ValueHelper.cs b/Modbus.Net/src/Base.Common/ValueHelper.cs index 01a2897..7d0a1cf 100644 --- a/Modbus.Net/src/Base.Common/ValueHelper.cs +++ b/Modbus.Net/src/Base.Common/ValueHelper.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; +using Serilog; namespace Modbus.Net { @@ -707,12 +708,13 @@ namespace Modbus.Net } default: { - throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + throw new NotImplementedException("Number casting not implemented"); } } } - catch (Exception) + catch (Exception e) { + Log.Error(e, "ValueHelper -> ByteArrayToObjectArray error"); count = contents.Length; } } @@ -798,7 +800,7 @@ namespace Modbus.Net } default: { - throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + throw new NotImplementedException("Number casting not implemented"); } } } @@ -818,8 +820,9 @@ namespace Modbus.Net Array.Copy(datas, 0, contents, pos, datas.Length); return true; } - catch (Exception) + catch (Exception e) { + Log.Error(e, "ValueHelper -> SetValue set value failed"); return false; } } @@ -866,8 +869,9 @@ namespace Modbus.Net contents[pos] = SetBit(contents[pos], subPos, setValue); return true; } - catch (Exception) + catch (Exception e) { + Log.Error(e, "ValueHelper -> SetBit set bit failed"); return false; } }