3

I am new to the OPC UA world. Can anybody guide my how to create a custom complex type in c# using OPCFoundation/UA-.NETStandard.In my CreateAddressSpace method I want to create a node 'ABC' with custom datatype like Person and Person will have some attributes or properties like name, age, id with string or int data types. I want to done all this by code without using any code generating tool.

Also can anybody refer me to proper documentation as original documentation by OPCFoundation/UA-.NETStandard (Github repository) is not quite helpfull.

Yasir
  • 47
  • 2
  • if you want to understand about the attribute a node can have I would like you to refer [Docs of Unified Automtion](http://documentation.unified-automation.com/uasdkdotnet/2.0.0/L2UaNodeClasses.html). If the answer given below is not actually what you are really looking for, let everyone know in the comment of that answer, or if you have got the answer mark it as accepted. – Naushad Warsi Sep 25 '19 at 05:49

1 Answers1

0

if you don't want to use code generator then you have two ways to write Information model,

1): You can Manually write XML file Starting the base Object State And Add the keep adding the references. for Example,

<?xml version="1.0" encoding="utf-8"?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" xmlns:s1="http://yourorganisation.org/PlainNode/Types.xsd" xmlns:ua="http://unifiedautomation.com/Configuration/NodeSet.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <NamespaceUris>
    <Uri>http://www.umati.info/</Uri>
  </NamespaceUris>
  <Aliases>
    <Alias Alias="Int16">i=4</Alias>
    <Alias Alias="UInt32">i=7</Alias>
    <Alias Alias="Organizes">i=35</Alias>
    <Alias Alias="HasTypeDefinition">i=40</Alias>
    <Alias Alias="HasProperty">i=46</Alias>
  </Aliases>
  <Extensions>
    <Extension>
      <ua:ModelInfo Tool="UaModeler" Hash="QR4Ef3OTG3i8Dtg13aqRiQ==" Version="1.5.1"/>
    </Extension>
  </Extensions>
  <UAObject NodeId="ns=1;i=5002" BrowseName="1:SimpleFolder">
    <DisplayName>SimpleFolder</DisplayName>
    <References>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
      <Reference ReferenceType="Organizes">ns=1;i=6002</Reference>
      <Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
    </References>
  </UAObject>
  <UAVariable DataType="Int16" NodeId="ns=1;i=6002" BrowseName="1:MyInt" UserAccessLevel="3" AccessLevel="3">
    <DisplayName>MyInt</DisplayName>
    <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5002</Reference>
      <Reference ReferenceType="HasProperty">ns=1;i=6001</Reference>
    </References>
    <Value>
      <uax:Int16>0</uax:Int16>
    </Value>
  </UAVariable>
  <UAVariable DataType="UInt32" ParentNodeId="ns=1;i=6002" NodeId="ns=1;i=6001" BrowseName="StateNumber">
    <DisplayName>StateNumber</DisplayName>
    <References>
      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=6002</Reference>
    </References>
  </UAVariable>
</UANodeSet>

2): YOu can write the complete information model in C# Code

Example:


            {
                FolderState MachineTools = new FolderState(null)
                {
                    SymbolicName = "Root1",
                    ReferenceTypeId = ReferenceTypes.Organizes,
                    TypeDefinitionId = ObjectTypeIds.FolderType,
                    NodeId = new NodeId(1, NamespaceIndex),
                    BrowseName = new QualifiedName("Root1", NamespaceIndex),
                    DisplayName = new LocalizedText("MachineTools", "MachineTools"),
                    WriteMask = AttributeWriteMask.None,
                    UserWriteMask = AttributeWriteMask.None,
                    EventNotifier = EventNotifiers.None
                };


                BaseObjectState root = new BaseObjectState(MachineTools)
                {
                    NodeId = new NodeId(10, NamespaceIndex),
                    BrowseName = new QualifiedName("MachineTool", NamespaceIndex),
                    DisplayName = new LocalizedText("MachineTool", "MachineTool"),
                    TypeDefinitionId = ObjectTypeIds.BaseObjectType,
                };
                MachineTools.AddChild(root);



                // ensure the root object can be found via the server object.  
                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out IList<IReference> references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List<IReference>();
                }
                MachineTools.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);
                references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, MachineTools.NodeId));



                BaseDataVariableState<string> BuildYear = _BuildYear = new BaseDataVariableState<string>(Identification)
                {
                    NodeId = new NodeId(1011, NamespaceIndex),
                    BrowseName = new QualifiedName("Build Year", NamespaceIndex),
                    DisplayName = new LocalizedText("BuildYear", "BuildYear"),
                    TypeDefinitionId = VariableTypeIds.BaseDataVariableType,
                    ReferenceTypeId = ReferenceTypeIds.HasProperty,
                    DataType = DataTypeIds.String,
                    ValueRank = ValueRanks.Scalar,
                    Timestamp = DateTime.UtcNow,
                    StatusCode = StatusCodes.Good,
                    AccessLevel = AccessLevels.CurrentReadOrWrite,
                    UserAccessLevel = AccessLevels.CurrentReadOrWrite
                };
                Identification.AddChild(BuildYear);

for the reference of a working Project take a look

  • Could you also post an example at your github repo for the c# client side to read the data? – Dominic Jonas Oct 02 '19 at 13:10
  • Please take a look at the same [Client project](https://github.com/NakWarsi/OPC_CLIENT_DotNet_Explorer/blob/master/ClientTest1/ClientOPC.cs) , [here](https://github.com/NakWarsi/OPC_CLIENT_DotNet_Explorer/blob/d71811da82e8396f85ec10688326633bb0a66c2b/ClientTest1/ClientOPC.cs#L199) you can see I am reading the noe from the server and [herre](https://github.com/NakWarsi/OPC_CLIENT_DotNet_Explorer/blob/d71811da82e8396f85ec10688326633bb0a66c2b/ClientTest1/ClientOPC.cs#L212) you can see I am monitoring some nodes. if this answer gives you what you wanted please mark it as accepted – Naushad Warsi Oct 03 '19 at 05:41