Merge pull request #317 from scamille/read-request-header

Unify async read request header building.
This commit is contained in:
Michael Croes
2020-10-14 21:14:17 +02:00
committed by GitHub
4 changed files with 68 additions and 24 deletions

View File

@@ -1,4 +1,5 @@
using S7.Net.Helper;
using S7.Net.Protocol.S7;
using S7.Net.Types;
using System;
using System.Collections.Generic;
@@ -14,7 +15,7 @@ namespace S7.Net
/// </summary>
/// <param name="amount"></param>
/// <returns></returns>
private void BuildHeaderPackage(System.IO.MemoryStream stream, int amount = 1)
private static void BuildHeaderPackage(System.IO.MemoryStream stream, int amount = 1)
{
//header size = 19 bytes
stream.WriteByteArray(new byte[] { 0x03, 0x00 });
@@ -37,7 +38,7 @@ namespace S7.Net
/// <param name="startByteAdr">Start address of the byte</param>
/// <param name="count">Number of bytes to be read</param>
/// <returns></returns>
private void BuildReadDataRequestPackage(System.IO.MemoryStream stream, DataType dataType, int db, int startByteAdr, int count = 1)
private static void BuildReadDataRequestPackage(System.IO.MemoryStream stream, DataType dataType, int db, int startByteAdr, int count = 1)
{
//single data req = 12
stream.WriteByteArray(new byte[] { 0x12, 0x0a, 0x10 });
@@ -176,7 +177,7 @@ namespace S7.Net
/// <param name="varType"></param>
/// <param name="varCount"></param>
/// <returns>Byte lenght of variable</returns>
private int VarTypeToByteLength(VarType varType, int varCount = 1)
internal static int VarTypeToByteLength(VarType varType, int varCount = 1)
{
switch (varType)
{
@@ -242,5 +243,20 @@ namespace S7.Net
offset++;
}
}
private static byte[] BuildReadRequestPackage(IList<DataItemAddress> dataItems)
{
int packageSize = 19 + (dataItems.Count * 12);
var package = new System.IO.MemoryStream(packageSize);
BuildHeaderPackage(package, dataItems.Count);
foreach (var dataItem in dataItems)
{
BuildReadDataRequestPackage(package, dataItem.DataType, dataItem.DB, dataItem.StartByteAddress, dataItem.ByteLength);
}
return package.ToArray();
}
}
}

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using S7.Net.Protocol;
using System.IO;
using System.Threading;
using S7.Net.Protocol.S7;
namespace S7.Net
{
@@ -262,20 +263,10 @@ namespace S7.Net
try
{
// first create the header
int packageSize = 19 + (dataItems.Count * 12);
var package = new System.IO.MemoryStream(packageSize);
BuildHeaderPackage(package, dataItems.Count);
// package.Add(0x02); // datenart
foreach (var dataItem in dataItems)
{
BuildReadDataRequestPackage(package, dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, VarTypeToByteLength(dataItem.VarType, dataItem.Count));
}
var dataToSend = package.ToArray();
var dataToSend = BuildReadRequestPackage(dataItems.Select(d => DataItem.GetDataItemAddress(d)).ToList());
await stream.WriteAsync(dataToSend, 0, dataToSend.Length);
var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken); //TODO use Async
var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken);
ValidateResponseCode((ReadWriteErrorCode)s7data[14]);
ParseDataIntoDataItems(s7data, dataItems);
@@ -295,6 +286,7 @@ namespace S7.Net
return dataItems;
}
/// <summary>
/// Write a number of bytes from a DB starting from a specified index. This handles more than 200 bytes with multiple requests.
/// If the write was not successful, check LastErrorCode or LastErrorString.
@@ -444,14 +436,7 @@ namespace S7.Net
{
var stream = GetStreamIfAvailable();
// first create the header
int packageSize = 31;
var package = new System.IO.MemoryStream(packageSize);
BuildHeaderPackage(package);
// package.Add(0x02); // datenart
BuildReadDataRequestPackage(package, dataType, db, startByteAdr, count);
var dataToSend = package.ToArray();
var dataToSend = BuildReadRequestPackage(new [] { new DataItemAddress(dataType, db, startByteAdr, count)});
await stream.WriteAsync(dataToSend, 0, dataToSend.Length, cancellationToken);
var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken);

View File

@@ -0,0 +1,37 @@
namespace S7.Net.Protocol.S7
{
/// <summary>
/// Represents an area of memory in the PLC
/// </summary>
internal class DataItemAddress
{
public DataItemAddress(DataType dataType, int db, int startByteAddress, int byteLength)
{
DataType = dataType;
DB = db;
StartByteAddress = startByteAddress;
ByteLength = byteLength;
}
/// <summary>
/// Memory area to read
/// </summary>
public DataType DataType { get; }
/// <summary>
/// Address of memory area to read (example: for DB1 this value is 1, for T45 this value is 45)
/// </summary>
public int DB { get; }
/// <summary>
/// Address of the first byte to read
/// </summary>
public int StartByteAddress { get; }
/// <summary>
/// Length of data to read
/// </summary>
public int ByteLength { get; }
}
}

View File

@@ -1,4 +1,5 @@
using System;
using S7.Net.Protocol.S7;
using System;
namespace S7.Net.Types
{
@@ -94,5 +95,10 @@ namespace S7.Net.Types
return dataItem;
}
internal static DataItemAddress GetDataItemAddress(DataItem dataItem)
{
return new DataItemAddress(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, Plc.VarTypeToByteLength(dataItem.VarType, dataItem.Count));
}
}
}