2017-05-17 Update 3 Implement log system and add comments
This commit is contained in:
@@ -5,11 +5,24 @@
|
||||
/// </summary>
|
||||
public class AddressFormaterNA200H : AddressFormater
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <returns>格式化的地址字符串</returns>
|
||||
public override string FormatAddress(string area, int address)
|
||||
{
|
||||
return area + " " + address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <param name="subAddress">比特位地址</param>
|
||||
/// <returns>格式化的地址字符串</returns>
|
||||
public override string FormatAddress(string area, int address, int subAddress)
|
||||
{
|
||||
return area + " " + address + "." + subAddress;
|
||||
@@ -21,11 +34,24 @@
|
||||
/// </summary>
|
||||
public class AddressFormaterModbus : AddressFormater
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <returns>格式化的地址字符串</returns>
|
||||
public override string FormatAddress(string area, int address)
|
||||
{
|
||||
return area + " " + address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化地址
|
||||
/// </summary>
|
||||
/// <param name="area">地址区域</param>
|
||||
/// <param name="address">地址</param>
|
||||
/// <param name="subAddress">比特位地址</param>
|
||||
/// <returns>格式化的地址字符串</returns>
|
||||
public override string FormatAddress(string area, int address, int subAddress)
|
||||
{
|
||||
return area + " " + address + "." + subAddress;
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
public AddressTranslatorNA200H()
|
||||
{
|
||||
TransDictionary = new Dictionary<string, int>
|
||||
@@ -154,6 +157,12 @@ namespace Modbus.Net.Modbus
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址转换
|
||||
/// </summary>
|
||||
/// <param name="address">格式化的地址</param>
|
||||
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
|
||||
/// <returns>翻译后的地址</returns>
|
||||
public override AddressDef AddressTranslate(string address, bool isRead)
|
||||
{
|
||||
address = address.ToUpper();
|
||||
@@ -188,6 +197,11 @@ namespace Modbus.Net.Modbus
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取区域中的单个地址占用的字节长度
|
||||
/// </summary>
|
||||
/// <param name="area">区域名称</param>
|
||||
/// <returns>字节长度</returns>
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return ReadFunctionCodeDictionary[area].AreaWidth;
|
||||
@@ -209,6 +223,9 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
public AddressTranslatorModbus()
|
||||
{
|
||||
ReadFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
|
||||
@@ -259,6 +276,12 @@ namespace Modbus.Net.Modbus
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址转换
|
||||
/// </summary>
|
||||
/// <param name="address">格式化的地址</param>
|
||||
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
|
||||
/// <returns>翻译后的地址</returns>
|
||||
public override AddressDef AddressTranslate(string address, bool isRead)
|
||||
{
|
||||
address = address.ToUpper();
|
||||
@@ -293,6 +316,11 @@ namespace Modbus.Net.Modbus
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取区域中的单个地址占用的字节长度
|
||||
/// </summary>
|
||||
/// <param name="area">区域名称</param>
|
||||
/// <returns>字节长度</returns>
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return ReadFunctionCodeDictionary[area].AreaWidth;
|
||||
|
||||
@@ -7,11 +7,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusAsciiProtocal : ModbusProtocal
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusAsciiProtocal(byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: this(ConfigurationManager.AppSettings["COM"], slaveAddress, masterAddress, endian)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="com">串口地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusAsciiProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: base(slaveAddress, masterAddress, endian)
|
||||
{
|
||||
|
||||
@@ -8,13 +8,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusAsciiProtocalLinker : ComProtocalLinker
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="com">串口地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
public ModbusAsciiProtocalLinker(string com, int slaveAddress)
|
||||
: base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验返回数据是否正确
|
||||
/// </summary>
|
||||
/// <param name="content">返回的数据</param>
|
||||
/// <returns>校验是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocalLinker不会返回null
|
||||
if (!base.CheckRight(content).Value) return false;
|
||||
//CRC校验失败
|
||||
var contentString = Encoding.ASCII.GetString(content);
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace Modbus.Net.Modbus
|
||||
public class ModbusMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">读写的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
|
||||
Endian endian = Endian.BigEndianLsb)
|
||||
@@ -20,6 +30,15 @@ namespace Modbus.Net.Modbus
|
||||
AddressCombinerSet = new AddressCombinerContinus<TUnitKey>(AddressTranslator, 100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">读写的地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey>> getAddresses, byte slaveAddress, byte masterAddress,
|
||||
Endian endian = Endian.BigEndianLsb)
|
||||
@@ -33,6 +52,16 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusMachine : BaseMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">读写的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
|
||||
Endian endian = Endian.BigEndianLsb)
|
||||
@@ -44,6 +73,15 @@ namespace Modbus.Net.Modbus
|
||||
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">读写的地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress,
|
||||
Endian endian = Endian.BigEndianLsb)
|
||||
|
||||
@@ -9,7 +9,14 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
internal enum ModbusProtocalVariableFunctionCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读变量
|
||||
/// </summary>
|
||||
ReadVariable = 20,
|
||||
|
||||
/// <summary>
|
||||
/// 写变量
|
||||
/// </summary>
|
||||
WriteVariable = 21
|
||||
}
|
||||
|
||||
@@ -18,7 +25,14 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public enum ModbusProtocalTimeFunctionCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读时间
|
||||
/// </summary>
|
||||
GetSystemTime = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 写时间
|
||||
/// </summary>
|
||||
SetSystemTime = 16
|
||||
}
|
||||
|
||||
@@ -27,9 +41,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public enum ModbusProtocalReadDataFunctionCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读线圈
|
||||
/// </summary>
|
||||
ReadCoilStatus = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 读输入线圈
|
||||
/// </summary>
|
||||
ReadInputStatus = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 读保持寄存器
|
||||
/// </summary>
|
||||
ReadHoldRegister = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 读输入寄存器
|
||||
/// </summary>
|
||||
ReadInputRegister = 4
|
||||
}
|
||||
|
||||
@@ -38,7 +67,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
internal enum ModbusProtocalWriteDataFunctionCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 写单个线圈
|
||||
/// </summary>
|
||||
WriteSingleCoil = 5,
|
||||
|
||||
/// <summary>
|
||||
/// 写单个寄存器
|
||||
/// </summary>
|
||||
WriteSingleRegister = 6,
|
||||
|
||||
/// <summary>
|
||||
/// 写多个线圈
|
||||
/// </summary>
|
||||
WriteMultiCoil = 15,
|
||||
|
||||
/// <summary>
|
||||
/// 写多个寄存器
|
||||
/// </summary>
|
||||
WriteMultiRegister = 16
|
||||
}
|
||||
|
||||
@@ -47,16 +93,30 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public abstract class ModbusProtocal : BaseProtocal
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站地址</param>
|
||||
/// <param name="masterAddress">主站地址</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
protected ModbusProtocal(byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: base(slaveAddress, masterAddress, endian)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override bool Connect()
|
||||
{
|
||||
return ProtocalLinker.Connect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
return await ProtocalLinker.ConnectAsync();
|
||||
@@ -65,8 +125,18 @@ namespace Modbus.Net.Modbus
|
||||
|
||||
#region 读PLC数据
|
||||
|
||||
/// <summary>
|
||||
/// 读数据输入
|
||||
/// </summary>
|
||||
public class ReadDataModbusInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站地址</param>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="getCount">读取个数</param>
|
||||
/// <param name="addressTranslator">地址翻译器</param>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站地址
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取个数
|
||||
/// </summary>
|
||||
public ushort GetCount { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读数据输出
|
||||
/// </summary>
|
||||
public class ReadDataModbusOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="dataCount">数据个数</param>
|
||||
/// <param name="dataValue">读取的数据值</param>
|
||||
public ReadDataModbusOutputStruct(byte slaveAddress, byte functionCode,
|
||||
int dataCount, byte[] dataValue)
|
||||
{
|
||||
@@ -98,17 +190,37 @@ namespace Modbus.Net.Modbus
|
||||
DataValue = dataValue.Clone() as byte[];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据个数
|
||||
/// </summary>
|
||||
public int DataCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据值
|
||||
/// </summary>
|
||||
public byte[] DataValue { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读数据协议
|
||||
/// </summary>
|
||||
public class ReadDataModbusProtocal : ProtocalUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="message">读取参数</param>
|
||||
/// <returns>读取数据的协议核心</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反格式化
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">设备返回的信息</param>
|
||||
/// <param name="pos">当前反格式化的位置</param>
|
||||
/// <returns>反格式化的信息</returns>
|
||||
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数据
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输入
|
||||
/// </summary>
|
||||
public class WriteDataModbusInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="writeValue">写入的数据</param>
|
||||
/// <param name="addressTranslator">地址翻译器</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public WriteDataModbusInputStruct(byte slaveAddress, string startAddress, object[] writeValue,
|
||||
AddressTranslator addressTranslator, Endian endian)
|
||||
{
|
||||
@@ -147,21 +276,49 @@ namespace Modbus.Net.Modbus
|
||||
WriteValue = writeByteValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入个数
|
||||
/// </summary>
|
||||
public ushort WriteCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入字节个数
|
||||
/// </summary>
|
||||
public byte WriteByteCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入的数据
|
||||
/// </summary>
|
||||
public byte[] WriteValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输出
|
||||
/// </summary>
|
||||
public class WriteDataModbusOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="writeCount">写入个数</param>
|
||||
public WriteDataModbusOutputStruct(byte slaveAddress, byte functionCode,
|
||||
ushort startAddress, ushort writeCount)
|
||||
{
|
||||
@@ -171,20 +328,37 @@ namespace Modbus.Net.Modbus
|
||||
WriteCount = writeCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入个数
|
||||
/// </summary>
|
||||
public ushort WriteCount { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写多个寄存器状态
|
||||
/// 写多个寄存器协议
|
||||
/// </summary>
|
||||
public class WriteDataModbusProtocal : ProtocalUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="message">写寄存器参数</param>
|
||||
/// <returns>写寄存器协议核心</returns>
|
||||
public override byte[] Format(IInputStruct message)
|
||||
{
|
||||
var r_message = (WriteDataModbusInputStruct) message;
|
||||
@@ -194,6 +368,12 @@ namespace Modbus.Net.Modbus
|
||||
return formattingBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反格式化
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">设备返回的信息</param>
|
||||
/// <param name="flag">当前反格式化的位置</param>
|
||||
/// <returns>反格式化的信息</returns>
|
||||
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时间
|
||||
|
||||
/// <summary>
|
||||
/// 读时间输入
|
||||
/// </summary>
|
||||
public class GetSystemTimeModbusInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
public GetSystemTimeModbusInputStruct(byte slaveAddress)
|
||||
{
|
||||
SlaveAddress = slaveAddress;
|
||||
@@ -219,17 +406,45 @@ namespace Modbus.Net.Modbus
|
||||
GetCount = 5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取个数
|
||||
/// </summary>
|
||||
public ushort GetCount { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读时间输出
|
||||
/// </summary>
|
||||
public class GetSystemTimeModbusOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="writeByteCount">写入个数</param>
|
||||
/// <param name="year">年</param>
|
||||
/// <param name="day">日</param>
|
||||
/// <param name="month">月</param>
|
||||
/// <param name="hour">时</param>
|
||||
/// <param name="second">秒</param>
|
||||
/// <param name="minute">分</param>
|
||||
/// <param name="millisecond">毫秒</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入个数
|
||||
/// </summary>
|
||||
public byte WriteByteCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// </summary>
|
||||
public DateTime Time { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读系统时间
|
||||
/// 读系统时间协议
|
||||
/// </summary>
|
||||
public class GetSystemTimeModbusProtocal : ProtocalUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="message">写系统时间参数</param>
|
||||
/// <returns>写系统时间的核心</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反格式化
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">获取的信息</param>
|
||||
/// <param name="flag">当前反格式化的位置</param>
|
||||
/// <returns>反格式化的信息</returns>
|
||||
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时间
|
||||
|
||||
/// <summary>
|
||||
/// 写时间输入
|
||||
/// </summary>
|
||||
public class SetSystemTimeModbusInputStruct : IInputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="time">时间</param>
|
||||
public SetSystemTimeModbusInputStruct(byte slaveAddress, DateTime time)
|
||||
{
|
||||
SlaveAddress = slaveAddress;
|
||||
@@ -300,33 +546,79 @@ namespace Modbus.Net.Modbus
|
||||
Millisecond = (ushort) time.Millisecond;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入个数
|
||||
/// </summary>
|
||||
public ushort WriteCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入字节个数
|
||||
/// </summary>
|
||||
public byte WriteByteCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 年
|
||||
/// </summary>
|
||||
public ushort Year { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 日
|
||||
/// </summary>
|
||||
public byte Day { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 月
|
||||
/// </summary>
|
||||
public byte Month { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 时
|
||||
/// </summary>
|
||||
public ushort Hour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 秒
|
||||
/// </summary>
|
||||
public byte Second { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 分
|
||||
/// </summary>
|
||||
public byte Minute { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 毫秒
|
||||
/// </summary>
|
||||
public ushort Millisecond { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写时间输出
|
||||
/// </summary>
|
||||
public class SetSystemTimeModbusOutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="startAddress">开始地址</param>
|
||||
/// <param name="writeCount">写入个数</param>
|
||||
public SetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode,
|
||||
ushort startAddress, ushort writeCount)
|
||||
{
|
||||
@@ -336,20 +628,37 @@ namespace Modbus.Net.Modbus
|
||||
WriteCount = writeCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从站号
|
||||
/// </summary>
|
||||
public byte SlaveAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能码
|
||||
/// </summary>
|
||||
public byte FunctionCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始地址
|
||||
/// </summary>
|
||||
public ushort StartAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入个数
|
||||
/// </summary>
|
||||
public ushort WriteCount { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写系统时间
|
||||
/// 写系统时间协议
|
||||
/// </summary>
|
||||
public class SetSystemTimeModbusProtocal : ProtocalUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="message">写系统时间的参数</param>
|
||||
/// <returns>写系统时间的核心</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反格式化
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">获取的信息</param>
|
||||
/// <param name="flag">当前反格式化的位置</param>
|
||||
/// <returns>反格式化的信息</returns>
|
||||
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"}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Modbus错误
|
||||
/// </summary>
|
||||
/// <param name="messageNumber">Modbus错误号</param>
|
||||
public ModbusProtocalErrorException(int messageNumber)
|
||||
: base(ProtocalErrorDictionary[messageNumber])
|
||||
{
|
||||
ErrorMessageNumber = messageNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modbus错误号
|
||||
/// </summary>
|
||||
public int ErrorMessageNumber { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,11 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusTcpProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议扩展,协议内容发送前调用
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的原始协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
//Modbus/Tcp协议扩张,前面加6个字节,前面4个为0,后面两个为协议整体内容的长度
|
||||
@@ -22,6 +27,11 @@ namespace Modbus.Net.Modbus
|
||||
return newFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议收缩,协议内容接收后调用
|
||||
/// </summary>
|
||||
/// <param name="content">收缩前的完整协议内容</param>
|
||||
/// <returns>收缩后的协议内容</returns>
|
||||
public byte[] BytesDecact(byte[] content)
|
||||
{
|
||||
//Modbus/Tcp协议收缩,抛弃前面6个字节的内容
|
||||
@@ -31,8 +41,16 @@ namespace Modbus.Net.Modbus
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rtu协议字节伸缩
|
||||
/// </summary>
|
||||
public class ModbusRtuProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议扩展,协议内容发送前调用
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的原始协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
var crc = new byte[2];
|
||||
@@ -44,6 +62,11 @@ namespace Modbus.Net.Modbus
|
||||
return newFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议收缩,协议内容接收后调用
|
||||
/// </summary>
|
||||
/// <param name="content">收缩前的完整协议内容</param>
|
||||
/// <returns>收缩后的协议内容</returns>
|
||||
public byte[] BytesDecact(byte[] content)
|
||||
{
|
||||
//Modbus/Rtu协议收缩,抛弃后面2个字节的内容
|
||||
@@ -53,8 +76,16 @@ namespace Modbus.Net.Modbus
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ascii协议字节伸缩
|
||||
/// </summary>
|
||||
public class ModbusAsciiProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议扩展,协议内容发送前调用
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的原始协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
//Modbus/Ascii协议扩张,前面增加:,后面增加LRC校验和尾字符
|
||||
@@ -68,6 +99,11 @@ namespace Modbus.Net.Modbus
|
||||
return newContent.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议收缩,协议内容接收后调用
|
||||
/// </summary>
|
||||
/// <param name="content">收缩前的完整协议内容</param>
|
||||
/// <returns>收缩后的协议内容</returns>
|
||||
public byte[] BytesDecact(byte[] content)
|
||||
{
|
||||
//Modbus/Ascii协议收缩,抛弃头尾。
|
||||
|
||||
@@ -7,11 +7,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusRtuProtocal : ModbusProtocal
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusRtuProtocal(byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: this(ConfigurationManager.AppSettings["COM"], slaveAddress, masterAddress, endian)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="com">串口</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusRtuProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: base(slaveAddress, masterAddress, endian)
|
||||
{
|
||||
|
||||
@@ -7,13 +7,24 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusRtuProtocalLinker : ComProtocalLinker
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="com">串口地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
public ModbusRtuProtocalLinker(string com, int slaveAddress)
|
||||
: base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验返回数据
|
||||
/// </summary>
|
||||
/// <param name="content">设备返回的数据</param>
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocalLinker的CheckRight不会返回null
|
||||
if (!base.CheckRight(content).Value) return false;
|
||||
//CRC校验失败
|
||||
if (!Crc16.GetInstance().CrcEfficacy(content))
|
||||
|
||||
@@ -7,17 +7,38 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusTcpProtocal : ModbusProtocal
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusTcpProtocal(byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: this(ConfigurationManager.AppSettings["IP"], slaveAddress, masterAddress, endian)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="ip">ip地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusTcpProtocal(string ip, byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: base(slaveAddress, masterAddress, endian)
|
||||
{
|
||||
ProtocalLinker = new ModbusTcpProtocalLinker(ip);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="ip">ip地址</param>
|
||||
/// <param name="port">端口</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusTcpProtocal(string ip, int port, byte slaveAddress, byte masterAddress, Endian endian)
|
||||
: base(slaveAddress, masterAddress, endian)
|
||||
{
|
||||
|
||||
@@ -7,17 +7,32 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class ModbusTcpProtocalLinker : TcpProtocalLinker
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="ip">IP地址</param>
|
||||
public ModbusTcpProtocalLinker(string ip)
|
||||
: base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"] ?? "502"))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="ip">IP地址</param>
|
||||
/// <param name="port">端口</param>
|
||||
public ModbusTcpProtocalLinker(string ip, int port) : base(ip, port)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验返回数据
|
||||
/// </summary>
|
||||
/// <param name="content">设备返回的数据</param>
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocalLinker的CheckRight不会返回null
|
||||
if (!base.CheckRight(content).Value) return false;
|
||||
//长度校验失败
|
||||
if (content[5] != content.Length - 6)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
|
||||
namespace Modbus.Net.Modbus
|
||||
{
|
||||
@@ -34,6 +35,13 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
private ModbusType _modbusType;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">协议类型</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="connectionType">协议类型</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 端格式
|
||||
/// </summary>
|
||||
public override Endian Endian { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ip地址
|
||||
/// </summary>
|
||||
protected string ConnectionStringIp
|
||||
{
|
||||
get
|
||||
@@ -65,6 +87,9 @@ namespace Modbus.Net.Modbus
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 端口
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议类型
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置协议类型
|
||||
/// </summary>
|
||||
/// <param name="connectionType">协议类型</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user