Folks,
I expected some questions here. The silence might be for two reasons:
- the wrapper class is well understood and there is no need for more explanation
- it is not very clear how to use the wrapper class
Just in case of the second reason one, I will explain a little bit more in detail and the usage in a real application. The base of my GUI application is the attached tag list class. The instance of this class needs to be filled with the information provided by the EipTagListFactory wrapper. This is done with the following two methods.
The usage of the wrapper in words:
- Run thru the EipTagListFactory.TagNameCollection or the EipTagListFactory.TagInstanceIdCollection
- You will get the tag definition of all tags in the PLC - controller and program tags
- Read the template with the symbolType of each tag, e.g. template = eipTagListFactory.GetTemplateByInstance(tag.SymbolType);
- if you got a null pointer it is a plain tag, like BOOL, DINT, REAL[x.y.z] or whatever
- if you got a valid template pointer it is the detailled information of the structured tag which might contain further structured tags - therefore the tree list
/// <summary>
/// Returns the EipTagList as a workaround as long as the open source library does not support the templates of structured tags
/// </summary>
/// <param name="deviceName">The device name we are connected to</param>
/// <returns>The EipTagList with the tags in the PLC we are connected to</returns>
//-----------------------------------------------------------------------------------------
private EipTagList EipTagListFromEipTagListFactory(string deviceName)
//-----------------------------------------------------------------------------------------
{
string tagName, typeAsString, detailledTypeDescription;
UInt16 structureHandle;
EipTagListFactory.EipTag tag;
EipTagListFactory.EipTemplate template;
EipTagList eipTagList;
EipTagList childEipTagList;
// read all tag and the template of all structured tags from the PLC - throws an Exception on errors which needs to be caught by the caller
EipTagListFactory eipTagListFactory = new EipTagListFactory(this.DeviceIpAddress, this.DevicePort);
// instantiate an EipTagProcessor instance to get the tag types as string
EipTagProcessor eipTagProcessor = new EipTagProcessor();
// create the EipTagList instance as the base for the GUI interfacing
eipTagList = new EipTagList(deviceName); // the name of the PLC is the root
// show the browsing duration in the StatusBar
this.LblStatusLeft.Content = @"Browsing duration:" + String.Format(@" {0:0},{1:00} s", eipTagListFactory.Duration.Seconds, eipTagListFactory.Duration.Milliseconds);
// run thru the EipTagListFactory instance and fill the EipTagList instance which is the base of this GUI
foreach (var pair in eipTagListFactory.TagNameCollection)
{
structureHandle = 0;
tagName = pair.Key;
tag = pair.Value;
// get the template object instance or null if it is not a template
template = eipTagListFactory.GetTemplateByInstance(tag.SymbolType);
// create the symbol type as a string in a human readable form
typeAsString = eipTagProcessor.GetTagDataType(tag.SymbolType, tag.Dimensions, out detailledTypeDescription);
// create the default for plain symbols
typeAsString += @" - " + detailledTypeDescription;
// if it is a template, the type is the template name
if (template != null) typeAsString = template.TemplateName + @" - UDT (" + template.TransferredWireBytesOnRead.ToString() + @" Bytes)";
// if it is a template, set the StructureHandle for standard STRING indication - remember: handle 0xFCE is a STRING type
if (template != null) structureHandle = template.StructureHandle;
// add the tag to the list
childEipTagList = eipTagList.AddTag(eipTagList, tag.SymbolName, tag.ElementSize, (uint)tag.InstanceId, tag.SymbolType, typeAsString, tag.Dimensions, structureHandle);
// if the member is a template, we drill down
if (template != null) this.AddTemplateToTag(eipTagListFactory, template, childEipTagList);
}
return eipTagList;
}
/// <summary>
/// Adds the template data to the parent EipTagList
/// </summary>
/// <param name="eipTagListFactory">The EipTagListFactory instance object</param>
/// <param name="template">The template instance object</param>
/// <param name="parent">The EipTagList instance object of the parent</param>
//-----------------------------------------------------------------------------------------
private void AddTemplateToTag(EipTagListFactory eipTagListFactory, EipTagListFactory.EipTemplate template, EipTagList parent)
//-----------------------------------------------------------------------------------------
{
string typeAsString, detailledTypeDescription, plcAccessTagName;
uint[] dimensions = new uint[3] { 0, 0, 0 }; // the dimensions of the tag
EipTagProcessor eipTagProcessor = new EipTagProcessor(); // just to get the tag type as a string
EipTagListFactory.EipTemplate childTemplate;
EipTagList childEipTagList;
UInt16 structureHandle;
// run thru the EipTagListFactory.EipTemplateMember instance and fill the EipTagList instance
foreach (EipTagListFactory.EipTemplateMember member in template.TemplateMemberList)
{
// reset the previous settings of the structured member
structureHandle = 0;
// reset the previous dimension of the structured member
dimensions[0] = 0;
// get the template instance or null if it is not a template
childTemplate = eipTagListFactory.GetTemplateByInstance(member.MemberType);
// if it is an array set the array dimension which is defined in the member.MemberInfo property. Struct member arrays are always with a dimension[1]
if (eipTagListFactory.IsArrayTag(member.MemberType)) dimensions[0] = member.MemberInfo;
// create the symbol type as a string in a human readable form
typeAsString = eipTagProcessor.GetTagDataType(member.MemberType, dimensions, out detailledTypeDescription);
// create the default for plain symbols
typeAsString += @" - " + detailledTypeDescription;
// if it is template, the data type is the template name
if (childTemplate != null) typeAsString = childTemplate.TemplateName + @" - UDT (" + childTemplate.TransferredWireBytesOnRead.ToString() + @" Bytes)";
// if it is template, set the StructureHandle
if (childTemplate != null) structureHandle = childTemplate.StructureHandle;
// set the during drill down growing PlcAccessTagName for the element-wise access to the structured tag
plcAccessTagName = parent.PlcAccessTagName + @"." + member.MemberName;
// add the tag to the list - length and instanceId are not relevant here as the length is defined with the data type and the instanceId is the parent instanceId
childEipTagList = parent.AddTag(parent, member.MemberName, 0, 0, member.MemberType, typeAsString, dimensions, structureHandle, plcAccessTagName);
// if the member is a template, we need to place a recursive call as a drill down action
if (childTemplate != null) this.AddTemplateToTag(eipTagListFactory, childTemplate, childEipTagList);
}
}
Hope this helps a little bit.