Search code examples
c#opc-uaunified-automation-sdk

Creating instance of custom opcua object type node


Noobie OPCUA user here. I built a custom object type using UA Modeler, which as far as I understand creates a class of x custom object with y properties. My issue is with creating a node instance of that in my server. I'm looking for something that would allow me to do: Node test = new object node of type x custom object. I know that I could recreate my custom object in code, but that wouldn't be very smart... I think this is a very simple issue, but I can't find how to fix it in documentation or in the servers. Unless this is the way?

CreateObjectSettings settings = new CreateObjectSettings()
                {
                    // All the settings
                    TypeDefinitionId = ObjectTypeIds.MyCustomObject,
                };
                CreateObject(Server.DefaultRequestContext, settings);

Thanks for the help :)


Solution

  • You are on the right track.

    Here is a function I wrote to create custom objects based on the type passed-in. Notice that you have to lock the nodes and make sure that the node does not already exist.

    private ObjectNode CreateOpcObject(NodeId parentNodeId, string nodeName, string identifier, uint type,
            bool inRootFolder, bool isParentAsOwner, string description = "")
        {
            ObjectNode newNode = null;
    
            lock (InMemoryNodeLock)
            {
                if (FindInMemoryNode(new NodeId(identifier, DefaultNamespaceIndex)) == null)
                {
                    if (!inRootFolder && FindInMemoryNode(parentNodeId) == null)
                    {
                        log.Warn("Cannot create OPC object because parent node is not found for nodeName {nodeName}, identifier {identifier}.", nodeName, identifier);
                        return null;
                    }
    
                    var settings = new CreateObjectSettings
                    {
                        ParentNodeId = parentNodeId,
                        ParentAsOwner = isParentAsOwner, // cannot set this to true since it makes deleting much slower
                        ReferenceTypeId = ReferenceTypeIds.Organizes,
                        RequestedNodeId = new NodeId(identifier, DefaultNamespaceIndex),
                        BrowseName = new QualifiedName(nodeName, DefaultNamespaceIndex),
                        TypeDefinitionId = new NodeId(type, DefaultNamespaceIndex),
                        DisplayName = nodeName,
                        Description = description
                    };
    
                    newNode = CreateObject(Server.DefaultRequestContext, settings);
                }
                else
                {
                    log.Warn("Cannot create OPC object because identifier is not found for nodeName {nodeName}, identifier {identifier}.", nodeName, identifier);
                }
            }
            return newNode;
        }
    

    Notice that you can to do this instead of just assigning the type to the TypeDefinitionId:

    TypeDefinitionId = new NodeId(type, DefaultNamespaceIndex),
    

    You call this by doing something like this:

    var newNode = CreateOpcObject(parentNodeId, newNodeName, newNodeId, Model.ObjectTypes.MyGeneratedType, false, true, "This is a description of the new node object.");