NoResponseController
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -16,7 +17,17 @@ namespace Modbus.Net.HJ212
|
||||
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"));
|
||||
var splitPos = ip.IndexOf(':');
|
||||
if (splitPos > -1)
|
||||
{
|
||||
string realIp = ip.Substring(0, splitPos);
|
||||
string port = ip.Substring(splitPos + 1);
|
||||
ProtocolLinker = new HJ212ProtocolLinker(realIp, int.Parse(port));
|
||||
}
|
||||
else
|
||||
{
|
||||
ProtocolLinker = new HJ212ProtocolLinker(ip, int.Parse(ConfigurationReader.GetValueDirect("TCP:" + ip, "HJ212Port") ?? ConfigurationReader.GetValueDirect("TCP:Modbus", "HJ212Port") ?? "443"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,7 +54,7 @@ namespace Modbus.Net.HJ212
|
||||
public override byte[] Format(IInputStruct message)
|
||||
{
|
||||
var r_message = (WriteRequestHJ212InputStruct)message;
|
||||
string formatMessage = "##0633";
|
||||
string formatMessage = "";
|
||||
formatMessage += "QN=" + r_message.QN + ";";
|
||||
formatMessage += "ST=" + r_message.ST + ";";
|
||||
formatMessage += "CN=" + r_message.CN + ";";
|
||||
@@ -61,7 +72,6 @@ namespace Modbus.Net.HJ212
|
||||
formatMessage += ";";
|
||||
}
|
||||
formatMessage = formatMessage[..^1];
|
||||
formatMessage += "&&";
|
||||
return Encoding.ASCII.GetBytes(formatMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,21 @@ namespace Modbus.Net.HJ212
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
var crc = new byte[2];
|
||||
var newFormat = new byte[content.Length + 12];
|
||||
Array.Copy(content, 0, newFormat, 6, content.Length);
|
||||
//表头长度扩张
|
||||
var length = content.Length;
|
||||
string lengthString = length.ToString("0000");
|
||||
lengthString = "##" + lengthString;
|
||||
var lengthCalc = Encoding.ASCII.GetBytes(lengthString);
|
||||
Array.Copy(lengthCalc, 0, newFormat, 0, 6);
|
||||
//Modbus/Rtu协议扩张,增加CRC校验
|
||||
var newFormat = new byte[content.Length + 4];
|
||||
var crc = new byte[2];
|
||||
Crc16.GetInstance().GetCRC(content, ref crc);
|
||||
Array.Copy(content, 0, newFormat, 0, content.Length);
|
||||
string crcString = BitConverter.ToString(crc).Replace("-", string.Empty);
|
||||
crcString = "&&" + crcString;
|
||||
var crcCalc = Encoding.ASCII.GetBytes(crcString);
|
||||
Array.Copy(crcCalc, 0, newFormat, newFormat.Length - 4, 4);
|
||||
Array.Copy(crcCalc, 0, newFormat, newFormat.Length - 6, 6);
|
||||
return newFormat;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace Modbus.Net.Modbus
|
||||
/// <returns>校验是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
var contentString = Encoding.ASCII.GetString(content);
|
||||
if (byte.Parse(contentString.Substring(3, 2)) > 127)
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace Modbus.Net.Modbus
|
||||
/// <returns>校验是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
var contentString = Encoding.ASCII.GetString(content);
|
||||
if (byte.Parse(contentString.Substring(3, 2)) > 127)
|
||||
|
||||
@@ -24,8 +24,7 @@ namespace Modbus.Net.Modbus
|
||||
/// <returns>校验是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
var contentString = Encoding.ASCII.GetString(content);
|
||||
if (byte.Parse(contentString.Substring(3, 2)) > 127)
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker的CheckRight不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
if (content[1] > 127)
|
||||
throw new ModbusProtocolErrorException(content[2]);
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker的CheckRight不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
if (content[1] > 127)
|
||||
throw new ModbusProtocolErrorException(content[2]);
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker的CheckRight不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//CRC校验失败
|
||||
if (!Crc16.GetInstance().CrcEfficacy(content))
|
||||
throw new ModbusProtocolErrorException(501);
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker的CheckRight不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
if (content[7] > 127)
|
||||
throw new ModbusProtocolErrorException(content[2] > 0 ? content[2] : content[8]);
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
/// <returns>数据是否正确</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
//ProtocolLinker的CheckRight不会返回null
|
||||
if (base.CheckRight(content) != true) return false;
|
||||
if (base.CheckRight(content) != true) return base.CheckRight(content);
|
||||
//Modbus协议错误
|
||||
if (content[7] > 127)
|
||||
throw new ModbusProtocolErrorException(content[2] > 0 ? content[2] : content[8]);
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<byte[]>
|
||||
{
|
||||
Datas = outputStruct?.DataValue,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = ""
|
||||
};
|
||||
@@ -325,7 +325,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<byte>()
|
||||
{
|
||||
Datas = outputStruct.OutputData,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -355,7 +355,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<DiagnoticsData>()
|
||||
{
|
||||
Datas = new DiagnoticsData() { SubFunction = outputStruct.SubFunction, Data = outputStruct.Data },
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -385,7 +385,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<CommEventCounterData>()
|
||||
{
|
||||
Datas = new CommEventCounterData() { EventCount = outputStruct.EventCount, Status = outputStruct.Status },
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -415,7 +415,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<CommEventLogData>()
|
||||
{
|
||||
Datas = new CommEventLogData() { Status = outputStruct.Status, Events = outputStruct.Events },
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -445,7 +445,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<SlaveIdData>()
|
||||
{
|
||||
Datas = new SlaveIdData() { SlaveId = outputStruct.SlaveId, IndicatorStatus = outputStruct.RunIndicatorStatus, AdditionalData = outputStruct.AdditionalData },
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -475,7 +475,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<ReadFileRecordOutputDef[]>()
|
||||
{
|
||||
Datas = outputStruct.RecordDefs,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -505,7 +505,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<WriteFileRecordOutputDef[]>()
|
||||
{
|
||||
Datas = outputStruct.WriteRecords,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -535,7 +535,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<MaskRegisterData>()
|
||||
{
|
||||
Datas = new MaskRegisterData() { ReferenceAddress = outputStruct.ReferenceAddress, AndMask = outputStruct.AndMask, OrMask = outputStruct.OrMask },
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -565,7 +565,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<ushort[]>()
|
||||
{
|
||||
Datas = outputStruct.ReadRegisterValues,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
@@ -595,7 +595,7 @@ namespace Modbus.Net.Modbus
|
||||
return new ReturnStruct<ushort[]>()
|
||||
{
|
||||
Datas = outputStruct.FIFOValueRegister,
|
||||
IsSuccess = true,
|
||||
IsSuccess = outputStruct == null ? null : true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Modbus.Net
|
||||
/// <inheritdoc />
|
||||
public abstract partial class BaseConnector : BaseConnector<byte[], byte[]>
|
||||
{
|
||||
private static readonly ILogger<EventHandlerConnector> logger = LogProvider.CreateLogger<EventHandlerConnector>();
|
||||
private static readonly ILogger<BaseConnector> logger = LogProvider.CreateLogger<BaseConnector>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
243
Modbus.Net/Modbus.Net/Controller/NoResponseController.cs
Normal file
243
Modbus.Net/Modbus.Net/Controller/NoResponseController.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Quartz.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器基类
|
||||
/// </summary>
|
||||
public class NoResponseController : IController
|
||||
{
|
||||
private static readonly ILogger<NoResponseController> logger = LogProvider.CreateLogger<NoResponseController>();
|
||||
|
||||
/// <summary>
|
||||
/// 等待的消息队列
|
||||
/// </summary>
|
||||
protected List<MessageWaitingDef> WaitingMessages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息维护线程
|
||||
/// </summary>
|
||||
protected Task SendingThread { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 间隔时间
|
||||
/// </summary>
|
||||
public int AcquireTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息维护线程是否在运行
|
||||
/// </summary>
|
||||
public virtual bool IsSending => SendingThread != null;
|
||||
|
||||
private MessageWaitingDef _currentSendingPos;
|
||||
|
||||
private CancellationTokenSource _sendingThreadCancel;
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
public NoResponseController(int acquireTime)
|
||||
{
|
||||
WaitingMessages = new List<MessageWaitingDef>();
|
||||
AcquireTime = acquireTime;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MessageWaitingDef AddMessage(byte[] sendMessage)
|
||||
{
|
||||
var def = new MessageWaitingDef
|
||||
{
|
||||
Key = GetKeyFromMessage(sendMessage)?.Item1,
|
||||
SendMessage = sendMessage,
|
||||
SendMutex = new AutoResetEvent(false),
|
||||
ReceiveMutex = new AutoResetEvent(false)
|
||||
};
|
||||
if (AddMessageToList(def))
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息的实际内部方法
|
||||
/// </summary>
|
||||
protected void SendingMessageControlInner(CancellationToken token)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (AcquireTime > 0)
|
||||
{
|
||||
Thread.Sleep(AcquireTime);
|
||||
}
|
||||
lock (WaitingMessages)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_currentSendingPos == null)
|
||||
{
|
||||
if (WaitingMessages.Count > 0)
|
||||
{
|
||||
_currentSendingPos = WaitingMessages.First();
|
||||
_currentSendingPos.SendMutex.Set();
|
||||
_currentSendingPos.ReceiveMessage = new byte[0];
|
||||
_currentSendingPos.ReceiveMutex.Set();
|
||||
ForceRemoveWaitingMessage(_currentSendingPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WaitingMessages.Count <= 0)
|
||||
{
|
||||
_currentSendingPos = null;
|
||||
}
|
||||
else if (WaitingMessages.IndexOf(_currentSendingPos) == -1)
|
||||
{
|
||||
_currentSendingPos = WaitingMessages.First();
|
||||
_currentSendingPos.SendMutex.Set();
|
||||
_currentSendingPos.ReceiveMessage = new byte[0];
|
||||
_currentSendingPos.ReceiveMutex.Set();
|
||||
ForceRemoveWaitingMessage(_currentSendingPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException e)
|
||||
{
|
||||
logger.LogError(e, "Controller _currentSendingPos disposed");
|
||||
_currentSendingPos = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, "Controller throws exception");
|
||||
SendStop();
|
||||
}
|
||||
}
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SendStop()
|
||||
{
|
||||
Clear();
|
||||
_sendingThreadCancel?.Cancel();
|
||||
if (SendingThread != null)
|
||||
{
|
||||
while (!SendingThread.IsCanceled)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
SendingThread.Dispose();
|
||||
SendingThread = null;
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear()
|
||||
{
|
||||
if (WaitingMessages != null)
|
||||
{
|
||||
lock (WaitingMessages)
|
||||
{
|
||||
WaitingMessages.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将信息添加到队列
|
||||
/// </summary>
|
||||
/// <param name="def">需要添加的信息信息</param>
|
||||
protected virtual bool AddMessageToList(MessageWaitingDef def)
|
||||
{
|
||||
var ans = false;
|
||||
lock (WaitingMessages)
|
||||
{
|
||||
if (WaitingMessages.FirstOrDefault(p => p.Key == def.Key) == null || def.Key == null)
|
||||
{
|
||||
WaitingMessages.Add(def);
|
||||
ans = true;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取信息的检索关键字
|
||||
/// </summary>
|
||||
/// <param name="message">待确认的信息</param>
|
||||
/// <returns>信息的检索关键字</returns>
|
||||
protected (string, string)? GetKeyFromMessage(byte[] message)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<(byte[], bool)> ConfirmMessage(byte[] receiveMessage)
|
||||
{
|
||||
var ans = new List<(byte[], bool)>
|
||||
{
|
||||
(receiveMessage, true)
|
||||
};
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从等待队列中匹配信息
|
||||
/// </summary>
|
||||
/// <param name="receiveMessage">返回的信息</param>
|
||||
/// <returns>从等待队列中匹配的信息</returns>
|
||||
protected MessageWaitingDef GetMessageFromWaitingList(byte[] receiveMessage)
|
||||
{
|
||||
MessageWaitingDef ans;
|
||||
lock (WaitingMessages)
|
||||
{
|
||||
ans = WaitingMessages.FirstOrDefault();
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ForceRemoveWaitingMessage(MessageWaitingDef def)
|
||||
{
|
||||
lock (WaitingMessages)
|
||||
{
|
||||
if (WaitingMessages.IndexOf(def) >= 0)
|
||||
{
|
||||
WaitingMessages.Remove(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,15 @@ 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);
|
||||
var noResponse = bool.Parse(ConfigurationReader.GetValue("COM:" + com, "NoResponse") ?? ConfigurationReader.GetValue("Controller", "NoResponse"));
|
||||
if (noResponse)
|
||||
{
|
||||
((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new NoResponseController(int.Parse(ConfigurationReader.GetValue("COM:" + com + ":" + slaveAddress, "FetchSleepTime"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AddController(new object[2] { com, slaveAddress }, BaseConnector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,15 @@
|
||||
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);
|
||||
var noResponse = bool.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "NoResponse") ?? ConfigurationReader.GetValue("Controller", "NoResponse"));
|
||||
if (noResponse)
|
||||
{
|
||||
((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new NoResponseController(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AddController(new object[2] { ip, port }, BaseConnector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,15 @@
|
||||
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);
|
||||
var noResponse = bool.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "NoResponse") ?? ConfigurationReader.GetValue("Controller", "NoResponse"));
|
||||
if (noResponse)
|
||||
{
|
||||
((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new NoResponseController(int.Parse(ConfigurationReader.GetValue("UDP:" + ip + ":" + port, "FetchSleepTime"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AddController(new object[2] { ip, port }, BaseConnector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,9 +98,19 @@ namespace Modbus.Net
|
||||
ValueHelper.ByteLength[
|
||||
communicateAddress.DataType.FullName]));
|
||||
|
||||
|
||||
//如果已知没有返回,终止
|
||||
if (datas.IsSuccess == null)
|
||||
{
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
Datas = null,
|
||||
IsSuccess = null,
|
||||
ErrorCode = datas.ErrorCode,
|
||||
ErrorMsg = datas.ErrorMsg
|
||||
};
|
||||
}
|
||||
//如果没有数据,终止
|
||||
if (datas.IsSuccess == false || datas.Datas == null)
|
||||
else if (datas.IsSuccess == false || datas.Datas == null)
|
||||
{
|
||||
return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
|
||||
{
|
||||
@@ -336,6 +346,14 @@ namespace Modbus.Net
|
||||
//如果设备本身能获取到数据但是没有数据
|
||||
var datas = datasReturn;
|
||||
|
||||
//没有返回,直接设0
|
||||
if (datas.IsSuccess == null)
|
||||
{
|
||||
datas.Datas = new byte[(int)
|
||||
Math.Ceiling(communicateAddress.GetCount *
|
||||
ValueHelper.ByteLength[
|
||||
communicateAddress.DataType.FullName])];
|
||||
}
|
||||
//如果没有数据,终止
|
||||
if (datas.IsSuccess == false || datas.Datas == null)
|
||||
{
|
||||
|
||||
@@ -185,7 +185,12 @@ namespace Modbus.Net
|
||||
public virtual async Task<T> SendReceiveAsync<T>(TProtocolUnit unit, IInputStruct content)
|
||||
where T : class, IOutputStruct
|
||||
{
|
||||
return (await SendReceiveAsync(unit, content)).Unwrap<T>();
|
||||
var ans = await SendReceiveAsync(unit, content);
|
||||
if (ans.Success == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return ans.Unwrap<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Modbus.Net
|
||||
/// <param name="parameters">传递给输入结构的参数</param>
|
||||
/// <param name="success">上次的管道是否成功执行</param>
|
||||
protected PipeUnit(IProtocolLinker<byte[], byte[]> protocolLinker, ProtocolUnit<byte[], byte[]> protocolUnit, byte[] parameters,
|
||||
bool success) : base(protocolLinker, protocolUnit, parameters, success)
|
||||
bool? success) : base(protocolLinker, protocolUnit, parameters, success)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Modbus.Net
|
||||
/// <returns>发送完成之后新的管道实例</returns>
|
||||
public async Task<PipeUnit> SendReceiveAsync(Endian endian, Func<byte[], object[]> inputStructCreator)
|
||||
{
|
||||
if (Success)
|
||||
if (Success == true)
|
||||
{
|
||||
var content = inputStructCreator.Invoke(ReturnParams);
|
||||
if (ProtocolLinker != null)
|
||||
@@ -47,7 +47,7 @@ namespace Modbus.Net
|
||||
await ProtocolLinker.SendReceiveAsync(ProtocolUnit<byte[], byte[]>.TranslateContent(endian, content)),
|
||||
true);
|
||||
}
|
||||
return new PipeUnit(ProtocolLinker, null, ReturnParams, false);
|
||||
return new PipeUnit(ProtocolLinker, null, ReturnParams, Success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -62,8 +62,18 @@ namespace Modbus.Net
|
||||
{
|
||||
var receiveContent = await SendReceiveAsyncParamOut(unit, inputStructCreator);
|
||||
if (receiveContent != null)
|
||||
return new PipeUnit(ProtocolLinker, unit,
|
||||
receiveContent, true);
|
||||
{
|
||||
if (receiveContent.Length > 0)
|
||||
{
|
||||
return new PipeUnit(ProtocolLinker, unit,
|
||||
receiveContent, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new PipeUnit(ProtocolLinker, unit,
|
||||
receiveContent, null);
|
||||
}
|
||||
}
|
||||
return new PipeUnit(ProtocolLinker, unit, ReturnParams,
|
||||
false);
|
||||
}
|
||||
@@ -106,7 +116,7 @@ namespace Modbus.Net
|
||||
/// <param name="protocolUnit">协议单元</param>
|
||||
/// <param name="parameters">输入参数</param>
|
||||
/// <param name="success">上一次管道结果是否成功</param>
|
||||
protected PipeUnit(TProtocolLinker protocolLinker, TProtocolUnit protocolUnit, TParamOut parameters, bool success)
|
||||
protected PipeUnit(TProtocolLinker protocolLinker, TProtocolUnit protocolUnit, TParamOut parameters, bool? success)
|
||||
{
|
||||
ProtocolLinker = protocolLinker;
|
||||
ProtocolUnit = protocolUnit;
|
||||
@@ -132,7 +142,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 本次管道是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; }
|
||||
public bool? Success { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 向设备发送数据,返回输出参数
|
||||
@@ -143,7 +153,7 @@ namespace Modbus.Net
|
||||
protected async Task<TParamOut> SendReceiveAsyncParamOut(TProtocolUnit unit,
|
||||
Func<TParamOut, IInputStruct> inputStructCreator)
|
||||
{
|
||||
if (Success)
|
||||
if (Success == true)
|
||||
{
|
||||
var content = inputStructCreator.Invoke(ReturnParams);
|
||||
var formatContent = unit.Format(content);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/// <summary>
|
||||
/// 操作是否成功
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; set; }
|
||||
public bool? IsSuccess { get; set; }
|
||||
/// <summary>
|
||||
/// 错误代码
|
||||
/// </summary>
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ namespace MachineJob.Service
|
||||
private Dictionary<string, double>? QueryConsole(DataReturnDef dataReturnDef)
|
||||
{
|
||||
var values = dataReturnDef.ReturnValues.Datas;
|
||||
if (dataReturnDef.ReturnValues.IsSuccess)
|
||||
if (dataReturnDef.ReturnValues.IsSuccess == true)
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
@@ -135,6 +135,19 @@ namespace MachineJob.Service
|
||||
|
||||
return values.MapGetValuesToSetValues();
|
||||
}
|
||||
else if(dataReturnDef.ReturnValues.IsSuccess == null)
|
||||
{
|
||||
Random r = new Random();
|
||||
|
||||
Dictionary<string, double> ans = new Dictionary<string, double>();
|
||||
|
||||
for (int i = 0; i< 10; i++)
|
||||
{
|
||||
ans["Test" + (i+1)] = r.Next(65536) - 32768;
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user