在OPC UA(UA-.NETStandard)中创建自定义复杂数据类型

3

我刚接触OPC UA领域,有没有人能指导我如何使用OPCFoundation/UA-.NETStandard在c#中创建自定义复杂类型。在我的CreateAddressSpace方法中,我想创建一个名为“ABC”的节点,并使用类似于Person的自定义数据类型,Person将具有一些属性或属性,例如名称、年龄、ID以及字符串或整数数据类型。我希望通过代码完成所有这些操作,而不使用任何代码生成工具。

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


如果您想了解节点可以具有的属性,请参考统一自动化文档。如果下面给出的答案实际上不是您真正寻找的内容,请在该答案的评论中让每个人知道,或者如果您已经得到了答案,请将其标记为已接受。 - Naushad Warsi
1个回答

0

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

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

为了参考一个正在运行的项目请看一下


你能否在你的 Github 仓库中发布一个示例,让 C# 客户端读取数据? - Dominic Jonas
请查看同一个客户端项目这里您可以看到我正在从服务器读取节点,并且这里您可以看到我正在监视一些节点。如果这个答案符合您的要求,请将其标记为已接受。 - Naushad Warsi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接