Skip to content

Commit

Permalink
Get CPU ordernumber (MLFB) from CPUFolders.
Browse files Browse the repository at this point in the history
Attempt at reading out the MLFB from *.s7h files in the "s7hstatx" folder.

The byte sequence that define the position of the MLFB string in the file
appear to be different among PLC types, thus the different seqeuences
are all tested against. However, there may be more sequences that should
be added, but it must be tested with more Step7 projects. Currently tested
with 7 different CPU types.

Probably there is another way to identify the location of the MLFB string
that is more deterministic than this pragmatic method. Hopefully someone
will find that way.

Another weakness with this method is that for one out of 35 projects tested,
the s7h file did not exist. Only after a HWConfig recompile was it created.
Maybe it was last compiled by on old Step7 version, or there have been
an error of some kind.
  • Loading branch information
fleibede committed Apr 21, 2020
1 parent 41f6d86 commit fd41ede
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class CPUFolder : Step7ProjectFolder, IHardwareFolder
internal int TobjId;
public PLCType CpuType { get; set; }

public string MLFB_OrderNumber { get; set; }

public string PasswdHard { get; set; }

public int Rack { get; set; }
Expand Down
57 changes: 57 additions & 0 deletions LibNoDaveConnectionLibrary/Projectfiles/Step7ProjectV5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,63 @@ override protected void LoadProject()
}
}

//Get The CPU Order number (MLFB)
foreach (var y in CPUFolders)
{
string filepath = ProjectFolder + "hOmSave7" + _DirSeperator +
"s7hstatx" + _DirSeperator + y.UnitID.ToString("x") + ".s7h";
if (!_ziphelper.FileExists(filepath))
continue; //In some projects the s7h files does not exist, but is created after a HWconf recompile (v5.6 SP1 HF5).

Stream s7h = _ziphelper.GetReadStream(filepath);
BinaryReader rd = new BinaryReader(s7h);
byte[] completeBuffer = rd.ReadBytes((int)_ziphelper.GetStreamLength(filepath, s7h));
rd.Close();
s7h.Close();

// Byte sequence before information about each slot on the rack.
string[] checkSequences = {
ASCIIEncoding.ASCII.GetString(new byte[] { 0x0a, 0x00, 0x03 }),// 319-3 (EL00/01), 317-2DP
ASCIIEncoding.ASCII.GetString(new byte[] { 0x0c, 0x00, 0x03 }),// 317T-3 PN/DP
ASCIIEncoding.ASCII.GetString(new byte[] { 0x09, 0x00, 0x03 }) // PLCType.SimaticRTX
};
string buffer = ASCIIEncoding.ASCII.GetString(completeBuffer);
List<IEnumerable<int>> hitsList = new List<IEnumerable<int>>();
foreach ( string checkSeq in checkSequences)
{
//Find the indexes of the matches in the byte-buffer.
var matches = System.Text.RegularExpressions.Regex.
Matches(buffer, checkSeq).Cast<System.Text.
RegularExpressions.Match>().Select(m => m.Index);
// If the byte address i higher than 2000, it is most likely
// not the CPU MLFB that is found.
if (matches.Count() > 0 && matches.ElementAt(0) < 2000)
{
hitsList.Add(matches);
}
}
// Sort the list by the result with most matches.
hitsList.Sort((a,b) => b.Count() - a.Count());
// Take the result with the most matches.
IEnumerable<int> matchList = hitsList.First();

// The first hit has e.g. slot1, power supply etc.
// The second hit has the CPU information
if (matchList.Count() < 2)
continue;

//The length of the text field is the byte before the text field.
//First two fields are seperated by bytes "03 20 20 32"
int descrStart = matchList.ElementAt(1);
int dscr1_length = completeBuffer[descrStart + 6]; // CPU Name
int dscr2_length = completeBuffer[descrStart + 6 + dscr1_length + 5]; // CPU Name
int dscr3_length = completeBuffer[descrStart + 6 + dscr1_length + 5 + dscr2_length + 1]; // CPU MLFB
int dscr3_position = descrStart + 6 + dscr1_length + 5 + dscr2_length + 2;
string descr3 = ASCIIEncoding.ASCII.GetString(completeBuffer, dscr3_position, dscr3_length);

y.MLFB_OrderNumber = descr3;
}

//Get The CPU(ET200S)...
if (_ziphelper.FileExists(ProjectFolder + "hOmSave7" + _DirSeperator + "s7hkcomx" + _DirSeperator + "HOBJECT1.DBF"))
{
Expand Down

0 comments on commit fd41ede

Please sign in to comment.