UaServer_CreateInstance with optional child nodes

Questions regarding the use of the ANSI C SDK for Server or Client development or integration into customer products ...

Moderator: uasdkc

Post Reply
JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

UaServer_CreateInstance with optional child nodes

Post by JeromeBos »

When I call the UaServer_CreateInstance() function, the mandatory child nodes are automatically created. I would like to select some of the optional child nodes as well. I believe the a_pOptionalNodePath argument is meant for this purpose. Is this assumption correct? Unfortunately I have no idea how to use it. Could you provide an example?

This is what I tried, but doesn't work:

Code: Select all

UaServer_OptionalNodePath optional_nodes;

num_elements = 2;
optional_nodes.Elements = (OpcUa_QualifiedName*)OpcUa_Alloc(sizeof(OpcUa_QualifiedName)*num_elements);
optional_nodes.NoOfElements = num_elements;
UaBase_CreateQualifiedNameEx(&optional_nodes.Elements[0], "pCustomVar1", g_SomeNamespaceIndex);
UaBase_CreateQualifiedNameEx(&optional_nodes.Elements[1], "pCustomVar2", g_SomeNamespaceIndex);

uStatus = UaServer_CreateInstance(&pNode,&newId,&refTypeId,"NewNode","NewNode",2,&optional_nodes);
...
edit:

Alright, I think I figured it out:

Code: Select all

UaServer_OptionalNodePath p_optional_nodes[2];
OpcUa_QualifiedName names_1[1];
OpcUa_QualifiedName names_2[1];

p_optional_nodes[0].Elements = names_1;
p_optional_nodes[0].NoOfElements = 1;
UaBase_CreateQualifiedNameEx(&names_1[0], "pCustomVar1", g_SomeNamespaceIndex);

p_optional_nodes[1].Elements = names_2;
p_optional_nodes[1].NoOfElements = 1;
UaBase_CreateQualifiedNameEx(&names_2[0], "pCustomVar2", g_SomeNamespaceIndex);

uStatus = UaServer_CreateInstance(&pNode,&newId,&refTypeId,"NewNode","NewNode",2,p_optional_nodes);
...
This seems to work. Any suggestions to improve this code are obviously welcome.

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: UaServer_CreateInstance with optional child nodes

Post by JeromeBos »

I have a follow-up question. How do I select the optional nodes of sub-components to be derived as well?

For example, given the following Type tree:

Code: Select all

BaseObjectType
|- CustomAddInType (Reference=HasSubType)
| |- CustomVariable (Reference=HasComponent, ModellingRule=Optional)
|
|-CustomType (Reference=HasSubType)
| |- CustomAddIn (Reference=HasComponent, TypeDefinition=CustomAddInType, ModellingRule=Mandatory)
Now when I call UaServer_CreateInstance to create an Instance of CustomType I would like to derive the CustomVariable as well. The result should look like this:

Code: Select all

Objects
|- CustomObject (HasTypeDefinition=CustomType)
|  |- CustomAddIn (HasTypeDefinition=CustomAddInType)
|  |  |- CustomVariable
This is what I tried, but doesn't work:

Code: Select all

UaBase_CreateQualifiedNameEx(&Custom_CustomAddIn_CustomVariable_QN, "/CustomAddIn/CustomVariable", g_SomeNamespaceIndex);

optionalNodePaths[0].Elements = &Custom_CustomAddIn_CustomVariable_QN;
optionalNodePaths[0].NoOfElements = 1;

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: UaServer_CreateInstance with optional child nodes

Post by JeromeBos »

I have another follow-up question. Can the UaServer_CreateInstance() function also implement child-nodes from different namespaces?

Example:

Code: Select all

CustomType (NamespaceIndex=2)
|- CustomChild1 (Reference=HasComponent, ModellingRule=Mandatory, NamespaceIndex=2)
|- CustomChild2 (Reference=HasComponent, ModellingRule=Mandatory, NamespaceIndex=3)

Or do I have to create a SubType to make this work?

Code: Select all

CustomType (NamespaceIndex=2)
|- CustomChild1 (Reference=HasComponent, ModellingRule=Mandatory, NamespaceIndex=2)
|- CustomSubType (Reference=HasSubType, NamespaceIndex=3)
|  |- CustomChild2 (Reference=HasComponent, ModellingRule=Mandatory, NamespaceIndex=3)

User avatar
Support Team
Hero Member
Hero Member
Posts: 3069
Joined: 18 Mar 2011, 15:09

Re: UaServer_CreateInstance with optional child nodes

Post by Support Team »

Hello JeromeBos,

your assumption about the a_pOptionalNodePath argument is correct, it's used for selection optional child nodes that shall be created.


In response to your first follow-up: assuming following type tree, you can use the code after the type tree to instantiate CustomType including the optional child of CustomAddInType:

Code: Select all

BaseObjectType
|- CustomAddInType (Reference=HasSubType)
| |- CustomVariable (Reference=HasComponent, ModellingRule=Optional)
|
|- CustomType (Reference=HasSubType)
| |- CustomAddIn (Reference=HasComponent, TypeDefinition=CustomAddInType, ModellingRule=Mandatory)

Code: Select all

IFMETHODIMP(UaProvider_Demo_AfterInitialize)()
{
    OpcUa_StatusCode ret = OpcUa_Good;
    OpcUa_BaseNode *pNode = OpcUa_Null, *pParentNode = OpcUa_Null;
    OpcUa_NodeId nodeId, typeId;

    OpcUa_QualifiedName nodePathElements[2];
    UaServer_OptionalNodePath optionalNodePath[1];

    UaBase_SetDefaultNamespace(g_UaProviderDemo_uNamespaceIndex1);
    UaBase_CreateNumericNodeId(&nodeId, 1234);
    UaBase_CreateNumericNodeId(&typeId, Demo_CustomTypeId);

    nodePathElements[0].NamespaceIndex = g_UaProviderDemo_uNamespaceIndex1;
    OpcUa_String_AttachReadOnly(&nodePathElements[0].Name, "CustomAddIn");

    nodePathElements[1].NamespaceIndex = g_UaProviderDemo_uNamespaceIndex1;
    OpcUa_String_AttachReadOnly(&nodePathElements[1].Name, "CustomVariable");

    optionalNodePath[0].NoOfElements = 2;
    optionalNodePath[0].Elements = nodePathElements;

    ret = UaServer_CreateInstance(&pNode,
                                  &nodeId,
                                  &typeId,
                                  "DynamicNode",
                                  "DynamicNode",
                                  1,
                                  optionalNodePath);
    OpcUa_ReturnErrorIfBad(ret);

    UaBase_CreateStringNodeId(&nodeId, Demo_Objects_Demo);
    pParentNode = UaServer_GetNodeById(&nodeId);
    UaBase_CreateNumericNodeIdEx(&typeId, OpcUaId_HasComponent, 0);

    ret = OpcUa_BaseNode_AddReferenceToNode(pParentNode, pNode, &typeId, OpcUa_True);
    OpcUa_ReturnErrorIfBad(ret);

    return ret;
}

In response to your second follow-up: all child nodes of a type will be created, independent of their namespace. The namespace of the resulting instance nodes will be the same as the namespace of the a_pNodeId parameter passed to UaServer_CreateInstance.


For further questions, for a better overview please ask only one question per thread.

Best regards
Unified Automation Support Team

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: UaServer_CreateInstance with optional child nodes

Post by JeromeBos »

Thank you, this works wonderfully.

Post Reply