Dennis Lee
Dennis Lee

Reputation: 93

How to add my self-defined node to OPC UA Server using the OPC UA .NET StandardLibrary

I am a noob to establish an OPC UA Server using tehe .NET Standardenter link description here when I want to add the new self-defined node to the OPC Server, it cannot generate the node correctly,below is my code

  public override void CreateAddressSpace(IDictionary<NodeId, IList<IReference>> externalReferences)
    {
        lock (Lock)
        {
            LoadPredefinedNodes(SystemContext, externalReferences);

            // find the untyped Boiler1 node that was created when the model was loaded.
            BaseObjectState passiveNode = (BaseObjectState)FindPredefinedNode(new NodeId(Objects.Boiler1, NamespaceIndexes[0]), typeof(BaseObjectState));
            BaseObjectState passiveNode2 = (BaseObjectState)FindPredefinedNode(new NodeId(SelfDefined.Objects.DefinedModel, NamespaceIndexes[0]), typeof(BaseObjectState));

            // convert the untyped node to a typed node that can be manipulated within the server.
            m_boiler1 = new BoilerState(null);
            m_boiler1.Create(SystemContext, passiveNode);

            m_test1 = new TestVariableState(null);
            m_test1.Create(SystemContext, passiveNode2);

            // replaces the untyped predefined nodes with their strongly typed versions.
            AddPredefinedNode(SystemContext, m_boiler1);
            AddPredefinedNode(SystemContext, m_test1);

            // create a boiler node.
            m_boiler2 = new BoilerState(null);
           m_test2 = new TestVariableState(null);

            // initialize it from the type model and assign unique node ids.
            m_boiler2.Create(
                SystemContext,
                null,
                new QualifiedName("Boiler #2", NamespaceIndexes[1]),
                null,
                true);

            m_test2.Create(
                SystemContext,
                null,
                new QualifiedName("Value #2", NamespaceIndexes[1]),
                null,
                true
                );

            // link root to objects folder.
            IList<IReference> references = null;

            if (!externalReferences.TryGetValue(Opc.Ua.ObjectIds.ObjectsFolder, out references))
            {
                externalReferences[Opc.Ua.ObjectIds.ObjectsFolder] = references = new List<IReference>();
            }

            references.Add(new NodeStateReference(Opc.Ua.ReferenceTypeIds.Organizes, false, m_test2.NodeId));

            // store it and all of its children in the pre-defined nodes dictionary for easy look up.
            AddPredefinedNode(SystemContext, m_boiler2);
            AddPredefinedNode(SystemContext, m_test2);

            // start a simulation that changes the values of the nodes.
            m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000);
        }
    }

m_test1 and m_test2 is defined by me and the boiler is the original node in the BoilerServer. And all the node is generated by the ModelCompiler of the OPCFoundation:enter link description here

Upvotes: 1

Views: 1444

Answers (1)

koepalex
koepalex

Reputation: 195

You wrote that you used the Opc.Ua.ModelCompiler, so I assume that you have generated your own model and added the own classes to the solution. Did you specified the new namespaces in constructor of BoilerNodeManager?

string[] namespaceUrls = new string[4];
namespaceUrls[0] = Namespaces.Boiler;
namespaceUrls[1] = Namespaces.Boiler + "/Instance";
namespaceUrls[2] = <EnterYourNamespace>;
namespaceUrls[3] = <EnterYourNamespace> + "/Instance";
SetNamespaces(namespaceUrls);

This collection must be extended with your own namespaces and than you have to update the NamespaceIndexes:

BaseObjectState passiveNode2 = (BaseObjectState)FindPredefinedNode(new NodeId(SelfDefined.Objects.DefinedModel, NamespaceIndexes[2]), typeof(BaseObjectState));
//..
m_test2.Create(
  SystemContext,
  null,
  new QualifiedName("Value #2", NamespaceIndexes[3]),
  null,
  true);

Upvotes: 1

Related Questions