Skip to content

Commit d4d2cbd

Browse files
committed
Browsing of arrays of struct or udt
1 parent 79eb9ac commit d4d2cbd

File tree

2 files changed

+381
-55
lines changed

2 files changed

+381
-55
lines changed

src/S7CommPlusDriver/ClientApi/Browser.cs

Lines changed: 122 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515

1616
using System;
1717
using System.Collections.Generic;
18-
using System.Linq;
19-
using System.Text;
20-
using System.Threading.Tasks;
2118

2219
namespace S7CommPlusDriver
2320
{
@@ -90,6 +87,12 @@ private void AddFlatSubnodes(Node node, string names, string accessIds)
9087
names += node.Name;
9188
accessIds += "." + String.Format("{0:X}", node.AccessId);
9289
break;
90+
case eNodeType.StructArray:
91+
names += node.Name;
92+
// TODO: Hier Besonderheit: Zwischen Array-Index und Zugriffs-ID steht noch eine 1.
93+
// Unklar ob die 1 fix ist, oder sich aus einem weiteren Wert ergibt.
94+
accessIds += "." + String.Format("{0:X}", node.AccessId + ".1");
95+
break;
9396
default:
9497
names += "." + node.Name;
9598
accessIds += "." + String.Format("{0:X}", node.AccessId);
@@ -134,6 +137,11 @@ public void BuildTree()
134137

135138
private void AddSubNodes(ref Node node, PObject o)
136139
{
140+
uint ArrayElementCount;
141+
int ArrayLowerBounds;
142+
uint[] MdimArrayElementCount;
143+
int[] MdimArrayLowerBounds;
144+
137145
int element_index = 0;
138146
// Sind in einem Bereich überhaupt keine Variablen vorhanden, dann ist diese Liste auch nicht vorhanden.
139147
if (o.VartypeList != null)
@@ -149,33 +157,73 @@ private void AddSubNodes(ref Node node, PObject o)
149157
node.Childs.Add(subnode);
150158
// Arrays verarbeiten
151159
// TODO: Besonderheiten der Übersichtlichkeit wegen in eigene Methoden auslagern.
152-
if (vte.OffsetInfoType.GetType() == typeof(POffsetInfoType_Array1Dim))
160+
161+
if (vte.OffsetInfoType.Is1Dim())
153162
{
154-
POffsetInfoType_Array1Dim oit = (POffsetInfoType_Array1Dim)vte.OffsetInfoType;
155-
Console.WriteLine("AddSubNodes: POffsetInfoType_Array1Dim");
156-
// Die Zugriffs-ID beginnt hier immer bei 0, unabhängig vom Inter
157-
for (uint i = 0; i < oit.ArrayElementCount; i++)
163+
#region Struct/UDT oder flaches Array mit einer Dimension
164+
165+
var ioit = (IOffsetInfoType_1Dim)vte.OffsetInfoType;
166+
ArrayElementCount = ioit.GetArrayElementCount();
167+
ArrayLowerBounds = ioit.GetArrayLowerBounds();
168+
169+
// Die Zugriffs-ID beginnt hier immer bei 0, unabhängig von Lowerbounds
170+
for (uint i = 0; i < ArrayElementCount; i++)
158171
{
159-
var arraynode = new Node
172+
// Struct Array gesondert behandeln/kennzeichnen. Hier ist noch eine zusätzliche ID hinter Array Index
173+
// und Zugriffs-LID vorhanden.
174+
175+
if (vte.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_STRUCT)
160176
{
161-
NodeType = eNodeType.Array,
162-
Name = "[" + (i + oit.ArrayLowerBounds) + "]",
163-
Softdatatype = vte.Softdatatype,
164-
AccessId = i
165-
};
166-
subnode.Childs.Add(arraynode);
177+
var arraynode = new Node
178+
{
179+
NodeType = eNodeType.StructArray,
180+
Name = "[" + (i + ArrayLowerBounds) + "]",
181+
Softdatatype = vte.Softdatatype,
182+
AccessId = i
183+
};
184+
subnode.Childs.Add(arraynode);
185+
186+
// Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
187+
var ioit2 = (IOffsetInfoType_Relation)vte.OffsetInfoType;
188+
189+
foreach (var ob in m_objs)
190+
{
191+
if (ob.RelationId == ioit2.GetRelationId())
192+
{
193+
AddSubNodes(ref arraynode, ob);
194+
break;
195+
}
196+
}
197+
}
198+
else
199+
{
200+
var arraynode = new Node
201+
{
202+
NodeType = eNodeType.Array,
203+
Name = "[" + (i + ArrayLowerBounds) + "]",
204+
Softdatatype = vte.Softdatatype,
205+
AccessId = i
206+
};
207+
subnode.Childs.Add(arraynode);
208+
}
167209
}
210+
#endregion
168211
}
169-
else if (vte.OffsetInfoType.GetType() == typeof(POffsetInfoType_ArrayMDim))
212+
else if (vte.OffsetInfoType.IsMDim())
170213
{
171-
POffsetInfoType_ArrayMDim oit = (POffsetInfoType_ArrayMDim)vte.OffsetInfoType;
172-
Console.WriteLine("AddSubNodes: POffsetInfoType_ArrayMDim");
214+
#region Struct/UDT oder flaches Array mehr als einer Dimension
215+
216+
var ioit = (IOffsetInfoType_MDim)vte.OffsetInfoType;
217+
ArrayElementCount = ioit.GetArrayElementCount();
218+
ArrayLowerBounds = ioit.GetArrayLowerBounds();
219+
MdimArrayElementCount = ioit.GetMdimArrayElementCount();
220+
MdimArrayLowerBounds = ioit.GetMdimArrayLowerBounds();
173221

174222
// Feststellen wie viele Dimensionen das Array besitzt
175223
int actdimensions = 0;
176224
for (int d = 0; d < 6; d++)
177225
{
178-
if (oit.MdimArrayElementCount[d] > 0)
226+
if (MdimArrayElementCount[d] > 0)
179227
{
180228
actdimensions++;
181229
}
@@ -190,7 +238,7 @@ private void AddSubNodes(ref Node node, PObject o)
190238
aname = "[";
191239
for (int j = actdimensions - 1; j >= 0; j--)
192240
{
193-
aname += (xx[j] + oit.MdimArrayLowerBounds[j]).ToString();
241+
aname += (xx[j] + MdimArrayLowerBounds[j]).ToString();
194242
if (j > 0)
195243
{
196244
aname += ",";
@@ -201,50 +249,82 @@ private void AddSubNodes(ref Node node, PObject o)
201249
}
202250
}
203251

204-
var arraynode = new Node
252+
if (vte.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_STRUCT)
205253
{
206-
NodeType = eNodeType.Array,
207-
Name = aname,
208-
Softdatatype = vte.Softdatatype,
209-
AccessId = id
210-
};
211-
subnode.Childs.Add(arraynode);
254+
var arraynode = new Node
255+
{
256+
NodeType = eNodeType.StructArray,
257+
Name = aname,
258+
Softdatatype = vte.Softdatatype,
259+
AccessId = id
260+
};
261+
subnode.Childs.Add(arraynode);
262+
263+
// Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
264+
var ioit2 = (IOffsetInfoType_Relation)vte.OffsetInfoType;
212265

266+
foreach (var ob in m_objs)
267+
{
268+
if (ob.RelationId == ioit2.GetRelationId())
269+
{
270+
AddSubNodes(ref arraynode, ob);
271+
break;
272+
}
273+
}
274+
}
275+
else
276+
{
277+
var arraynode = new Node
278+
{
279+
NodeType = eNodeType.Array,
280+
Name = aname,
281+
Softdatatype = vte.Softdatatype,
282+
AccessId = id
283+
};
284+
subnode.Childs.Add(arraynode);
285+
}
213286
xx[0]++;
214287
// Bei BBOOL-Arrays wird die ID bei Überlauf des kleinsten Array-Index immer auf ein Vielfaches von 8 gerundet.
215-
if (subnode.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_BBOOL && xx[0] >= oit.MdimArrayElementCount[0])
288+
if (subnode.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_BBOOL && xx[0] >= MdimArrayElementCount[0])
216289
{
217-
if (oit.MdimArrayElementCount[0] % 8 != 0)
290+
if (MdimArrayElementCount[0] % 8 != 0)
218291
{
219292
id += 8 - (xx[0] % 8);
220293
}
221294
}
222295
for (int dim = 0; dim < 5; dim++)
223296
{
224-
if (xx[dim] >= oit.MdimArrayElementCount[dim])
297+
if (xx[dim] >= MdimArrayElementCount[dim])
225298
{
226299
xx[dim] = 0;
227300
xx[dim + 1]++;
228301
}
229302
}
230303
id++;
231304
n++;
232-
} while (n <= oit.ArrayElementCount);
305+
} while (n <= ArrayElementCount);
306+
#endregion
233307
}
234-
235-
if (subnode.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_STRUCT)
308+
else
236309
{
237-
POffsetInfoType_Struct oit = (POffsetInfoType_Struct)vte.OffsetInfoType;
238-
foreach (var ob in m_objs)
310+
#region Struct/UDT aber keine Art von Array
311+
if (subnode.Softdatatype == Softdatatype.S7COMMP_SOFTDATATYPE_STRUCT)
239312
{
240-
if (ob.RelationId == oit.RelationId)
313+
// Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
314+
var ioit = (IOffsetInfoType_Relation)vte.OffsetInfoType;
315+
316+
foreach (var ob in m_objs)
241317
{
242-
AddSubNodes(ref subnode, ob);
243-
break;
318+
if (ob.RelationId == ioit.GetRelationId())
319+
{
320+
AddSubNodes(ref subnode, ob);
321+
break;
322+
}
244323
}
324+
// Es kann durchaus vorkommen, dass kein Eintrag gefunden wird, z.B. wenn ein Bereich wie Merker oder
325+
// Ausgänge leer ist. Darum nicht weiter als Fehler auswerten.
245326
}
246-
// Es kann durchaus vorkommen, dass kein Eintrag gefunden wird, z.B. wenn ein Bereich wie Merker oder
247-
// Ausgänge leer ist. Darum nicht weiter als Fehler auswerten.
327+
#endregion
248328
}
249329
element_index++;
250330
}
@@ -284,6 +364,7 @@ public enum eNodeType
284364
Undefined = 0,
285365
Root,
286366
Var,
287-
Array
367+
Array,
368+
StructArray
288369
}
289370
}

0 commit comments

Comments
 (0)