[fix] add max retry attempt to prevent infinite loop

[fix] process grouped registers' data at once
[update] update configuration template
This commit is contained in:
Stephen Chen (ManPower) 2017-12-19 11:55:53 +08:00
Родитель 218dfc3eae
Коммит 8177016929
3 изменённых файлов: 72 добавлений и 28 удалений

Просмотреть файл

@ -1,17 +1,19 @@
{
"Interval": "1500",
"PublishInterval": "5000",
"SlaveConfigs": {
"Slave01": {
"SlaveConnection": "127.0.0.1",
"HwId": "PowerMeter-0a:01:01:01:01:01",
"Operations": {
"Op01": {
"PollingInterval": "2000",
"UnitId": "1",
"StartAddress": "400001",
"Count": "2",
"DisplayName": "Voltage"
},
"Op02": {
"PollingInterval": "2000",
"UnitId": "1",
"StartAddress": "400002",
"Count": "2",
@ -29,12 +31,14 @@
"FlowControl": "NONE",
"Operations": {
"Op01": {
"PollingInterval": "2000",
"UnitId": "1",
"StartAddress": "40001",
"Count": "2",
"DisplayName": "Voltage"
},
"Op02": {
"PollingInterval": "2000",
"UnitId": "1",
"StartAddress": "40002",
"Count": "2",

Просмотреть файл

@ -6,8 +6,8 @@
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using tempSerialPort;
using System.IO.Ports;
using tempSerialPort;
using System.IO.Ports;
using System.Runtime.InteropServices;
/* Modbus Frame Details
@ -98,6 +98,7 @@
public ModbusSlaveConfig config;
protected HandleResultDelegate messageDelegate;
protected const int m_bufSize = 512;
protected const int m_retryMax = 10;
protected bool m_run = false;
protected List<Task> m_taskList = new List<Task>();
protected virtual int m_reqSize { get; }
@ -114,7 +115,7 @@
#region Public Methods
public abstract void ReleaseSession();
public delegate void HandleResultDelegate(ModbusOutMessage message);
public delegate void HandleResultDelegate(List<ModbusOutMessage> message);
public async Task InitSession()
{
await ConnectSlave();
@ -191,6 +192,7 @@
int count = 0;
int step_size = 0;
int start_digit = 0;
List<ModbusOutMessage> message_list = new List<ModbusOutMessage>();
switch (x.Response[m_dataBodyOffset])//function code
{
case (byte)ModbusConstants.FunctionCodeType.ReadCoils:
@ -231,8 +233,10 @@
ModbusOutMessage message = new ModbusOutMessage()
{ HwId = config.HwId, DisplayName = x.DisplayName, Address = cell, Value = val, SourceTimestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") };
messageDelegate(message);
}
message_list.Add(message);
}
if (message_list.Count > 0)
messageDelegate(message_list);
}
protected bool ParseEntity(string startAddress, bool isRead, out ushort outAddress, out byte functionCode, out byte entityType)
{
@ -450,21 +454,39 @@
int data_len = 0;
int h_l = 0;
int d_l = 0;
int retry = 0;
while (header_len < m_dataBodyOffset)
while (header_len < m_dataBodyOffset && retry < m_retryMax)
{
h_l = m_socket.Receive(response, header_len, m_dataBodyOffset - header_len, SocketFlags.None);
if (h_l >= 0)
header_len += h_l;
{
header_len += h_l;
}
else
{
retry++;
}
}
int byte_counts = IPAddress.NetworkToHostOrder((Int16)BitConverter.ToUInt16(response, 4)) - 1;
while (data_len < byte_counts)
while (data_len < byte_counts && retry < m_retryMax)
{
d_l = m_socket.Receive(response, m_dataBodyOffset + data_len, byte_counts - data_len, SocketFlags.None);
if (d_l >= 0)
data_len += d_l;
{
data_len += d_l;
}
else
{
retry++;
}
}
if (retry >= m_retryMax)
{
return null;
}
return response;
@ -517,13 +539,13 @@
try
{
Console.WriteLine($"Opening...{config.SlaveConnection}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
m_serialPort = WinSerialDevice.CreateDevice(config.SlaveConnection, (int)config.BaudRate, config.Parity, (int)config.DataBits, config.StopBits);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
m_serialPort = WinSerialDevice.CreateDevice(config.SlaveConnection, (int)config.BaudRate, config.Parity, (int)config.DataBits, config.StopBits);
}
else
{
m_serialPort = UnixSerialDevice.CreateDevice(config.SlaveConnection, (int)config.BaudRate, config.Parity, (int)config.DataBits, config.StopBits);
else
{
m_serialPort = UnixSerialDevice.CreateDevice(config.SlaveConnection, (int)config.BaudRate, config.Parity, (int)config.DataBits, config.StopBits);
}
m_serialPort.Open();
//m_serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
@ -632,23 +654,41 @@
{
byte[] response = new byte[m_bufSize];
int header_len = 0;
int data_len = 0;
int h_l = 0;
int d_l = 0;
int data_len = 0;
int h_l = 0;
int d_l = 0;
int retry = 0;
while (header_len < 3)
while (header_len < 3 && retry < m_retryMax)
{
h_l = m_serialPort.Read(response, header_len, 3 - header_len);
if (h_l >= 0)
header_len += h_l;
}
{
header_len += h_l;
}
else
{
retry++;
}
}
int byte_counts = response[2] + 2;
while (data_len < byte_counts)
while (data_len < byte_counts && retry < m_retryMax)
{
d_l = m_serialPort.Read(response, 3 + data_len, byte_counts - data_len);
if (d_l >= 0)
data_len += d_l;
{
data_len += d_l;
}
else
{
retry++;
}
}
if (retry >= m_retryMax)
{
return null;
}
return response;

Просмотреть файл

@ -248,7 +248,7 @@ namespace Modbus.Containers
}
else
{
Console.WriteLine("No configuration found in desired properties.");
Console.WriteLine("No configuration found in desired properties, look in local...");
if (File.Exists(@"iot-edge-modbus.json"))
{
try
@ -258,7 +258,7 @@ namespace Modbus.Containers
}
catch (Exception ex)
{
Console.WriteLine("Unable to read configuration from file. Error: " + ex.Message);
Console.WriteLine("No configuration found in local file. Error: " + ex.Message);
}
}
}
@ -378,11 +378,11 @@ namespace Modbus.Containers
}
}
static void UpdateMessage(ModbusOutMessage message)
static void UpdateMessage(List<ModbusOutMessage> messages)
{
lock(message_lock)
{
result.Add(message);
result.AddRange(messages);
}
}
}