From e2a0ed548d64a0b2bd32bf0fdc847b7a91411313 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Sat, 12 Sep 2020 21:33:53 +0200 Subject: [PATCH] Unify async read request header building. Add concept of DataRequestItem which contains the necessary data to build the request. --- S7.Net/DataRequestItem.cs | 42 +++++++++++++++++++++++++++++++++++++++ S7.Net/PLCHelpers.cs | 6 +++--- S7.Net/PlcAsynchronous.cs | 37 ++++++++++++++++------------------ 3 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 S7.Net/DataRequestItem.cs diff --git a/S7.Net/DataRequestItem.cs b/S7.Net/DataRequestItem.cs new file mode 100644 index 0000000..6b27c85 --- /dev/null +++ b/S7.Net/DataRequestItem.cs @@ -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)) + { + + } + + /// + /// Memory area to read + /// + public DataType DataType { get; } + + /// + /// Address of memory area to read (example: for DB1 this value is 1, for T45 this value is 45) + /// + public int DB { get; } + + /// + /// Address of the first byte to read + /// + public int StartByteAddress { get; } + + /// + /// Length of data to read + /// + public int ByteLength { get; } + } +} diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs index f2c757d..949fcd3 100644 --- a/S7.Net/PLCHelpers.cs +++ b/S7.Net/PLCHelpers.cs @@ -14,7 +14,7 @@ namespace S7.Net /// /// /// - 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 /// Start address of the byte /// Number of bytes to be read /// - 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 /// /// /// Byte lenght of variable - private int VarTypeToByteLength(VarType varType, int varCount = 1) + internal static int VarTypeToByteLength(VarType varType, int varCount = 1) { switch (varType) { diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index fd3e6fd..8f33940 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -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 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(); + } + /// /// 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);