diff --git a/Modbus.Net/Modbus.Net.BigEndian3412/Modbus.Net.BigEndian3412.csproj b/Modbus.Net/Modbus.Net.BigEndian3412/Modbus.Net.BigEndian3412.csproj
index 56b1cf7..744e140 100644
--- a/Modbus.Net/Modbus.Net.BigEndian3412/Modbus.Net.BigEndian3412.csproj
+++ b/Modbus.Net/Modbus.Net.BigEndian3412/Modbus.Net.BigEndian3412.csproj
@@ -6,7 +6,7 @@
Modbus.Net.BigEndian3412
Modbus.Net.BigEndian3412
Modbus.Net.BigEndian3412
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net.Modbus
diff --git a/Modbus.Net/Modbus.Net.CodeGenerator/ConnectorWithControllerByteArrayCodeGenerator.cs b/Modbus.Net/Modbus.Net.CodeGenerator/ConnectorWithControllerByteArrayCodeGenerator.cs
new file mode 100644
index 0000000..74dcb4f
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.CodeGenerator/ConnectorWithControllerByteArrayCodeGenerator.cs
@@ -0,0 +1,158 @@
+using Microsoft.CodeAnalysis;
+using System.Text;
+
+namespace Modbus.Net.CodeGenerator
+{
+ [Generator]
+ public class BaseConnectorCodeGenerator : ISourceGenerator
+ {
+ public void Execute(GeneratorExecutionContext context)
+ {
+ var source = $@"
+using Microsoft.Extensions.Logging;
+using Nito.AsyncEx;
+using System;
+using System.Threading.Tasks;
+
+namespace Modbus.Net
+{{
+ public abstract partial class BaseConnector : BaseConnector
+ {{
+"
++ ConnectorWithControllerByteArrayCodeContent.Code("BaseConnector")
++ $@"
+ }}
+}}";
+ context.AddSource("BaseConnectorContent.g.cs", source);
+ }
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+
+ }
+ }
+
+ [Generator]
+ public class EventHandlerConnectorCodeGenerator : ISourceGenerator
+ {
+ public void Execute(GeneratorExecutionContext context)
+ {
+ var source = $@"
+using Microsoft.Extensions.Logging;
+using Nito.AsyncEx;
+using System;
+using System.Threading.Tasks;
+
+namespace Modbus.Net
+{{
+ public abstract partial class EventHandlerConnector : EventHandlerConnector
+ {{
+"
++ ConnectorWithControllerByteArrayCodeContent.Code("EventHandlerConnector")
++ $@"
+ }}
+}}";
+ context.AddSource("EventHandlerConnectorContent.g.cs", source);
+ }
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+
+ }
+ }
+
+ public static class ConnectorWithControllerByteArrayCodeContent
+ {
+ public static string Code(string className)
+ {
+ return new StringBuilder(@"
+ ///
+ /// 发送锁
+ ///
+ protected abstract AsyncLock Lock { get; }
+
+ ///
+ /// 是否为全双工
+ ///
+ public bool IsFullDuplex { get; }
+
+ ///
+ /// 发送超时时间
+ ///
+ protected abstract int TimeoutTime { get; set; }
+
+ ///
+ /// 构造器
+ ///
+ /// 发送超时时间
+ /// 是否为全双工
+ protected {%0}(int timeoutTime = 10000, bool isFullDuplex = false)
+ {
+ IsFullDuplex = isFullDuplex;
+ if (timeoutTime < -1) timeoutTime = -1;
+ TimeoutTime = timeoutTime;
+ }
+
+ ///
+ public override async Task SendMsgAsync(byte[] message)
+ {
+ var ans = await SendMsgInner(message);
+ if (ans == null) return new byte[0];
+ return ans.ReceiveMessage;
+ }
+
+ ///
+ /// 发送内部
+ ///
+ /// 发送的信息
+ /// 是否为重发消息
+ /// 发送信息的定义
+ protected async Task SendMsgInner(byte[] message, bool repeat = false)
+ {
+ IDisposable asyncLock = null;
+ try
+ {
+ if (!Controller.IsSending)
+ {
+ Controller.SendStart();
+ }
+ var messageSendingdef = Controller.AddMessage(message);
+ if (messageSendingdef != null)
+ {
+ if (!IsFullDuplex)
+ {
+ asyncLock = await Lock.LockAsync();
+ }
+ var success = messageSendingdef.SendMutex.WaitOne(TimeoutTime);
+ if (success)
+ {
+ await SendMsgWithoutConfirm(message);
+ success = messageSendingdef.ReceiveMutex.WaitOne(TimeoutTime);
+ if (success)
+ {
+ if (!repeat && messageSendingdef.ReceiveMessage == null)
+ {
+ asyncLock?.Dispose();
+ return await SendMsgInner(message, true);
+ }
+ return messageSendingdef;
+ }
+ }
+ Controller.ForceRemoveWaitingMessage(messageSendingdef);
+ }
+ logger.LogInformation(""Message is waiting in {0}. Cancel!"", ConnectionToken);
+ return null;
+ }
+ catch (Exception e)
+ {
+ logger.LogError(e, ""Connector {0} Send Error."", ConnectionToken);
+ return null;
+ }
+ finally
+ {
+ asyncLock?.Dispose();
+ }
+ }").Replace("{%0}", className).ToString();
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.CodeGenerator/Modbus.Net.CodeGenerator.csproj b/Modbus.Net/Modbus.Net.CodeGenerator/Modbus.Net.CodeGenerator.csproj
new file mode 100644
index 0000000..e9041c6
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.CodeGenerator/Modbus.Net.CodeGenerator.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Library
+ netstandard2.0
+ 9.0
+ true
+
+
+
+
+
+
+
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212Controller.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212Controller.cs
new file mode 100644
index 0000000..89d2788
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212Controller.cs
@@ -0,0 +1,10 @@
+namespace Modbus.Net.HJ212
+{
+ public class HJ212Controller : FifoController
+ {
+ public HJ212Controller(string ip, int port) : base(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")))
+ {
+
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212Machine.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212Machine.cs
new file mode 100644
index 0000000..fdf9341
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212Machine.cs
@@ -0,0 +1,101 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Modbus.Net.HJ212
+{
+ public class HJ212Machine : BaseMachine where TKey : IEquatable
+ where TUnitKey : IEquatable
+ {
+ private static readonly ILogger> logger = LogProvider.CreateLogger>();
+
+ private readonly int _maxErrorCount = 3;
+
+ protected string ST { get; }
+
+ protected string CN { get; }
+
+ protected string PW { get; }
+
+ protected string MN { get; }
+
+ private int ErrorCount { get; set; }
+
+ ///
+ /// 构造函数
+ ///
+ /// 设备的ID号
+ /// 连接地址
+ public HJ212Machine(TKey id, string connectionString, string st, string cn, string pw, string mn)
+ : base(id, null, true)
+ {
+ BaseUtility = new HJ212Utility(connectionString);
+ ST = st;
+ CN = cn;
+ PW = pw;
+ MN = mn;
+ }
+
+ public override Task>>> GetDatasAsync(MachineDataType getDataType)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override async Task> SetDatasAsync(MachineDataType setDataType, Dictionary values)
+ {
+ try
+ {
+ //检测并连接设备
+ if (!BaseUtility.IsConnected)
+ await BaseUtility.ConnectAsync();
+ //如果设备无法连接,终止
+ if (!BaseUtility.IsConnected) return new ReturnStruct()
+ {
+ Datas = false,
+ IsSuccess = false,
+ ErrorCode = -1,
+ ErrorMsg = "Connection Error"
+ };
+
+ //遍历每个要设置的值
+ Dictionary formatValues = new Dictionary();
+ foreach (var value in values)
+ {
+ //根据设置类型找到对应的地址描述
+ formatValues.Add(value.Key, value.Value.ToString());
+ }
+ var sendValues = new List>() { formatValues };
+ //写入数据
+ await
+ BaseUtility.GetUtilityMethods().SetDatasAsync("0", new object[] { ST, CN, PW, MN, sendValues, DateTime.Now });
+
+ //如果不保持连接,断开连接
+ if (!KeepConnect)
+ BaseUtility.Disconnect();
+ }
+ catch (Exception e)
+ {
+ ErrorCount++;
+ logger.LogError(e, $"BaseMachine -> SetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}.");
+
+ if (ErrorCount >= _maxErrorCount)
+ Disconnect();
+ return new ReturnStruct()
+ {
+ Datas = false,
+ IsSuccess = false,
+ ErrorCode = -100,
+ ErrorMsg = "Unknown Exception"
+ };
+ }
+ return new ReturnStruct()
+ {
+ Datas = true,
+ IsSuccess = true,
+ ErrorCode = 0,
+ ErrorMsg = ""
+ };
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212Protocol.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212Protocol.cs
new file mode 100644
index 0000000..6ec4256
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212Protocol.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Modbus.Net.HJ212
+{
+ ///
+ /// HJ212协议
+ ///
+ public class HJ212Protocol : BaseProtocol
+ {
+ ///
+ /// 构造函数
+ ///
+ public HJ212Protocol(string ip)
+ : base(0, 0, Endian.BigEndianLsb)
+ {
+ ProtocolLinker = new HJ212ProtocolLinker(ip, int.Parse(ConfigurationReader.GetValueDirect("TCP:" + ip, "HJ212Port") ?? ConfigurationReader.GetValueDirect("TCP:Modbus", "HJ212Port") ?? "443"));
+ }
+
+ ///
+ /// 连接
+ ///
+ /// 是否连接成功
+ public override async Task ConnectAsync()
+ {
+ return await ProtocolLinker.ConnectAsync();
+ }
+ }
+
+ #region 写数据
+ ///
+ /// 写数据协议
+ ///
+ public class WriteRequestHJ212Protocol : ProtocolUnit
+ {
+ ///
+ /// 从对象的参数数组格式化
+ ///
+ /// 非结构化的输入数据
+ /// 格式化后的字节流
+ public override byte[] Format(IInputStruct message)
+ {
+ var r_message = (WriteRequestHJ212InputStruct)message;
+ string formatMessage = "##0633";
+ formatMessage += "QN=" + r_message.QN + ";";
+ formatMessage += "ST=" + r_message.ST + ";";
+ formatMessage += "CN=" + r_message.CN + ";";
+ formatMessage += "PW=" + r_message.PW + ";";
+ formatMessage += "MN=" + r_message.MN + ";";
+ formatMessage += "CP=&&";
+ formatMessage += "DateTime=" + r_message.Datetime.ToString("yyyyMMddHHmmss") + ";";
+ foreach (var record in r_message.CP)
+ {
+ foreach (var data in record)
+ {
+ formatMessage += data.Key + "=" + data.Value + ",";
+ }
+ formatMessage = formatMessage[..^1];
+ formatMessage += ";";
+ }
+ formatMessage = formatMessage[..^1];
+ formatMessage += "&&";
+ return Encoding.ASCII.GetBytes(formatMessage);
+ }
+
+ ///
+ /// 把仪器返回的内容填充到输出结构中
+ ///
+ /// 返回数据的字节流
+ /// 转换标记位
+ /// 结构化的输出数据
+ public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
+ {
+ return new WriteRequestHJ212OutputStruct(Encoding.ASCII.GetString(messageBytes));
+ }
+ }
+
+ ///
+ /// 写数据输入
+ ///
+ public class WriteRequestHJ212InputStruct : IInputStruct
+ {
+ public WriteRequestHJ212InputStruct(string st, string cn, string pw, string mn, List> cp, DateTime datetime)
+ {
+ ST = st;
+ CN = cn;
+ PW = pw;
+ MN = mn;
+ CP = cp;
+ Datetime = datetime;
+ }
+
+ public string QN => "20170101000926706";
+
+ public string ST { get; }
+
+ public string CN { get; }
+
+ public string PW { get; }
+
+ public string MN { get; }
+
+ public List> CP { get; }
+
+ public DateTime Datetime { get; }
+ }
+
+ ///
+ /// 写数据输出
+ ///
+ public class WriteRequestHJ212OutputStruct : IOutputStruct
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 读取的数据
+ public WriteRequestHJ212OutputStruct(string value)
+ {
+ GetValue = value;
+ }
+
+ ///
+ /// 读取的地址
+ ///
+ public string GetValue { get; private set; }
+ }
+ #endregion
+}
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinker.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinker.cs
new file mode 100644
index 0000000..6e4ed29
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinker.cs
@@ -0,0 +1,22 @@
+namespace Modbus.Net.HJ212
+{
+ ///
+ /// HJ212协议连接器
+ ///
+ public class HJ212ProtocolLinker : TcpProtocolLinker
+ {
+ public HJ212ProtocolLinker(string ip, int port) : base(ip, port)
+ {
+ }
+
+ ///
+ /// 检查接收的数据是否正确
+ ///
+ /// 接收协议的内容
+ /// 协议是否是正确的
+ public override bool? CheckRight(byte[] content)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinkerBytesExtend.cs
new file mode 100644
index 0000000..d07317f
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinkerBytesExtend.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Text;
+
+namespace Modbus.Net.HJ212
+{
+ ///
+ /// Rtu协议字节伸缩
+ ///
+ public class HJ212ProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend
+ {
+ ///
+ /// 协议扩展,协议内容发送前调用
+ ///
+ /// 扩展前的原始协议内容
+ /// 扩展后的协议内容
+ public byte[] BytesExtend(byte[] content)
+ {
+ var crc = new byte[2];
+ //Modbus/Rtu协议扩张,增加CRC校验
+ var newFormat = new byte[content.Length + 4];
+ Crc16.GetInstance().GetCRC(content, ref crc);
+ Array.Copy(content, 0, newFormat, 0, content.Length);
+ string crcString = BitConverter.ToString(crc).Replace("-", string.Empty);
+ var crcCalc = Encoding.ASCII.GetBytes(crcString);
+ Array.Copy(crcCalc, 0, newFormat, newFormat.Length - 4, 4);
+ return newFormat;
+ }
+
+ ///
+ /// 协议收缩,协议内容接收后调用
+ ///
+ /// 收缩前的完整协议内容
+ /// 收缩后的协议内容
+ public byte[] BytesDecact(byte[] content)
+ {
+ //Modbus/Rtu协议收缩,抛弃后面2个字节的内容
+ var newContent = new byte[content.Length - 2];
+ Array.Copy(content, 0, newContent, 0, newContent.Length);
+ return newContent;
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.HJ212/HJ212Utility.cs b/Modbus.Net/Modbus.Net.HJ212/HJ212Utility.cs
new file mode 100644
index 0000000..fd047b1
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/HJ212Utility.cs
@@ -0,0 +1,61 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Modbus.Net.HJ212
+{
+ public class HJ212Utility : BaseUtility, PipeUnit>
+ {
+ private static readonly ILogger logger = LogProvider.CreateLogger();
+
+ public HJ212Utility(string connectionString) : base(0, 0)
+ {
+ ConnectionString = connectionString;
+ Wrapper = new HJ212Protocol(connectionString);
+ }
+
+ public override Endian Endian => throw new NotImplementedException();
+
+ public override Task> GetDatasAsync(string startAddress, int getByteCount)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void SetConnectionType(int connectionType)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override async Task> SetDatasAsync(string startAddress, object[] setContents)
+ {
+ try
+ {
+ var writeRequestHJ212InputStruct =
+ new WriteRequestHJ212InputStruct((string)setContents[0], (string)setContents[1], (string)setContents[2], (string)setContents[3], (List>)setContents[4], (DateTime)setContents[5]);
+ var writeRequestOpcOutputStruct =
+ await
+ Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestHJ212Protocol)],
+ writeRequestHJ212InputStruct);
+ return new ReturnStruct
+ {
+ Datas = writeRequestOpcOutputStruct?.GetValue != null,
+ IsSuccess = writeRequestOpcOutputStruct?.GetValue != null,
+ ErrorCode = 0,
+ ErrorMsg = null,
+ };
+ }
+ catch (Exception e)
+ {
+ logger.LogError(e, $"OpcUtility -> SetDatas: {ConnectionString} error: {e.Message}");
+ return new ReturnStruct
+ {
+ Datas = false,
+ IsSuccess = false,
+ ErrorCode = -100,
+ ErrorMsg = e.Message
+ };
+ }
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.HJ212/Modbus.Net.HJ212.csproj b/Modbus.Net/Modbus.Net.HJ212/Modbus.Net.HJ212.csproj
new file mode 100644
index 0000000..306c693
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/Modbus.Net.HJ212.csproj
@@ -0,0 +1,39 @@
+
+
+
+ net6.0
+ 10.0
+ Modbus.Net.HJ212
+ Modbus.Net.HJ212
+ Modbus.Net.HJ212
+ 1.4.3
+ Chris L.(Luo Sheng)
+ Hangzhou Delian Science Technology Co.,Ltd.
+ Modbus.Net.HJ212
+ Modbus.Net Modbus Implementation
+ Copyright 2023 Hangzhou Delian Science Technology Co.,Ltd.
+ https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.HJ212
+ https://github.com/parallelbgls/Modbus.Net
+ git
+ hardware communicate protocol modbus Delian
+ False
+ True
+ True
+ True
+ MIT
+ README.md
+ snupkg
+
+
+
+ bin\Debug\Modbus.Net.HJ212.xml
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net.HJ212/README.md b/Modbus.Net/Modbus.Net.HJ212/README.md
new file mode 100644
index 0000000..b9b4c3d
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.HJ212/README.md
@@ -0,0 +1,7 @@
+Modbus.Net.HJ212
+===================
+[](https://www.nuget.org/packages/Modbus.Net.HJ212/)
+
+HJ212 Implementation of Modbus.Net
+
+Doc has been moved to wiki.
diff --git a/Modbus.Net/Modbus.Net.Modbus.NA200H/Modbus.Net.Modbus.NA200H.csproj b/Modbus.Net/Modbus.Net.Modbus.NA200H/Modbus.Net.Modbus.NA200H.csproj
index 1587249..b023755 100644
--- a/Modbus.Net/Modbus.Net.Modbus.NA200H/Modbus.Net.Modbus.NA200H.csproj
+++ b/Modbus.Net/Modbus.Net.Modbus.NA200H/Modbus.Net.Modbus.NA200H.csproj
@@ -6,7 +6,7 @@
Modbus.Net.Modbus.NA200H
Modbus.Net.Modbus.NA200H
Modbus.Net.Modbus.NA200H
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net.Modbus
diff --git a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/Modbus.Net.Modbus.SelfDefinedSample.csproj b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/Modbus.Net.Modbus.SelfDefinedSample.csproj
index feb9f26..d53a0e3 100644
--- a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/Modbus.Net.Modbus.SelfDefinedSample.csproj
+++ b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/Modbus.Net.Modbus.SelfDefinedSample.csproj
@@ -6,7 +6,7 @@
Modbus.Net.Modbus.SelfDefinedSample
Modbus.Net.Modbus.SelfDefinedSample
Modbus.Net.Modbus.SelfDefinedSample
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net.Modbus
diff --git a/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj b/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj
index 1e0e453..f75da4b 100644
--- a/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj
+++ b/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj
@@ -6,7 +6,7 @@
Modbus.Net.Modbus
Modbus.Net.Modbus
Modbus.Net.Modbus
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net.Modbus
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInTcpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInTcpProtocolLinker.cs
index 23f5ba2..4844887 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInTcpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInTcpProtocolLinker.cs
@@ -24,21 +24,6 @@ namespace Modbus.Net.Modbus
public ModbusAsciiInTcpProtocolLinker(string ip, int port)
: base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[0] != 0x3a) return 0;
- for (int i = 1; i < content.Length; i++)
- {
- if (content[i - 1] == 0x0D && content[i] == 0x0A) return i + 1;
- }
- return -1;
- },
- checkRightFunc: ContentCheck.LrcCheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null
- ? int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount"))
- : null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInUdpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInUdpProtocolLinker.cs
index 8324e10..bda4526 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInUdpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiInUdpProtocolLinker.cs
@@ -24,22 +24,6 @@ namespace Modbus.Net.Modbus
public ModbusAsciiInUdpProtocolLinker(string ip, int port)
: base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[0] != 0x3a) return 0;
- for (int i = 1; i < content.Length; i++)
- {
- if (content[i - 1] == 0x0D && content[i] == 0x0A)
- return i + 1;
- }
- return -1;
- },
- checkRightFunc: ContentCheck.LrcCheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null
- ? int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount"))
- : null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocolLinker.cs
index c4457f2..14cb1b7 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocolLinker.cs
@@ -15,22 +15,6 @@ namespace Modbus.Net.Modbus
public ModbusAsciiProtocolLinker(string com, int slaveAddress)
: base(com, slaveAddress)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[0] != 0x3a) return 0;
- for (int i = 1; i < content.Length; i++)
- {
- if (content[i - 1] == 0x0D && content[i] == 0x0A) return i + 1;
- }
- return -1;
- },
- checkRightFunc: ContentCheck.LrcCheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusController.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusController.cs
new file mode 100644
index 0000000..9a5887b
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusController.cs
@@ -0,0 +1,238 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Modbus.Net.Modbus
+{
+ ///
+ /// Modbus长度计算
+ ///
+ public static class ModbusLengthCalc
+ {
+ ///
+ /// Modbus Ascii协议长度计算
+ ///
+ public static Func ModbusAsciiLengthCalc => content =>
+ {
+ if (content[0] != 0x3a) return 0;
+ for (int i = 1; i < content.Length; i++)
+ {
+ if (content[i - 1] == 0x0D && content[i] == 0x0A) return i + 1;
+ }
+ return -1;
+ };
+
+ ///
+ /// Modbus Rtu协议长度计算
+ ///
+ public static Func ModbusRtuLengthCalc => content =>
+ {
+ if (content[1] > 128) return 5;
+ else if (content[1] == 5 || content[1] == 6 || content[1] == 8 || content[1] == 11 || content[1] == 15 || content[1] == 16) return 8;
+ else if (content[1] == 7) return 5;
+ else if (content[1] == 22) return 10;
+ else return DuplicateWithCount.GetDuplcateFunc(new List { 2 }, 5).Invoke(content);
+ };
+ }
+
+ ///
+ /// Modbus Ascii协议控制器
+ ///
+ public class ModbusAsciiController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 串口
+ /// 从站号
+ public ModbusAsciiController(string com, int slaveAddress) : base(
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusAsciiLengthCalc,
+ checkRightFunc: ContentCheck.LrcCheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Ascii in Tcp协议控制器
+ ///
+ public class ModbusAsciiInTcpController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusAsciiInTcpController(string ip, int port) : base(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusAsciiLengthCalc,
+ checkRightFunc: ContentCheck.LrcCheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null
+ ? int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount"))
+ : null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Ascii in Udp协议控制器
+ ///
+ public class ModbusAsciiInUdpController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusAsciiInUdpController(string ip, int port) : base(int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusAsciiLengthCalc,
+ checkRightFunc: ContentCheck.LrcCheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null
+ ? int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount"))
+ : null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Rtu协议控制器
+ ///
+ public class ModbusRtuController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 串口
+ /// 从站号
+ public ModbusRtuController(string com, int slaveAddress) : base(
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusRtuLengthCalc,
+ checkRightFunc: ContentCheck.Crc16CheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Rtu in Tcp协议控制器
+ ///
+ public class ModbusRtuInTcpController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusRtuInTcpController(string ip, int port) : base(
+ int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusRtuLengthCalc,
+ checkRightFunc: ContentCheck.Crc16CheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Rtu in Udp协议控制器
+ ///
+ public class ModbusRtuInUdpController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusRtuInUdpController(string ip, int port) : base(
+ int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FetchSleepTime")),
+ lengthCalc: ModbusLengthCalc.ModbusRtuLengthCalc,
+ checkRightFunc: ContentCheck.Crc16CheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Tcp协议控制器
+ ///
+ public class ModbusTcpController : ModbusEthMatchDirectlySendController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusTcpController(string ip, int port) : base(
+ new ICollection<(int, int)>[] { new List<(int, int)> { (0, 0), (1, 1) } },
+ lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 4, 5 }, 6),
+ waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// Modbus Udp协议控制器
+ ///
+ public class ModbusUdpController : ModbusEthMatchDirectlySendController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public ModbusUdpController(string ip, int port) : base(
+ new ICollection<(int, int)>[] { new List<(int, int)> { (0, 0), (1, 1) } },
+ lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 4, 5 }, 6),
+ waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// 匹配控制器,载入队列后直接发送
+ ///
+ public class ModbusEthMatchDirectlySendController : MatchDirectlySendController
+ {
+ ///
+ public ModbusEthMatchDirectlySendController(ICollection<(int, int)>[] keyMatches,
+ Func lengthCalc = null, Func checkRightFunc = null, int? waitingListMaxCount = null) : base(keyMatches,
+ lengthCalc, checkRightFunc, waitingListMaxCount)
+ {
+ }
+
+ ///
+ protected override MessageWaitingDef GetMessageFromWaitingList(byte[] receiveMessage)
+ {
+ MessageWaitingDef ans;
+ if (receiveMessage[0] == 0 && receiveMessage[1] == 0)
+ {
+ lock (WaitingMessages)
+ {
+ ans = WaitingMessages.FirstOrDefault();
+ }
+ }
+ else
+ {
+ var returnKey = GetKeyFromMessage(receiveMessage);
+ lock (WaitingMessages)
+ {
+ ans = WaitingMessages.FirstOrDefault(p => returnKey.HasValue && p.Key == returnKey.Value.Item2);
+ }
+ }
+ return ans;
+ }
+ }
+}
+
+
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInTcpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInTcpProtocolLinker.cs
index ae8d1d5..270b72c 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInTcpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInTcpProtocolLinker.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Modbus.Net.Modbus
+namespace Modbus.Net.Modbus
{
///
/// Modbus/Rtu协议连接器Tcp透传
@@ -24,19 +22,6 @@ namespace Modbus.Net.Modbus
public ModbusRtuInTcpProtocolLinker(string ip, int port)
: base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(
- int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[1] > 128) return 5;
- else if (content[1] == 5 || content[1] == 6 || content[1] == 15 || content[1] == 16 || content[1] == 21) return 8;
- else return DuplicateWithCount.GetDuplcateFunc(new List { 2 }, 5).Invoke(content);
- },
- checkRightFunc: ContentCheck.Crc16CheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInUdpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInUdpProtocolLinker.cs
index b4365b2..d11f31f 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInUdpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuInUdpProtocolLinker.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Modbus.Net.Modbus
+namespace Modbus.Net.Modbus
{
///
/// Modbus/Rtu协议连接器Udp透传
@@ -24,19 +22,6 @@ namespace Modbus.Net.Modbus
public ModbusRtuInUdpProtocolLinker(string ip, int port)
: base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(
- int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[1] > 128) return 5;
- else if (content[1] == 5 || content[1] == 6 || content[1] == 15 || content[1] == 16 || content[1] == 21) return 8;
- else return DuplicateWithCount.GetDuplcateFunc(new List { 2 }, 5).Invoke(content);
- },
- checkRightFunc: ContentCheck.Crc16CheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocolLinker.cs
index 859f32e..f9b3953 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocolLinker.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Modbus.Net.Modbus
+namespace Modbus.Net.Modbus
{
///
/// Modbus/Rtu协议连接器
@@ -15,21 +13,6 @@ namespace Modbus.Net.Modbus
public ModbusRtuProtocolLinker(string com, int slaveAddress)
: base(com, slaveAddress)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[1] > 128) return 5;
- else if (content[1] == 5 || content[1] == 6 || content[1] == 8 || content[1] == 11 || content[1] == 15 || content[1] == 16) return 8;
- else if (content[1] == 7) return 5;
- else if (content[1] == 22) return 10;
- else return DuplicateWithCount.GetDuplcateFunc(new List { 2 }, 5).Invoke(content);
- },
- checkRightFunc: ContentCheck.Crc16CheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpMatchDirectlySendController.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpMatchDirectlySendController.cs
deleted file mode 100644
index 3cfd997..0000000
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpMatchDirectlySendController.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Modbus.Net
-{
- ///
- /// 匹配控制器,载入队列后直接发送
- ///
- public class ModbusTcpMatchDirectlySendController : MatchDirectlySendController
- {
- ///
- public ModbusTcpMatchDirectlySendController(ICollection<(int, int)>[] keyMatches,
- Func lengthCalc = null, Func checkRightFunc = null, int? waitingListMaxCount = null) : base(keyMatches,
- lengthCalc, checkRightFunc, waitingListMaxCount)
- {
- }
-
- ///
- protected override MessageWaitingDef GetMessageFromWaitingList(byte[] receiveMessage)
- {
- MessageWaitingDef ans;
- if (receiveMessage[0] == 0 && receiveMessage[1] == 0)
- {
- lock (WaitingMessages)
- {
- ans = WaitingMessages.FirstOrDefault();
- }
- }
- else
- {
- var returnKey = GetKeyFromMessage(receiveMessage);
- lock (WaitingMessages)
- {
- ans = WaitingMessages.FirstOrDefault(p => returnKey.HasValue && p.Key == returnKey.Value.Item2);
- }
- }
- return ans;
- }
- }
-}
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocolLinker.cs
index 949f8b6..4f678e0 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocolLinker.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Modbus.Net.Modbus
+namespace Modbus.Net.Modbus
{
///
/// Modbus/Tcp协议连接器
@@ -23,13 +21,6 @@ namespace Modbus.Net.Modbus
/// 端口
public ModbusTcpProtocolLinker(string ip, int port) : base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new ModbusTcpMatchDirectlySendController(
- new ICollection<(int, int)>[] { new List<(int, int)> { (0, 0), (1, 1) } },
- lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 4, 5 }, 6),
- waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusUdpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusUdpProtocolLinker.cs
index a917e9a..7bd93db 100644
--- a/Modbus.Net/Modbus.Net.Modbus/ModbusUdpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Modbus/ModbusUdpProtocolLinker.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Modbus.Net.Modbus
+namespace Modbus.Net.Modbus
{
///
/// Modbus/Udp协议连接器
@@ -23,13 +21,6 @@ namespace Modbus.Net.Modbus
/// 端口
public ModbusUdpProtocolLinker(string ip, int port) : base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new ModbusTcpMatchDirectlySendController(
- new ICollection<(int, int)>[] { new List<(int, int)> { (0, 0), (1, 1) } },
- lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 4, 5 }, 6),
- waitingListMaxCount: ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Opc/Modbus.Net.Opc.csproj b/Modbus.Net/Modbus.Net.Opc/Modbus.Net.Opc.csproj
index e8d15dc..9068345 100644
--- a/Modbus.Net/Modbus.Net.Opc/Modbus.Net.Opc.csproj
+++ b/Modbus.Net/Modbus.Net.Opc/Modbus.Net.Opc.csproj
@@ -6,7 +6,7 @@
Modbus.Net.Opc
Modbus.Net.Opc
Modbus.Net.Opc
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net.Opc
diff --git a/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj b/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj
index 3ef6ebb..6cb3fd7 100644
--- a/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj
+++ b/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj
@@ -6,7 +6,7 @@
Modbus.Net.Siemens
Modbus.Net.Siemens
Modbus.Net.Siemens
- 1.4.2
+ 1.4.3
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
Modbus.Net Siemens Profinet Implementation
diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensController.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensController.cs
new file mode 100644
index 0000000..e0bb902
--- /dev/null
+++ b/Modbus.Net/Modbus.Net.Siemens/SiemensController.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+
+namespace Modbus.Net.Siemens
+{
+ ///
+ /// 西门子Ppi协议控制器
+ ///
+ public class SiemensPpiController : FifoController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// 串口
+ /// 从站号
+ public SiemensPpiController(string com, int slaveAddress) : base(
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
+ lengthCalc: content =>
+ {
+ if (content[0] == 0x10)
+ return 6;
+ else if (content[0] == 0xE5)
+ return 1;
+ else
+ return DuplicateWithCount.GetDuplcateFunc(new List { 1 }, 6)(content);
+ },
+ checkRightFunc: ContentCheck.FcsCheckRight,
+ waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+
+ ///
+ /// 西门子Tcp协议控制器
+ ///
+ public class SiemensTcpController : MatchDirectlySendController
+ {
+ ///
+ /// 构造函数
+ ///
+ /// ip地址
+ /// 端口号
+ public SiemensTcpController(string ip, int port) : base(
+ new ICollection<(int, int)>[] { new List<(int, int)> { (11, 11), (12, 12) } },
+ lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 2, 3 }, 0),
+ waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
+ int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
+ null
+ )
+ { }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocolLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocolLinker.cs
index 7c25c67..60505d4 100644
--- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocolLinker.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
@@ -23,22 +22,6 @@ namespace Modbus.Net.Siemens
: null
)
{
- ((IConnectorWithController)BaseConnector).AddController(new FifoController(
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime")),
- lengthCalc: content =>
- {
- if (content[0] == 0x10)
- return 6;
- else if (content[0] == 0xE5)
- return 1;
- else
- return DuplicateWithCount.GetDuplcateFunc(new List { 1 }, 6)(content);
- },
- checkRightFunc: ContentCheck.FcsCheckRight,
- waitingListMaxCount: ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocolLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocolLinker.cs
index 25234aa..a91160b 100644
--- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocolLinker.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
namespace Modbus.Net.Siemens
{
@@ -25,13 +24,6 @@ namespace Modbus.Net.Siemens
public SiemensTcpProtocolLinker(string ip, int port)
: base(ip, port)
{
- ((IConnectorWithController)BaseConnector).AddController(new MatchDirectlySendController(
- new ICollection<(int, int)>[] { new List<(int, int)> { (11, 11), (12, 12) } },
- lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List { 2, 3 }, 0),
- waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ?
- int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) :
- null
- ));
}
///
diff --git a/Modbus.Net/Modbus.Net.sln b/Modbus.Net/Modbus.Net.sln
index 92c3165..5b176af 100644
--- a/Modbus.Net/Modbus.Net.sln
+++ b/Modbus.Net/Modbus.Net.sln
@@ -45,6 +45,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Technosoftware.DaAeHdaClien
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Technosoftware.DaAeHdaClient.Com", "..\Technosoftware\DaAeHdaClient.Com\Technosoftware.DaAeHdaClient.Com.csproj", "{ACAF0A16-FC51-4369-BFA8-484FF20707D7}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.HJ212", "Modbus.Net.HJ212\Modbus.Net.HJ212.csproj", "{057644EF-1407-4C2B-808A-AEF0F2979EA8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modbus.Net.CodeGenerator", "Modbus.Net.CodeGenerator\Modbus.Net.CodeGenerator.csproj", "{D3210531-BA79-49B2-9F99-09FD0E1627B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MachineJob.CodeGenerator", "..\Samples\MachineJob.CodeGenerator\MachineJob.CodeGenerator.csproj", "{7337BC9A-ED07-463D-8FCD-A82896CEC6BE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -181,6 +187,30 @@ Global
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|Any CPU.Build.0 = Release|Any CPU
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|x64.ActiveCfg = Release|x64
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|x64.Build.0 = Release|x64
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|x64.Build.0 = Debug|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|x64.ActiveCfg = Release|Any CPU
+ {057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|x64.Build.0 = Release|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Debug|x64.Build.0 = Debug|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Release|x64.ActiveCfg = Release|Any CPU
+ {D3210531-BA79-49B2-9F99-09FD0E1627B6}.Release|x64.Build.0 = Release|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Debug|x64.Build.0 = Debug|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Release|x64.ActiveCfg = Release|Any CPU
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -191,6 +221,7 @@ Global
{1857DA63-3335-428F-84D8-1FA4F8178643} = {3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}
{AA3A42D2-0502-41D3-929A-BAB729DF07D6} = {3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}
{414956B8-DBD4-414C-ABD3-565580739646} = {3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}
+ {7337BC9A-ED07-463D-8FCD-A82896CEC6BE} = {3597B5C5-45B9-4ECB-92A3-D0FFBE47920A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF00D64E-3C70-474A-8A81-E9E48017C4B5}
diff --git a/Modbus.Net/Modbus.Net/Connector/BaseConnector.cs b/Modbus.Net/Modbus.Net/Connector/BaseConnector.cs
index 286cd74..3a315c9 100644
--- a/Modbus.Net/Modbus.Net/Connector/BaseConnector.cs
+++ b/Modbus.Net/Modbus.Net/Connector/BaseConnector.cs
@@ -1,102 +1,12 @@
using Microsoft.Extensions.Logging;
-using Nito.AsyncEx;
-using System;
using System.Threading.Tasks;
namespace Modbus.Net
{
///
- public abstract class BaseConnector : BaseConnector
+ public abstract partial class BaseConnector : BaseConnector
{
- private static readonly ILogger logger = LogProvider.CreateLogger();
-
- ///
- /// 发送锁
- ///
- protected abstract AsyncLock Lock { get; }
-
- ///
- /// 是否为全双工
- ///
- public bool IsFullDuplex { get; }
-
- ///
- /// 发送超时时间
- ///
- protected abstract int TimeoutTime { get; set; }
-
- ///
- /// 构造器
- ///
- /// 发送超时时间
- /// 是否为全双工
- protected BaseConnector(int timeoutTime = 10000, bool isFullDuplex = false)
- {
- IsFullDuplex = isFullDuplex;
- if (timeoutTime < -1) timeoutTime = -1;
- TimeoutTime = timeoutTime;
- }
-
- ///
- public override async Task SendMsgAsync(byte[] message)
- {
- var ans = await SendMsgInner(message);
- if (ans == null) return new byte[0];
- return ans.ReceiveMessage;
- }
-
- ///
- /// 发送内部
- ///
- /// 发送的信息
- /// 是否为重发消息
- /// 发送信息的定义
- protected async Task SendMsgInner(byte[] message, bool repeat = false)
- {
- IDisposable asyncLock = null;
- try
- {
- if (!Controller.IsSending)
- {
- Controller.SendStart();
- }
- var messageSendingdef = Controller.AddMessage(message);
- if (messageSendingdef != null)
- {
- if (!IsFullDuplex)
- {
- asyncLock = await Lock.LockAsync();
- }
- var success = messageSendingdef.SendMutex.WaitOne(TimeoutTime);
- if (success)
- {
- await SendMsgWithoutConfirm(message);
- success = messageSendingdef.ReceiveMutex.WaitOne(TimeoutTime);
- if (success)
- {
- if (!repeat && messageSendingdef.ReceiveMessage == null)
- {
- asyncLock?.Dispose();
- return await SendMsgInner(message, true);
- }
- return messageSendingdef;
- }
- }
- Controller.ForceRemoveWaitingMessage(messageSendingdef);
- }
- logger.LogInformation("Message is waiting in {0}. Cancel!", ConnectionToken);
- return null;
- }
- catch (Exception e)
- {
- logger.LogError(e, "Connector {0} Send Error.", ConnectionToken);
- return null;
- }
- finally
- {
- asyncLock?.Dispose();
- }
- }
+ private static readonly ILogger logger = LogProvider.CreateLogger();
}
///
diff --git a/Modbus.Net/Modbus.Net/Connector/ComConnector.cs b/Modbus.Net/Modbus.Net/Connector/ComConnector.cs
index 43900ce..5a149f7 100644
--- a/Modbus.Net/Modbus.Net/Connector/ComConnector.cs
+++ b/Modbus.Net/Modbus.Net/Connector/ComConnector.cs
@@ -82,10 +82,11 @@ namespace Modbus.Net
/// 获取线程
///
private Task _receiveThread;
+
///
- /// 获取线程关闭
+ /// 终止获取线程
///
- private bool _taskCancel = false;
+ private CancellationTokenSource _receiveThreadCancel;
///
/// 缓冲的字节流
@@ -276,24 +277,23 @@ namespace Modbus.Net
// Release managed resources
}
// Release unmanaged resources
- if (SerialPort != null)
+ Controller?.SendStop();
+ ReceiveMsgThreadStop();
+ Linkers?.Remove((_slave, _com));
+ logger.LogInformation("Com connector {ConnectionToken} Removed", _com);
+ if (Linkers?.Count(p => p.Item2 == _com) == 0)
{
- Linkers.Remove((_slave, _com));
- logger.LogInformation("Com connector {ConnectionToken} Removed", _com);
- if (Linkers.Count(p => p.Item2 == _com) == 0)
+ if (SerialPort?.IsOpen == true)
+ {
+ SerialPort?.Close();
+ }
+ SerialPort?.Dispose();
+ logger.LogInformation("Com interface {Com} Disposed", _com);
+ if (Connectors.ContainsKey(_com))
{
- if (SerialPort.IsOpen)
- {
- SerialPort.Close();
- }
- SerialPort.Dispose();
- logger.LogInformation("Com interface {Com} Disposed", _com);
- Controller.SendStop();
- Controllers.Remove(_com);
Connectors[_com] = null;
Connectors.Remove(_com);
- ReceiveMsgThreadStop();
- }
+ }
}
}
@@ -366,7 +366,7 @@ namespace Modbus.Net
{
lock (SerialPort)
{
- _taskCancel = false;
+ ReceiveMsgThreadStop();
SerialPort.Open();
ReceiveMsgThreadStart();
Controller.SendStart();
@@ -484,7 +484,7 @@ namespace Modbus.Net
message.Length);
logger.LogDebug(
$"Com client {ConnectionToken} send msg: {String.Concat(message.Select(p => " " + p.ToString("X2")))}");
- await Task.Run(() => SerialPort.Write(message, 0, message.Length));
+ await Task.Run(() => SerialPort?.Write(message, 0, message.Length));
}
catch (Exception err)
{
@@ -495,20 +495,57 @@ namespace Modbus.Net
}
///
- protected override void ReceiveMsgThreadStart()
+ protected override async void ReceiveMsgThreadStart()
{
- _receiveThread = Task.Run(ReceiveMessage);
+ if (_receiveThread == null)
+ {
+ _receiveThreadCancel = new CancellationTokenSource();
+ _receiveThread = Task.Run(async ()=>await ReceiveMessage(_receiveThreadCancel.Token), _receiveThreadCancel.Token);
+ try
+ {
+ await _receiveThread;
+ }
+ catch (OperationCanceledException)
+ { }
+ finally
+ {
+ _receiveThreadCancel.Dispose();
+ _receiveThreadCancel = null;
+ }
+ }
}
///
protected override void ReceiveMsgThreadStop()
{
- _taskCancel = true;
+ _receiveThreadCancel?.Cancel();
+ if (_receiveThread != null)
+ {
+ while (!_receiveThread.IsCanceled)
+ {
+ Thread.Sleep(10);
+ }
+ _receiveThread.Dispose();
+ _receiveThread = null;
+ }
+ CacheClear();
+ Controller?.Clear();
}
- private async Task ReceiveMessage()
+ private void CacheClear()
{
- while (!_taskCancel)
+ if (CacheBytes != null)
+ {
+ lock (CacheBytes)
+ {
+ CacheBytes.Clear();
+ }
+ }
+ }
+
+ private async Task ReceiveMessage(CancellationToken token)
+ {
+ while (true)
{
try
{
@@ -533,10 +570,7 @@ namespace Modbus.Net
CacheBytes.Count);
logger.LogError(
$"Com client {ConnectionToken} cached msg: {string.Concat(CacheBytes.Select(p => " " + p.ToString("X2")))}");
- lock (CacheBytes)
- {
- CacheBytes.Clear();
- }
+ CacheClear();
}
else
{
@@ -570,8 +604,13 @@ namespace Modbus.Net
}
catch (Exception e)
{
+ CacheClear();
logger.LogError(e, "Com client {ConnectionToken} read msg error", ConnectionToken);
}
+ if (token.IsCancellationRequested)
+ {
+ token.ThrowIfCancellationRequested();
+ }
}
}
diff --git a/Modbus.Net/Modbus.Net/Connector/EventHandlerConnector.cs b/Modbus.Net/Modbus.Net/Connector/EventHandlerConnector.cs
index 8068bfe..5447680 100644
--- a/Modbus.Net/Modbus.Net/Connector/EventHandlerConnector.cs
+++ b/Modbus.Net/Modbus.Net/Connector/EventHandlerConnector.cs
@@ -1,106 +1,17 @@
using DotNetty.Transport.Channels;
using Microsoft.Extensions.Logging;
-using Nito.AsyncEx;
using System;
using System.Threading.Tasks;
namespace Modbus.Net
{
///
- public abstract class EventHandlerConnector : EventHandlerConnector
+ public abstract partial class EventHandlerConnector : EventHandlerConnector
{
- ///
- public override bool IsSharable => true;
-
private static readonly ILogger logger = LogProvider.CreateLogger();
- ///
- /// 发送锁
- ///
- protected abstract AsyncLock Lock { get; }
-
- ///
- /// 是否为全双工
- ///
- public bool IsFullDuplex { get; }
-
- ///
- /// 发送超时时间
- ///
- protected abstract int TimeoutTime { get; set; }
-
- ///
- /// 构造器
- ///
- /// 发送超时时间
- /// 是否为全双工
- protected EventHandlerConnector(int timeoutTime = 10000, bool isFullDuplex = true)
- {
- IsFullDuplex = isFullDuplex;
- if (timeoutTime < -1) timeoutTime = -1;
- TimeoutTime = timeoutTime;
- }
-
- ///
- public override async Task SendMsgAsync(byte[] message)
- {
- var ans = await SendMsgInner(message);
- if (ans == null) return new byte[0];
- return ans.ReceiveMessage;
- }
-
- ///
- /// 发送内部
- ///
- /// 发送的信息
- /// 是否为重发消息
- /// 发送信息的定义
- protected async Task SendMsgInner(byte[] message, bool repeat = false)
- {
- IDisposable asyncLock = null;
- try
- {
- if (!Controller.IsSending)
- {
- Controller.SendStart();
- }
- var messageSendingdef = Controller.AddMessage(message);
- if (messageSendingdef != null)
- {
- if (!IsFullDuplex)
- {
- asyncLock = await Lock.LockAsync();
- }
- var success = messageSendingdef.SendMutex.WaitOne(TimeoutTime);
- if (success)
- {
- await SendMsgWithoutConfirm(message);
- success = messageSendingdef.ReceiveMutex.WaitOne(TimeoutTime);
- if (success)
- {
- if (!repeat && messageSendingdef.ReceiveMessage == null)
- {
- asyncLock?.Dispose();
- return await SendMsgInner(message, true);
- }
- return messageSendingdef;
- }
- }
- Controller.ForceRemoveWaitingMessage(messageSendingdef);
- }
- logger.LogInformation("Message is waiting in {0}. Cancel!", ConnectionToken);
- return null;
- }
- catch (Exception e)
- {
- logger.LogError(e, "Connector {0} Send Error.", ConnectionToken);
- return null;
- }
- finally
- {
- asyncLock?.Dispose();
- }
- }
+ ///
+ public override bool IsSharable => true;
///
public override void ChannelReadComplete(IChannelHandlerContext ctx)
diff --git a/Modbus.Net/Modbus.Net/Controller/BaseController.cs b/Modbus.Net/Modbus.Net/Controller/BaseController.cs
index e33b5ff..bf784f6 100644
--- a/Modbus.Net/Modbus.Net/Controller/BaseController.cs
+++ b/Modbus.Net/Modbus.Net/Controller/BaseController.cs
@@ -1,3 +1,4 @@
+using Quartz.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -24,7 +25,9 @@ namespace Modbus.Net
///
/// Ϣά߳Ƿ
///
- public virtual bool IsSending => SendingThread.Status.Equals(TaskStatus.Running);
+ public virtual bool IsSending => SendingThread != null;
+
+ private CancellationTokenSource _sendingThreadCancel;
///
/// зλú
@@ -68,26 +71,55 @@ namespace Modbus.Net
///
/// Ϣʵڲ
///
- protected abstract void SendingMessageControlInner();
+ protected abstract void SendingMessageControlInner(CancellationToken token);
///
- public abstract void SendStop();
-
- ///
- public virtual void SendStart()
+ public virtual void SendStop()
{
- if (SendingThread == null)
+ Clear();
+ _sendingThreadCancel?.Cancel();
+ if (SendingThread != null)
{
- SendingThread = Task.Run(() => SendingMessageControlInner());
+ while (!SendingThread.IsCanceled)
+ {
+ Thread.Sleep(10);
+ }
+ SendingThread.Dispose();
+ SendingThread = null;
+ }
+ Clear();
+ }
+
+ ///
+ public virtual async void SendStart()
+ {
+ if (!IsSending)
+ {
+ _sendingThreadCancel = new CancellationTokenSource();
+ SendingThread = Task.Run(() => SendingMessageControlInner(_sendingThreadCancel.Token), _sendingThreadCancel.Token);
+ try
+ {
+ await SendingThread;
+ }
+ catch (OperationCanceledException)
+ { }
+ finally
+ {
+ _sendingThreadCancel.Dispose();
+ _sendingThreadCancel = null;
+ }
}
}
///
public void Clear()
{
- lock (WaitingMessages)
+ if (WaitingMessages != null)
{
- WaitingMessages.Clear();
+ lock (WaitingMessages)
+ {
+ WaitingMessages.Clear();
+ }
}
}
@@ -191,13 +223,7 @@ namespace Modbus.Net
if (def != null)
{
def.ReceiveMessage = message.Item1;
- lock (WaitingMessages)
- {
- if (WaitingMessages.IndexOf(def) >= 0)
- {
- WaitingMessages.Remove(def);
- }
- }
+ ForceRemoveWaitingMessage(def);
def.ReceiveMutex.Set();
ans.Add((message.Item1, true));
}
diff --git a/Modbus.Net/Modbus.Net/Controller/FifoController.cs b/Modbus.Net/Modbus.Net/Controller/FifoController.cs
index 81a91e2..1e1f042 100644
--- a/Modbus.Net/Modbus.Net/Controller/FifoController.cs
+++ b/Modbus.Net/Modbus.Net/Controller/FifoController.cs
@@ -14,8 +14,6 @@ namespace Modbus.Net
private MessageWaitingDef _currentSendingPos;
- private bool _taskCancel = false;
-
private int _waitingListMaxCount;
///
@@ -38,9 +36,9 @@ namespace Modbus.Net
}
///
- protected override void SendingMessageControlInner()
+ protected override void SendingMessageControlInner(CancellationToken token)
{
- while (!_taskCancel)
+ while (true)
{
if (AcquireTime > 0)
{
@@ -79,24 +77,14 @@ namespace Modbus.Net
catch (Exception e)
{
logger.LogError(e, "Controller throws exception");
- _taskCancel = true;
+ SendStop();
}
}
+ if (token.IsCancellationRequested)
+ {
+ token.ThrowIfCancellationRequested();
+ }
}
- Clear();
- }
-
- ///
- public override void SendStart()
- {
- _taskCancel = false;
- base.SendStart();
- }
-
- ///
- public override void SendStop()
- {
- _taskCancel = true;
}
///
@@ -123,7 +111,7 @@ namespace Modbus.Net
{
return false;
}
- if (_taskCancel)
+ if (!IsSending)
{
return false;
}
diff --git a/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs b/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs
index b6e1627..73810d9 100644
--- a/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs
+++ b/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
namespace Modbus.Net
{
@@ -32,7 +33,7 @@ namespace Modbus.Net
}
///
- protected override void SendingMessageControlInner()
+ protected override void SendingMessageControlInner(CancellationToken token)
{
//empty
}
diff --git a/Modbus.Net/Modbus.Net/Helper/ControllerHelper.cs b/Modbus.Net/Modbus.Net/Helper/ControllerHelper.cs
new file mode 100644
index 0000000..d9942bf
--- /dev/null
+++ b/Modbus.Net/Modbus.Net/Helper/ControllerHelper.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Reflection;
+
+namespace Modbus.Net
+{
+ ///
+ /// ProtocolLinker添加Controller扩展方法
+ ///
+ public static class ControllerHelper
+ {
+ ///
+ /// 添加一个Controller
+ ///
+ /// ProtocolLinker实例
+ /// 参数
+ /// Connector实例
+ /// 如果没有发现控制器,报错
+ public static void AddController(this IProtocolLinker protocolLinker, object[] constructorParams, IConnector connector)
+ {
+ IController controller = null;
+ var assemblies = AssemblyHelper.GetAllLibraryAssemblies();
+ string controllerName = protocolLinker.GetType().Name.Substring(0, protocolLinker.GetType().Name.Length - 14) + "Controller";
+ foreach (var assembly in assemblies)
+ {
+ var controllerType = assembly.GetType(assembly.GetName().Name + "." + controllerName);
+ if (controllerType != null)
+ {
+ controller = assembly.CreateInstance(controllerType.FullName, true, BindingFlags.Default, null, constructorParams, null, null) as IController;
+ break;
+ }
+ }
+ if (controller != null)
+ {
+ ((IConnectorWithController)connector).AddController(controller);
+ return;
+ }
+ throw new NotImplementedException(controllerName + " not found exception");
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net/Linker/ComProtocolLinker.cs b/Modbus.Net/Modbus.Net/Linker/ComProtocolLinker.cs
index fca0bed..361c6b6 100644
--- a/Modbus.Net/Modbus.Net/Linker/ComProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net/Linker/ComProtocolLinker.cs
@@ -31,6 +31,7 @@ namespace Modbus.Net
connectionTimeout = int.Parse(connectionTimeout != null ? connectionTimeout.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "ConnectionTimeout"));
isFullDuplex = bool.Parse(isFullDuplex != null ? isFullDuplex.ToString() : null ?? ConfigurationReader.GetValue("COM:" + com, "FullDuplex"));
BaseConnector = new ComConnector(com + ":" + slaveAddress, baudRate.Value, parity.Value, stopBits.Value, dataBits.Value, handshake.Value, connectionTimeout.Value, isFullDuplex.Value);
+ this.AddController(new object[2] { com, slaveAddress }, BaseConnector);
}
}
}
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net/Linker/TcpProtocolLinker.cs b/Modbus.Net/Modbus.Net/Linker/TcpProtocolLinker.cs
index d476f85..4ef9b99 100644
--- a/Modbus.Net/Modbus.Net/Linker/TcpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net/Linker/TcpProtocolLinker.cs
@@ -18,6 +18,7 @@
isFullDuplex = bool.Parse(isFullDuplex != null ? isFullDuplex.ToString() : null ?? ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FullDuplex"));
//初始化连接对象
BaseConnector = new TcpConnector(ip, port, connectionTimeout.Value, isFullDuplex.Value);
+ this.AddController(new object[2] { ip, port }, BaseConnector);
}
}
}
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net/Linker/UdpProtocolLinker.cs b/Modbus.Net/Modbus.Net/Linker/UdpProtocolLinker.cs
index 7496341..6fb4d93 100644
--- a/Modbus.Net/Modbus.Net/Linker/UdpProtocolLinker.cs
+++ b/Modbus.Net/Modbus.Net/Linker/UdpProtocolLinker.cs
@@ -18,6 +18,7 @@
isFullDuplex = bool.Parse(isFullDuplex != null ? isFullDuplex.ToString() : null ?? ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FullDuplex"));
//初始化连接对象
BaseConnector = new UdpConnector(ip, port, connectionTimeout.Value, isFullDuplex.Value);
+ this.AddController(new object[2] { ip, port }, BaseConnector);
}
}
}
\ No newline at end of file
diff --git a/Modbus.Net/Modbus.Net/Modbus.Net.csproj b/Modbus.Net/Modbus.Net/Modbus.Net.csproj
index ef5cb65..0be88e2 100644
--- a/Modbus.Net/Modbus.Net/Modbus.Net.csproj
+++ b/Modbus.Net/Modbus.Net/Modbus.Net.csproj
@@ -6,7 +6,7 @@
Modbus.Net
Modbus.Net
Modbus.Net
- 1.4.2
+ 1.4.3
Modbus.Net
Chris L.(Luo Sheng)
Hangzhou Delian Science Technology Co.,Ltd.
@@ -34,18 +34,21 @@
PreserveNewest
-
+
-
+
-
+
+
+
+
\ No newline at end of file
diff --git a/Samples/MachineJob.CodeGenerator/DatabaseWriteEntityCodeGenerator.cs b/Samples/MachineJob.CodeGenerator/DatabaseWriteEntityCodeGenerator.cs
new file mode 100644
index 0000000..883dcfd
--- /dev/null
+++ b/Samples/MachineJob.CodeGenerator/DatabaseWriteEntityCodeGenerator.cs
@@ -0,0 +1,33 @@
+using Microsoft.CodeAnalysis;
+
+namespace Modbus.Net.CodeGenerator
+{
+ [Generator]
+ public class DatabaseWriteEntityCodeGenerator : ISourceGenerator
+ {
+ public void Execute(GeneratorExecutionContext context)
+ {
+ var content = "";
+ for (int i = 1; i <= 10; i++)
+ {
+ content += $@"public double? Value{i} {{ get; set; }}
+ ";
+ }
+ var source = $@"
+
+namespace MachineJob
+{{
+ public partial class DatabaseWriteEntity
+ {{
+ {content}
+ }}
+}}";
+ context.AddSource("DatabaseWriteContent.g.cs", source);
+ }
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+
+ }
+ }
+}
diff --git a/Samples/MachineJob.CodeGenerator/MachineJob.CodeGenerator.csproj b/Samples/MachineJob.CodeGenerator/MachineJob.CodeGenerator.csproj
new file mode 100644
index 0000000..7ae8fe2
--- /dev/null
+++ b/Samples/MachineJob.CodeGenerator/MachineJob.CodeGenerator.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Library
+ netstandard2.0
+ 9.0
+ true
+
+
+
+
+
+
+
+
diff --git a/Samples/MachineJob/DatabaseWrite.cs b/Samples/MachineJob/DatabaseWrite.cs
index 7e0d87c..2faebfe 100644
--- a/Samples/MachineJob/DatabaseWrite.cs
+++ b/Samples/MachineJob/DatabaseWrite.cs
@@ -24,20 +24,11 @@ namespace MachineJob
}
[Table(name: "databasewrites")]
- public class DatabaseWriteEntity
+ public partial class DatabaseWriteEntity
{
[Key]
public int Id { get; set; }
- public double? Value1 { get; set; }
- public double? Value2 { get; set; }
- public double? Value3 { get; set; }
- public double? Value4 { get; set; }
- public double? Value5 { get; set; }
- public double? Value6 { get; set; }
- public double? Value7 { get; set; }
- public double? Value8 { get; set; }
- public double? Value9 { get; set; }
- public double? Value10 { get; set; }
+
public DateTime UpdateTime { get; set; }
}
}
diff --git a/Samples/MachineJob/MachineJob.csproj b/Samples/MachineJob/MachineJob.csproj
index 2b490b0..70fedb1 100644
--- a/Samples/MachineJob/MachineJob.csproj
+++ b/Samples/MachineJob/MachineJob.csproj
@@ -8,17 +8,18 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
true
-
+
-
-
+
+
+
@@ -26,5 +27,6 @@
+
diff --git a/Samples/MachineJob/Program.cs b/Samples/MachineJob/Program.cs
index 8ee1307..059cccd 100644
--- a/Samples/MachineJob/Program.cs
+++ b/Samples/MachineJob/Program.cs
@@ -16,7 +16,9 @@ IHost host = Host.CreateDefaultBuilder(args).UseWindowsService()
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
+ .Enrich.FromLogContext()
.WriteTo.Console()
+ .WriteTo.File("Log\\log..txt", Serilog.Events.LogEventLevel.Error, shared: true, rollingInterval: RollingInterval.Day)
.CreateLogger();
var loggerFactory = new LoggerFactory().AddSerilog(Log.Logger);
diff --git a/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj b/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj
index 2c3705c..807224c 100644
--- a/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj
+++ b/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj
@@ -22,10 +22,13 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+