第二章:信息建模:概念1

REDISANT 提供互联网与物联网开发测试套件 #


为什么要进行信息建模? #

OPC UA 的基础是数据传输和信息建模。与传统 OPC 相比,数据传输已改为最先进的、独立于平台的、安全可靠的技术,并且信息建模能力得到了极大改善。在传统 OPC 中,仅提供“纯”数据,例如温度传感器测量的温度。唯一可用于理解所提供数据语义的信息是标签名称和一些基本信息,例如测量值的工程单位。OPC UA 提供了更强大的可能性来揭示所提供数据的语义。除了传统 OPC 提供的数据外,它还允许揭示信息,例如测量温度由特定类型的传感器设备提供,并允许在类型层次结构中揭示支持哪种设备。因此,OPC UA 客户端可以获得在不同位置处理同一种设备的信息。通过揭示更多语义,OPC UA 服务器允许客户端通过解释所提供数据的语义来处理高度复杂的任务。这包括自动集成由 OPC UA 服务器提供的数据以及从通用 OPC UA 客户端设计 OPC UA 服务器。

基本 OPC UA 规范仅提供建模信息的基础架构。供应商可以对信息进行建模,这当然会导致对类似信息进行建模的不同方式,从而使 OPC UA 客户端的工作变得困难。为了避免这种情况,OPC UA 规范提供了基于 OPC UA 定义信息模型规范的可能性。OPC 基金会已经开始了生成这些规范的活动。例如,有人努力定义一个基本模型,以在 OPC UA [UA 设备] 中公开设备信息和设备类型。供应商将使用此基本模型,并使用有关其设备的供应商特定信息对其进行扩展。客户端可以以相同的方式访问由不同的、特定于供应商的 OPC UA 服务器提供的设备信息,因为它们使用相同的基本模型以类似的方式公开。此外,供应商可以轻松无缝地将通过 OPC UA 公开其数据的第三方设备集成到其 OPC UA 服务器中,因为它们都使用相同的基本模型。这当然不仅适用于设备模型,也适用于其他场景,例如通过在 OPC UA 中公开 ISA 95 模型 [ISA95] 向 MES 或 ERP 系统提供数据。

OPC UA 中信息建模的基本原则如下:

  • **使用面向对象的技术,包括类型层次结构和继承。**类型实例允许客户端以相同的方式处理相同类型的所有实例。类型层次结构允许客户端使用基本类型并忽略更专业的信息。

  • **类型信息以与实例相同的方式公开和访问。**类型信息由 OPC UA 服务器提供,可以使用与访问实例相同的机制进行访问。这类似于关系数据库系统的信息模式,其中有关数据库表的信息在数据库表中管理,并可使用普通 SQL 语句访问 [ISO08b]。

  • **节点的全网状网络允许以各种方式连接信息。**OPC UA 允许支持多个层次结构,在这些层次结构的节点之间公开不同的语义和引用。因此,相同的信息可以以不同的方式公开,根据用例提供不同的路径和方式来在同一服务器中组织信息。

  • **关于类型层次结构以及节点之间引用类型的可扩展性。**OPC UA 在信息建模方面有多种可扩展方式。除了子类型的定义之外,它还允许例如指定定义节点和方法之间关系的其他引用类型,从而扩展 OPC UA 的功能。

  • **对于如何建模信息没有限制,以便为提供的数据提供适当的模型。**针对已经包含丰富信息模型的系统的 OPC UA 服务器可以在 OPC UA 中“本地”公开该模型,而不是将模型映射到其他模型。

  • OPC UA 信息建模始终在服务器端完成。 OPC UA 信息模型始终存在于 OPC UA 服务器上,而不是客户端。它们可以从 OPC UA 客户端访问和修改,OPC UA 服务器也可以具有访问其他 OPC UA 服务器的客户端部分。但一般来说,OPC UA 客户端不需要具有集成的 OPC UA 信息模型,也不必向 OPC UA 服务器提供此类信息。

让我们通过一个例子来检查 OPC UA 的建模能力。设备供应商提供了一个温度传感器,如图 1.1 所示。该设备具有一些配置参数和一些测量值,这些参数和测量值可能因配置而异。它使用前面提到的基本设备模型在 OPC UA 服务器中提供这些信息。

OPC UA 中的温度传感器和提供的数据

要理解该示例,了解 OPC UA 服务器在哪里运行以及它提供哪些附加信息并不重要。在最简单的情况下,OPC UA 服务器将直接在设备上运行;对于温度传感器等简单设备,OPC UA 服务器更可能在控制器或控制器顶部的 PC 上运行。任何 OPC UA 客户端都可以提供适当的用户界面,显示设备的测量值以及使用服务器提供的设备模型配置设备。该模型可以包括事件和历史数据。客户端可以使用通用用户界面(显示参数列表)或显示设备和主要参数的图形表示的专用用户界面。可以根据类型信息创建这些特定的用户界面。它们必须为一种类型仅实现或配置一次,并且可以用于该类型的每个实例或子类型的实例。因此,可以为设备模型的基本类型定义这样的用户界面,而无需公开任何特定于供应商的扩展。它还可以为根据特定供应商设备及其扩展量身定制的特定供应商类型进行定义。集成设备数据的最常见用例是在 DCS 中聚合它们并通过 DCS 将它们提供给客户端。在这种情况下,DCS 应充当 OPC UA 客户端来接收数据,并充当 OPC UA 服务器来公开数据。任何 OPC UA 客户端都可以通过 DCS 访问设备数据,而不会丢失任何功能。服务器包含多个设备信息的场景展示了利用类型信息知识进行编程的强大功能。例如,可以在一个图形中多次使用相同的图形元素,以显示工厂中的过程。图 1.2 概述了前面提到的 OPC UA 客户端用例。

不同场景如何使用 OPC UA 访问设备数据

本章概述了如何在 OPC UA 中建模信息。以下各节介绍了用于建模的 OPC UA 概念,从节点的基本概念及其之间的引用开始,解释包含具有变量、方法和事件的类型化对象的 OPC UA 对象模型,最后描述作为 OPC UA 元模型的 OPC UA 地址空间模型与针对某些领域定制的信息模型之间的差异。在下一章中,将给出一个关于如何在 OPC UA 中建模信息的详细示例,并提供一些最佳实践。

节点和引用 #

OPC UA 的基本建模概念是节点和节点之间的引用。节点可以属于不同的节点类,具体取决于节点的用途。有些节点表示实例,其他节点表示类型等。属性(Attribute)用于描述节点,并且根据节点类的不同,节点可以具有一组不同的属性。图 1.3 给出了一个示例。节点 1、节点 2 和节点 3 都包含属性,并被多个引用相连(引用 1-6)。

节点及节点间的引用

以下各节将介绍 OPC UA 的不同节点类。节点的属性取决于其节点类。但是,每个节点都有一些共同的属性。表 1.1 总结了这些属性。

公共属性
属性 数据类型 描述
NodeId NodeId 唯一地标识 OPC UA 服务器中的节点,并用于寻址 OPC UA 服务中的节点
NodeClass NodeClass 标识节点的节点类(如对象或方法)的枚举
BrowseName QualifiedName 浏览 OPC UA 服务器时标识节点。它未本地化
DisplayName LocalizedText 包含节点的名称,应用于在用户界面中显示名称。因此,它是本地化的
Description LocalizedText 此可选属性包含节点的本地化文本描述
WriteMask UInt32 是可选的,并指定节点的哪些属性是可写的,即可以由 OPC UA 客户端修改
UserWriteMask UInt32 是可选的,并指定当前连接到服务器的用户可以修改节点的哪些属性

NodeId 唯一地标识服务器中的节点。NodeId 是最重要的概念,它处理信息并在服务中交换以引用节点。服务器在浏览或查询地址空间时返回 NodeId,客户端使用 NodeId 在服务调用中寻址节点。一个节点可以有多个可用于寻址该节点的备选 NodeId。即使节点是由备选 NodeId 访问的,也可以通过读取 NodeId 属性来获取规范的 NodeId。NodeId 包含命名空间,允许不同的命名机构唯一地定义 NodeId。命名机构可以是组织、供应商或系统。有关 NodeId 及其数据类型的详细信息,请参见第 2.8.5 节。

BrowseName 仅用于浏览目的,不应用于显示节点的名称。BrowseName 对于特性(Property)(参见第 2.6 节)和使用类型信息知识进行编程(参见第 2.5.4 节)具有特殊含义。与 NodeId 一样,BrowseName 是一个包含命名空间和非本地化字符串的结构,如第 2.8.5 节所述。

DisplayName 和 Description 已本地化。第 2.8.5 节描述了有关本地化和数据类型 LocalizedText 的详细信息。

理论上,引用描述了两个节点之间的关系。因此,引用由引用的源节点、目标节点、引用的语义(引用类型,参见第 2.3 节)和引用的方向唯一标识。

实际上,服务器可能只在一个方向上公开引用,并且引用可能指向另一个 OPC UA 服务器中的节点或不存在的节点。因此,将引用视为存在于节点中并通过存储另一个节点的 NodeID 指向另一个节点的指针是有意义的。图 1.4 显示了对引用的这种看法。

此类引用指针包含被引用节点的 NodeID、管理被引用节点的 OPC UA 服务器、定义引用语义的引用类型(参见第 2.3 节)以及引用的方向。引用分为对称引用和非对称引用。

引用作为节点的指针

例如,非对称引用在一个方向上是“有父”而在另一个方向上是“是子”,而对称引用在两个方向上具有相同的语义,如“是兄弟”。在第一种情况下,引用的方向很重要,而在第二种情况下则无关紧要。

将引用视为指向其他节点的指针有助于理解 OPC UA 中为引用定义的约束或缺失约束。尽管引用连接两个节点,但 OPC UA 服务器可能只公开引用的一个方向,例如,图 1.4 中仅从节点 1 到节点 2 的指针,而不是反向。如果只公开一个方向,则引用称为单向的,否则称为双向的。指针可能指向服务器中不再存在的节点,也可能指向其他服务器中在特定时间点可能不可用或可能根本不可用的节点。客户端必须期望他们可能能够在一个方向上浏览引用,但不能在反向浏览引用,或者引用的节点不存在。

引用是无序的,也就是说,两次向节点请求其引用可能会导致引用集的顺序不同。但是,有些类型的引用定义了该类型的引用的顺序,例如 HasOrderedComponent [UA 第 3 部分]。服务器必须始终以相同的顺序返回这些引用。

节点的属性(Attribute)集由 OPC UA 规范定义,无法扩展。如果需要描述节点的其他信息,则必须使用特性(Property)(参见第 2.6 节)。

WriteMask 指示的可写属性集必须与 UserWriteMask 指示的可写属性集相同或为其超集,因为 WriteMask 定义了哪些属性可由任何用户修改。一般来说,对引用完整性的要求很低。引用可能指向同一服务器中不存在的节点,也可能指向客户端无法访问的其他服务器。引用可能只在一个方向上公开,并且引用可能导致循环。客户端必须能够处理这些不准确的数据。特定引用可能会对此进行限制,并对引用定义更高的约束(参见下一节)。

引用不包含任何属性(Attribute)或特性(Property)。如果需要在两个节点的关系中添加一些附加信息,则必须添加一个代理节点并由两个节点连接,而不是使用单个引用(有关如何使用代理节点的详细信息,请参阅第 3.3.8 节)。

引用类型 #

引用是两个节点之间的连接。引用不能直接访问,只能通过浏览节点并遵循引用来间接访问。引用不表示为节点,也不能包含任何属性或特性。但是,引用用于公开节点连接方式的不同语义。为了公开引用的语义,OPC UA 使用引用类型(ReferenceType)。引用类型定义引用的语义,每个引用都是类型化的,因此具有定义的语义。OPC UA 规范定义了一组引用类型。其中一些用于非常基本的地方,例如公开类型层次结构。但引用类型的概念是一个可扩展的概念,即 OPC UA 服务器可以定义自己的引用类型,公开引用的特定语义。为了组织引用类型,它们在类型层次结构中进行管理。

虽然引用不是节点,也没有属性,但引用类型在地址空间中作为节点公开。这样,客户端就可以通过访问 OPC UA 服务器地址空间中的节点来获取有关 OPC UA 服务器使用的引用的信息。表 1.2 总结了用于描述引用类型的属性。

ReferenceTypes 的属性
属性 数据类型 描述
包含表1.1中定义的所有公共属性
IsAbstract Boolean 指定 ReferenceType 是否可用于 References 或仅用于 ReferenceType 层次结构中的组织目的
Symmetric Boolean 表示 Reference 是否对称,即正向和反向含义是否相同
InverseName LocalizedText 此可选属性指定反向引用的语义。它仅适用于非对称引用,并且如果此类引用类型不是抽象的,则必须提供

除了这些属性之外,表 1.1 中描述的用于所有节点的通用属性也适用于 ReferenceType。其中一些属性在用于 ReferenceType 时有一些额外的约束。ReferenceType 的 BrowseName 在 OPC UA 服务器中必须是唯一的,以避免混淆具有不同语义但名称相同的多个 ReferenceType。DisplayName 必须包含 BrowseName 的本地化表示。BrowseName 以及 DisplayName 正向定义 ReferenceType 的语义,就像 InverseName 反向定义语义一样。

引用在 ReferenceType 层次结构中进行管理。这允许使用更专业的类型专门化现有的 ReferenceType。图 1.5 显示了由 OPC UA 规范定义的基本 ReferenceType 层次结构。它使用 OPC UA 符号来可视化 OPC UA 相关信息,如附录 A 中所述。附录 C 显示了由基本 OPC UA 规范定义的 ReferenceType 的完整层次结构。

基本引用类型层次结构

使用斜体字母的 ReferenceType 是抽象的,仅用于组织目的和过滤。第 5 章介绍了可以应用过滤的地方。如果过滤器中应考虑所有引用,则使用“References” ReferenceType。它有两个子类型,区分分层引用和非分层引用中的引用。当需要对层次结构进行建模时,应使用分层引用,非分层引用则用于其他目的,例如公开不同层次结构之间的关系。例如,非层次结构的 HasTypeDefinition 从实例引用到类型层次结构中的实例的类型。客户端应根据此使用引用,例如,在树控件中显示分层引用并过滤掉非层次结构的引用。

为了简化对 ReferenceType 的过滤,ReferenceType 层次结构仅支持单继承,即每个 ReferenceType 只有一个超类型。 例如,这保证了每个 ReferenceType 要么是分层 ReferenceType,要么是非分层 ReferenceType,但绝不会是两者。

1.5 中显示了一些分层引用的子类型。当两个节点应以分层方式连接时,使用 Organizes ReferenceType,而无需定义任何其他语义。使用此 ReferenceType 的一个示例是将文件系统映射到 OPC UA。文件夹可以作为节点公开,并可以使用 Organizes References 引用其子文件夹。Organizes Reference 或任何分层引用都不能保证在遵循这些引用时没有循环。图 1.6 给出了这样一个例子。在该示例中,存在两个层次结构。一个是组织设备,另一个包含配置信息。设备引用一些包含其配置的配置对象,但多个设备可以使用相同的配置,如 Device1 和 Device2,两者都使用配置 Config1。在配置层次结构中,组织了多个配置,其下有使用该配置的设备。如果在组合视图中查看这些层次结构,您会发现该层次结构中存在循环。查看该示例还表明,Organizes并不总是以分层方式引用节点的最佳选择。在该示例中,可以应用一些更具体的 ReferenceType。在介绍更多 ReferenceType 之后,我们将再次查看该示例。

层次结构中的循环示例

抽象的 HasChild Reference 不允许任何仅遵循其子类型的循环。因此,HasChild ReferenceType 定义了一个非循环层次结构。节点也可以组织在另一个层次结构中,因此遵循层次结构引用可能会导致节点,如图 1.7 所示。在这种情况下,使用 HasComponent ReferenceType,将设备的配置公开为设备的组件。作为抽象 Aggregates ReferenceType 的具体子类型,它继承了“is-part-of”语义。is-part-of 关系的性质是它不是循环的,也就是说,“A”的一部分不能有“A”作为子部分。请注意,不允许循环并不意味着节点不能有两个父节点,例如 Config1 是 Device1 和 Device2 的组件,因此在层次结构中有两个父节点。

结合配置层次结构,循环仍然是可能的。配置层次结构不能使用 HasComponent References;否则,继承的 HasChild ReferenceType 的非循环约束将被破坏。由于配置在逻辑上不包含它们配置的设备作为其一部分,因此使用 HasComponent ReferenceType 是没有意义的。

HasChild Reference 的另一个示例是 HasSubtype ReferenceType 公开类型层次结构(例如,在图 1.5 中的 ReferenceType 层次结构中使用)。在这种情况下,循环没有任何意义,因为类型不能是其自身的(间接)子类型。

允许层次结构引用中存在循环的原因是,服务器可能会在不同的层次结构中公开相同的节点,如图 1.7 所示。服务器可以在 HierarchicalReferences 下定义自己的 ReferenceType,用于公开其他层次结构。它们也可以选择使这些层次结构不循环,但与其他层次结构结合使用可能会产生循环,例如使用 HasChild References 的层次结构。当不需要定义其他层次结构,而只需指定引用的更具体语义时,其他 ReferenceType 应成为 HasChild ReferenceType 的子类型。

非循环和循环层次结构的示例

节点之间的引用受到限制。不允许在同一个节点之间两次提供相同方向的相同类型的引用。这包括 ReferenceType 的子类型,但不包括超类型。例如,允许具有不同类型的分层引用的引用,但不能使用 HasComponent 和 HasComponent 的子类型。关于相同类型的限制是模型固有的,因为引用是由源节点和目标节点以及 ReferenceType 定义的。为了避免服务器提供类型“A”的引用以及更专业的“A”子类型(称为“B”),不允许同时提供这两种引用。只应使用最合适的引用类型。使用子类型始终意味着超类型也有效。客户端在使用引用过滤器浏览或查询地址空间时必须考虑到这一点。

特定的引用类型进一步限制了引用类型的使用。这可能包括允许的源节点和目标节点(例如,限制 NodeClass 或具体类型)、引用在同一节点上使用的次数(例如,每个引用类型只能是一个 HasSubtype Reference 的目标[1])、是否允许循环(如 HasChild ReferenceType 所指定的那样)等。子类型只能进一步限制引用的使用;超类型的约束对子类型仍然有效。

没有标准化的方法来公开地址空间中引用类型的约束。然而,描述属性通常是放置约束的文本描述的好地方。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.redisant.cn