首页 > 解决方案 > 在 OPC UA (UA-.NETStandard) 中创建自定义复杂数据类型

问题描述

我是 OPC UA 世界的新手。任何人都可以指导我如何使用 OPCFoundation/UA-.NETStandard 在 c# 中创建自定义复杂类型。在我的 CreateAddressSpace 方法中,我想创建一个具有自定义数据类型的节点“ABC”,例如 Person,Person 将具有一些属性或属性,例如名称,年龄,id 字符串或 int 数据类型。我想通过代码完成所有这些,而不使用任何代码生成工具。

任何人都可以向我推荐适当的文档,因为 OPCFoundation/UA-.NETStandard(Github 存储库)的原始文档不是很有帮助。

标签: c#opc.net-standard-2.0opc-uacomplex-data-types

解决方案


如果您不想使用代码生成器,那么您有两种编写信息模型的方法,

1):您可以手动编写 XML 文件启动基本对象状态并添加不断添加引用。例如,

<?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):你可以用C#代码编写完整的信息模型

例子:


            {
                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);

供参考的工作项目看看


推荐阅读