Unify async read request header building.

Add concept of DataRequestItem which contains the necessary data to build the request.
This commit is contained in:
Serge Camille
2020-09-12 21:33:53 +02:00
parent 4124bae1bc
commit e2a0ed548d
3 changed files with 62 additions and 23 deletions

42
S7.Net/DataRequestItem.cs Normal file
View File

@@ -0,0 +1,42 @@

using S7.Net.Types;
namespace S7.Net
{
internal class DataRequestItem
{
public DataRequestItem(DataType dataType, int db, int startByteAddress, int byteLength)
{
DataType = dataType;
DB = db;
StartByteAddress = startByteAddress;
ByteLength = byteLength;
}
public DataRequestItem(DataItem dataItem)
: this(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, Plc.VarTypeToByteLength(dataItem.VarType, dataItem.Count))
{
}
/// <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

@@ -14,7 +14,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 +37,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 +176,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)
{

View File

@@ -262,20 +262,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=> new DataRequestItem(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 +285,20 @@ namespace S7.Net
return dataItems;
}
private static byte[] BuildReadRequestPackage(IList<DataRequestItem> dataItems)
{
// 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.StartByteAddress, dataItem.ByteLength);
}
return package.ToArray();
}
/// <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 +448,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 DataRequestItem(dataType, db, startByteAdr, count)});
await stream.WriteAsync(dataToSend, 0, dataToSend.Length, cancellationToken);
var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken);