From e2a0ed548d64a0b2bd32bf0fdc847b7a91411313 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Sat, 12 Sep 2020 21:33:53 +0200 Subject: [PATCH 1/3] 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); From 4d37679c753b79e22900b408bf1697c8a2b6ee74 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Wed, 16 Sep 2020 22:01:33 +0200 Subject: [PATCH 2/3] Move BuildReadRequestPackage to PlcHelpers, cleanup. --- S7.Net/PLCHelpers.cs | 15 +++++++++++++++ S7.Net/PlcAsynchronous.cs | 13 ------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs index 949fcd3..b701863 100644 --- a/S7.Net/PLCHelpers.cs +++ b/S7.Net/PLCHelpers.cs @@ -242,5 +242,20 @@ namespace S7.Net offset++; } } + + private static byte[] BuildReadRequestPackage(IList 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(); + } } } diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index 8f33940..9bd57de 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -285,19 +285,6 @@ 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. From a7608e3cb7097c3b9f6b522da3175cd27d040a08 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Wed, 16 Sep 2020 23:02:09 +0200 Subject: [PATCH 3/3] Rename and Move DataRequestItem --- S7.Net/PLCHelpers.cs | 3 ++- S7.Net/PlcAsynchronous.cs | 5 +++-- .../S7/DataItemAddress.cs} | 17 ++++++----------- S7.Net/Types/DataItem.cs | 8 +++++++- 4 files changed, 18 insertions(+), 15 deletions(-) rename S7.Net/{DataRequestItem.cs => Protocol/S7/DataItemAddress.cs} (69%) diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs index b701863..1668e08 100644 --- a/S7.Net/PLCHelpers.cs +++ b/S7.Net/PLCHelpers.cs @@ -1,4 +1,5 @@ using S7.Net.Helper; +using S7.Net.Protocol.S7; using S7.Net.Types; using System; using System.Collections.Generic; @@ -243,7 +244,7 @@ namespace S7.Net } } - private static byte[] BuildReadRequestPackage(IList dataItems) + private static byte[] BuildReadRequestPackage(IList dataItems) { int packageSize = 19 + (dataItems.Count * 12); var package = new System.IO.MemoryStream(packageSize); diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index 9bd57de..b6b49c6 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -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,7 +263,7 @@ namespace S7.Net try { - var dataToSend = BuildReadRequestPackage(dataItems.Select(d=> new DataRequestItem(d)).ToList()); + 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); @@ -435,7 +436,7 @@ namespace S7.Net { var stream = GetStreamIfAvailable(); - var dataToSend = BuildReadRequestPackage(new [] { new DataRequestItem(dataType, db, startByteAdr, count)}); + 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); diff --git a/S7.Net/DataRequestItem.cs b/S7.Net/Protocol/S7/DataItemAddress.cs similarity index 69% rename from S7.Net/DataRequestItem.cs rename to S7.Net/Protocol/S7/DataItemAddress.cs index 6b27c85..cf37382 100644 --- a/S7.Net/DataRequestItem.cs +++ b/S7.Net/Protocol/S7/DataItemAddress.cs @@ -1,11 +1,11 @@ - -using S7.Net.Types; - -namespace S7.Net +namespace S7.Net.Protocol.S7 { - internal class DataRequestItem + /// + /// Represents an area of memory in the PLC + /// + internal class DataItemAddress { - public DataRequestItem(DataType dataType, int db, int startByteAddress, int byteLength) + public DataItemAddress(DataType dataType, int db, int startByteAddress, int byteLength) { DataType = dataType; DB = db; @@ -13,11 +13,6 @@ namespace S7.Net ByteLength = byteLength; } - public DataRequestItem(DataItem dataItem) - : this(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, Plc.VarTypeToByteLength(dataItem.VarType, dataItem.Count)) - { - - } /// /// Memory area to read diff --git a/S7.Net/Types/DataItem.cs b/S7.Net/Types/DataItem.cs index c944ffa..254eab3 100644 --- a/S7.Net/Types/DataItem.cs +++ b/S7.Net/Types/DataItem.cs @@ -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)); + } } }