Skip to content

Commit

Permalink
Merge pull request #196 from ryan2445/master
Browse files Browse the repository at this point in the history
Add S7 options to get DB 'actual values' and expand arrays
  • Loading branch information
jogibear9988 authored Nov 11, 2023
2 parents 874b210 + 169a959 commit bc98f21
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@ public S7ConvertingOptions(MnemonicLanguage Mnemonic)
this.UseInFCStoredFCsForCalls = true; //todo implement the reading of them in the step7 project
this.UseComments = true;
this.UseFBDeclarationForInstanceDB = true; //Default to Simatic Mamager Behavior
this.UseDBActualValues = false;
this.ExpandArrays = false;
}

public bool UseComments { get; set; }
public MnemonicLanguage Mnemonic { get; set; }
public bool CombineDBOpenAndDBAccess { get; set; }
public bool ReplaceDBAccessesWithSymbolNames { get; set; }
public bool UseDBActualValues { get; set; }
public bool ExpandArrays { get; set; }

public bool ReplaceLokalDataAddressesWithSymbolNames { get; set; }
public bool ReplaceDIAccessesWithSymbolNames { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ You should have received a copy of the GNU Library General Public License
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Projectfolders.Step7V5;
using DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7;
using DotNetSiemensPLCToolBoxLibrary.General;
using System.Text.RegularExpressions;


namespace DotNetSiemensPLCToolBoxLibrary.DataTypes.Blocks
Expand Down Expand Up @@ -89,6 +90,41 @@ public string FullBlockAddressInDbFormat
}
}

internal List<string> GetStartValuesArray(object startValues)
{
if (startValues == null)
{
return new List<string>();
}

var strStartValues = startValues.ToString();

// matches on shortened pattern like "2(3),2(3)"
var shortPattern = @"(\d+)\(([^)]+)\)";
var matches = Regex.Matches(strStartValues, shortPattern);

if (matches.Count == 0)
{
// assumes "1,2,3,4,5" format
return strStartValues.Split(',').ToList();
}

var ret = new List<string>();

foreach (Match match in matches)
{
var count = int.Parse(match.Groups[1].Value);
var value = match.Groups[2].Value;

for (int i = 0; i < count; i++)
{
ret.Add(value);
}
}

return ret;
}

internal List<TiaAndSTep7DataBlockRow> _GetExpandedChlidren(S7DataBlockExpandOptions myExpOpt)
{
TiaAndSTep7DataBlockRow retVal = (TiaAndSTep7DataBlockRow)this.DeepCopy();
Expand All @@ -108,6 +144,8 @@ internal List<TiaAndSTep7DataBlockRow> _GetExpandedChlidren(S7DataBlockExpandOpt
{
List<TiaAndSTep7DataBlockRow> arrAsList = new List<TiaAndSTep7DataBlockRow>();

var startValues = GetStartValuesArray(StartValue);

var lastCnt = (ArrayStop.Last() - ArrayStart.Last()) + 1;

int[] arrAk = ArrayStart.ToArray();
Expand All @@ -129,6 +167,14 @@ internal List<TiaAndSTep7DataBlockRow> _GetExpandedChlidren(S7DataBlockExpandOpt
tmp.WasArray = retVal.IsArray;
tmp.IsArray = false;
tmp.WasNextHigherIndex = frst; // arrAk[ArrayStart.Count - 1] == ArrayStart[ArrayStart.Count - 1];
if (i < startValues.Count)
{
tmp.StartValue = startValues[i];
}
else
{
tmp.StartValue = Helper.DefaultValueForType(DataType);
}
arrAsList.Add(tmp);

for (int n = arrAk.Length - 1; n >= 0; n--)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,20 @@ private TmpBlock GetBlockBytes(string blkName)
}

public S7DataRow GetInterface(string blkName)
{
var myConvOpt = new S7ConvertingOptions(Project.ProjectLanguage);

return GetInterface(blkName, myConvOpt);
}

public S7DataRow GetInterface(string blkName, S7ConvertingOptions myConvOpt)
{
var blkInfo = GetProjectBlockInfoFromBlockName(blkName);
if (blkInfo == null)
return null;
TmpBlock myTmpBlk = GetBlockBytes(blkInfo);
List<string> tmpPar = new List<string>();
return Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref tmpPar, blkInfo.BlockType, false, this, null);
return Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref tmpPar, blkInfo.BlockType, false, this, null, myConvOpt);
}

/// <summary>
Expand Down Expand Up @@ -547,10 +554,10 @@ public Block GetBlock(ProjectBlockInfo blkInfo, S7ConvertingOptions myConvOpt)
{
S7DataRow InterfaceFB =
Parameter.GetInterfaceOrDBFromStep7ProjectString(InstFB.blkinterface, ref tmpPar,
PLCBlockType.FB, false, this, null);
PLCBlockType.FB, false, this, null, myConvOpt);
S7DataRow InterfaceDB =
Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref tmpPar,
PLCBlockType.DB, false, this, null);
PLCBlockType.DB, false, this, null, myConvOpt);

//Only use the FB interface Declaration if they are compatible
if (Parameter.IsInterfaceCompatible(InterfaceFB, InterfaceDB))
Expand All @@ -561,7 +568,7 @@ public Block GetBlock(ProjectBlockInfo blkInfo, S7ConvertingOptions myConvOpt)
if (myTmpBlk.mc7code != null)
retVal.CodeSize = myTmpBlk.mc7code.Length;

retVal.StructureFromString = Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref tmpList, blkInfo.BlockType, false, this, retVal, myTmpBlk.mc7code);
retVal.StructureFromString = Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref tmpList, blkInfo.BlockType, false, this, retVal, myConvOpt, myTmpBlk.mc7code);
if (myTmpBlk.blkinterfaceInMC5 != null)
{
//List<string> tmp = new List<string>();
Expand Down Expand Up @@ -604,7 +611,7 @@ public Block GetBlock(ProjectBlockInfo blkInfo, S7ConvertingOptions myConvOpt)
retVal.Author = myTmpBlk.username;
retVal.Version = myTmpBlk.version;

retVal.Parameter = Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref ParaList, blkInfo.BlockType, false, this, retVal);
retVal.Parameter = Parameter.GetInterfaceOrDBFromStep7ProjectString(myTmpBlk.blkinterface, ref ParaList, blkInfo.BlockType, false, this, retVal, myConvOpt);

if (myTmpBlk.blockdescription != null)
{
Expand Down
4 changes: 2 additions & 2 deletions LibNoDaveConnectionLibrary/PLCs/S7_xxx/MC7/CallConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public static void ConvertUCToCall(S7FunctionBlock myFct, S7ProgrammFolder myFld
else if (row.Command == Mnemonic.opBLD[(int)myOpt.Mnemonic] && (row.Parameter == "2" || row.Parameter == "8"))
{
//Block Interface auslesen (von FC oder vom Programm)
S7DataRow para = myblkFld.GetInterface(callRow.Parameter);
S7DataRow para = myblkFld.GetInterface(callRow.Parameter, myOpt);

newRow = new S7FunctionBlockRow();
newRow.Command = Mnemonic.opCALL[(int)myOpt.Mnemonic];
Expand Down Expand Up @@ -545,7 +545,7 @@ public static void ConvertUCToCall(S7FunctionBlock myFct, S7ProgrammFolder myFld
else if (row.Command == Mnemonic.opBLD[(int)myOpt.Mnemonic] && (row.Parameter == "4" || row.Parameter == "17" || row.Parameter == "15" || row.Parameter == "10"))
{
//Block Interface auslesen (von FC oder vom Programm)
S7DataRow para = myblkFld.GetInterface(callRow.Parameter);
S7DataRow para = myblkFld.GetInterface(callRow.Parameter, myOpt);

newRow = new S7FunctionBlockRow();
newRow.Parent = callRow.Parent;
Expand Down
2 changes: 1 addition & 1 deletion LibNoDaveConnectionLibrary/PLCs/S7_xxx/MC7/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ public static string GetFCPointer(byte b1, byte b2, byte b3, byte b4)
switch (b1)
{
case 0x80:
anf = "P#PE ";
anf = "P#P ";
wrt = (b3 * 0x100 + b4) >> 3;
break;
case 0x81:
Expand Down
96 changes: 91 additions & 5 deletions LibNoDaveConnectionLibrary/PLCs/S7_xxx/MC7/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ You should have received a copy of the GNU Library General Public License
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Blocks.Step7V5;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Projectfolders.Step7V5;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Blocks;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.AWL.Step7V5;

namespace DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7
{
Expand Down Expand Up @@ -167,7 +168,7 @@ internal static bool IsInterfaceCompatible(IDataRow Block1, IDataRow Block2)
/// <param name="myBlk">The Block where the Parsed Step7 code belongs to</param>
/// <param name="actualValues">the current values of the DB, if it is an DB</param>
/// <returns></returns>
internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref List<String> ParaList, PLCBlockType blkTP, bool isInstanceDB, BlocksOfflineFolder myFld, S7Block myBlk, byte[] actualValues = null)
internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref List<String> ParaList, PLCBlockType blkTP, bool isInstanceDB, BlocksOfflineFolder myFld, S7Block myBlk, S7ConvertingOptions myConvOpt, byte[] actualValues = null)
{
S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);
S7DataRow parameterRootWithoutTemp = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk);
Expand Down Expand Up @@ -550,6 +551,13 @@ internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref
// addRW.Value = GetVarTypeVal((byte)addRW.DataType, actualValues, ref Valpos);
//}

if (myConvOpt.ExpandArrays && blkTP == PLCBlockType.DB && addRW.IsArray)
{
var arrayMembers = addRW._GetExpandedChlidren(new S7DataBlockExpandOptions());

addRW.AddRange(arrayMembers);
}

akDataRow.Add(addRW);
ParaList.Add(tmpName);

Expand Down Expand Up @@ -580,15 +588,16 @@ internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref
}
}
}

if (blkTP != PLCBlockType.DB && blkTP != PLCBlockType.UDT && tempAdded == false)
{
parameterRoot.Add(parameterTEMP);
}

if (actualValues != null)
// Only get actual values for DBs
if (myConvOpt.UseDBActualValues && blkTP == PLCBlockType.DB && actualValues != null)
{
int vPos = 0, bPos = 0;
//FillActualValuesInDataBlock(parameterRoot, actualValues, ref vPos, ref bPos);
FillActualValuesInDataBlock(parameterRoot, actualValues);
}

return parameterRoot;
Expand Down Expand Up @@ -1119,9 +1128,86 @@ internal static object GetVarCurrentValue(S7DataRowType dataType, byte[] data, B
Result = Helper.GetS7String(valpos.ByteAddress, -1, data);
}
break;
case S7DataRowType.TIMER:
{
Result = "T " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.COUNTER:
{
Result = "Z " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.POINTER:
{
var dbNumber = libnodave.getU16from(data, valpos.ByteAddress);

var pointer = Helper.GetFCPointer(
data[valpos.ByteAddress + 2],
data[valpos.ByteAddress + 3],
data[valpos.ByteAddress + 4],
data[valpos.ByteAddress + 5]);

if (dbNumber != 0)
{
pointer = pointer.Insert(2, "DB" + dbNumber + ".");
}

Result = pointer;
}
break;
case S7DataRowType.ANY:
{
var pointerDataType = (S7DataRowType)data[valpos.ByteAddress + 1];

var repeatFactor = libnodave.getU16from(data, valpos.ByteAddress + 2);

var dbNumber = libnodave.getU16from(data, valpos.ByteAddress + 4);

var pointer = Helper.GetFCPointer(
data[valpos.ByteAddress + 6],
data[valpos.ByteAddress + 7],
data[valpos.ByteAddress + 8],
data[valpos.ByteAddress + 9]);

if (dbNumber != 0)
{
pointer = pointer.Insert(2, "DB" + dbNumber + ".");
}

pointer += " " + pointerDataType + " " + repeatFactor;

Result = pointer;
}
break;
case S7DataRowType.SFB: //unclear, needs to be checked
{ // 'SFB??';
Result = "SFB??";
Result = null;
}
break;
case S7DataRowType.BLOCK_FB:
{
Result = "FB " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.BLOCK_DB:
{
Result = "DB " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.BLOCK_FC:
{
Result = "FC " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.BLOCK_SDB:
{
Result = "SDB " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
case S7DataRowType.UDT:
{
Result = "UDT " + libnodave.getU16from(data, valpos.ByteAddress);
}
break;
default:
Expand Down
9 changes: 5 additions & 4 deletions ToolBoxLibUnitTests/TestDataBlockReading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using DotNetSiemensPLCToolBoxLibrary.DataTypes;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Blocks.Step7V5;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.Projectfolders.Step7V5;
using DotNetSiemensPLCToolBoxLibrary.DataTypes.AWL.Step7V5;
using NUnit.Framework;

namespace ToolBoxLibUnitTests
Expand All @@ -23,7 +24,7 @@ public void TestDB1()
PLCBlockType
.DB,
false,
fld, blk);
fld, blk, new S7ConvertingOptions());
Assert.AreEqual(test.Children[0].Name, "DB_VAR");
Assert.AreEqual(test.Children[1].Name, "aa");
Assert.AreEqual(test.Children[2].Name, "bb");
Expand All @@ -47,7 +48,7 @@ public void TestDB2()
PLCBlockType
.DB,
false,
fld, blk);
fld, blk, new S7ConvertingOptions());
Assert.AreEqual(test.Children[0].Name, "Fachkoordinate");
Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[0], 0);
Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[1], 1);
Expand All @@ -69,7 +70,7 @@ public void TestDB3()
PLCBlockType
.DB,
false,
fld, blk);
fld, blk, new S7ConvertingOptions());
Assert.AreEqual(test.Children[0].Name, "X_KOORDINATE");
Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[0], 0);
Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[1], 0);
Expand All @@ -93,7 +94,7 @@ public void TestDB4()
PLCBlockType
.DB,
false,
fld, blk);
fld, blk, new S7ConvertingOptions());
var rw = test.Children[0] as S7DataRow;
var callStr = rw.GetCallingString();
}
Expand Down

0 comments on commit bc98f21

Please sign in to comment.