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.");