Professional OPC
Development Tools

logos

Retrieve information about mapping from DAClientMapper

More
20 Feb 2015 14:30 #2829 by support
If you could add an additional property to the object, for each property mapped to OPC, and use [MetaMember("NodeDescriptor")], you could then take .BrowsePath from these node descriptors.

But you probably wanted it with less coding - the way you suggested in your pseudo-code.

With some simplification, the browse path of the property is, actually, the browse path of the parent, combined with the name of the property. Therefore you can just take the parent browse path and add a "/" and a name of the property to it, and you are done.

The simplification lies in the fact that you can specify an OPC browse name for the property that is differ from its C# name, or even a completely different browse path or use an Item ID etc.

The resolution from a parent node descriptor to the one that relates to the specific mapped member is done by a method that is, unfortunately, 'private', on the DAMappingContext object. It may help you to show how it looks like:
        [NotNull]
        static private DANodeDescriptor ResolveNodeDescriptor(
            [CanBeNull] DANodeDescriptor nodeDescriptor,    // current descriptor from the context
            [CanBeNull] string nodePathTemplateString,    // current string from the context
            [CanBeNull] string itemIdTemplateString,    // current string from the context
            [NotNull] string memberName,
            [NotNull] DANodeAttribute nodeAttribute)
        {
            ContractUtils.RequiresNotNull(nodeAttribute, "nodeDescriptor");
            ContractUtils.RequiresNotNull(memberName, "memberName");
            ContractUtils.EnsuresNotNullResult<DANodeDescriptor>();
 
            // Determine the current context values, or supply defaults (*no* item ID, and an empty browse path).
            // ReSharper disable once AccessToStaticMemberViaDerivedType
            string nodePath = (nodeDescriptor == null) ? DANodeDescriptor.DefaultNodePath : nodeDescriptor.NodePath;
            string itemId = (nodeDescriptor == null) ? DANodeDescriptor.DefaultItemId : nodeDescriptor.ItemId;
            BrowsePath originalBrowsePath = ((nodeDescriptor == null) 
                // ReSharper disable once AccessToStaticMemberViaDerivedType
                ? DANodeDescriptor.DefaultBrowsePath 
                : nodeDescriptor.BrowsePath) ?? BrowsePath.Root;
 
            // Make a clone of the browse path, because we do not want to modify the original
            Contract.Assert(originalBrowsePath != null);
            BrowsePath browsePath = originalBrowsePath.Clone();
 
            // If browse path is not specified in the new node attribute, we will use the name of the member.
            string browsePathModifier = nodeAttribute.BrowsePath ?? BrowsePath.EscapeBrowseName(memberName);
            Contract.Assert(browsePathModifier != null);
 
            // Use the absolute browse path directly, or append a relative browse path to the current browse path.
            browsePath.Combine(browsePathModifier);
 
            if ((nodePathTemplateString == null) && !browsePathModifier.IsEmpty())
                // Invalidate existing node path.
                nodePath = null;
            if ((itemIdTemplateString == null) && !browsePathModifier.IsEmpty())
                // Invalidate existing item Id.
                itemId = null;
 
            string parentNodePath = nodePath;
            string parentItemId = itemId;
            // If the new node attribute specifies a node path, it overrides whatever we had so far.
            if (nodeAttribute.NodePath != null)
                nodePath = nodeAttribute.NodePath;
            else if (nodePathTemplateString != null)
            {
                // ReSharper disable once UseMethodAny.0
                Contract.Assume(browsePath.BrowseNames.Count() > 0);
                string browseName = browsePath.BrowseNames.Last();
                nodePath = ExpandNodeTemplate(nodePathTemplateString, parentNodePath, parentItemId, browseName);
            }
            // If the new node attribute specifies an item ID, it overrides whatever we had so far.
            if (nodeAttribute.ItemId != null)
                itemId = nodeAttribute.ItemId;
            else if (itemIdTemplateString != null)
            {
                string browseName = browsePath.BrowseNames.Last();
                itemId = ExpandNodeTemplate(itemIdTemplateString, parentNodePath, parentItemId, browseName);
            }
 
            return new DANodeDescriptor(nodePath, itemId, browsePath);
        }

Please Log in or Create an account to join the conversation.

More
19 Feb 2015 19:45 - 19 Feb 2015 19:46 #2822 by miron
ok,
below you can find ilustration of idea:
Device dev = new ....
 
var mapper = new DAClientMapper();
mapper.Map(dev, new DAMappingContext                                            
{                                                                               
    ServerDescriptor = sd,   // local OPC server                                                      
    NodeDescriptor = new DANodeDescriptor { BrowsePath = "/TestChannel/MainGroup/Line2/" + dev.DeviceCode}, 
			GroupParameters = 300,  
		});               				
};
 
next
 
var t = dev.GetType();
 
var props = t.GetProperties();
 
foreach(var p in props)
{
 
   //now for each property
   //I would like obtain full browse path
   //this path I would like to use to automaticlly generate 
   //OPCServer configuration
 
   //e.g.
  string p = mapper.GetMappingBrowsePath(p) 
 
}
 
Last edit: 19 Feb 2015 19:46 by miron.

Please Log in or Create an account to join the conversation.

More
19 Feb 2015 19:11 #2821 by support
I am sorry but I do not understand the question. Can you please give an example of what you are trying to achieve, or elaborate further.

Thank you.

Please Log in or Create an account to join the conversation.

More
19 Feb 2015 14:04 #2818 by miron
Maybe I will have to overloading one of this function:

protected override DAFolderMapping CreateFolderMapping(AbstractMapping parent, DAFolderAttribute folderAttribute);
protected override DAFolderSource CreateFolderSource(DAMappingContext mappingContext, DAMemberMappingDefinition memberMappingDefinition);
protected override DAItemMapping CreateItemMapping(AbstractMapping parent, DAItemAttribute itemAttribute);
protected override DAItemSource CreateItemSource(DAMappingContext mappingContext, DAMemberMappingDefinition memberMappingDefinition);
protected override DAPropertyMapping CreatePropertyMapping(AbstractMapping parent, DAPropertyAttribute propertyAttribute);
protected override DAPropertySource CreatePropertySource(DAMappingContext mappingContext, DAMemberMappingDefinition memberMappingDefinition);

Please Log in or Create an account to join the conversation.

More
19 Feb 2015 13:58 - 19 Feb 2015 14:17 #2817 by miron
Hi,
Hi I could retrieve information about mapping from DAClientMapper?

I mean mapping for give property type.
Thant means it should exists possibility to get this information by property info.

And it is necessary to obtain full, resolved browse path.

I am consider to automatically generation configuration for OPC Server by using reflection.

Thank you.
Last edit: 19 Feb 2015 14:17 by miron.

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.189 seconds

      

 Recommend this on Google