对象、变量和方法 #
OPC UA 中最重要的节点类是对象、变量和方法。这些概念也是面向对象编程的产物。对象具有变量和方法,并且可以触发事件。
变量节点类的节点表示一个值。值的数据类型取决于变量。客户端可以读取值、订阅值的更改以及写入值。例如,变量用于表示温度传感器测量的温度或设定点,以管理某些控制应用程序,但通常用于公开地址空间中未被引用或节点属性捕获的任何数据。这包括配置数据或描述节点的附加元数据。
方法节点类的节点表示一种方法,即由客户端调用并返回结果的方法。每个方法都指定客户端应使用的输入参数以及客户端应期望的输出参数。方法的目的是执行速度相对较快。客户端使用调用服务来调用方法(参见第 5 章),并且此服务调用的响应已包含结果。当服务器需要公开由客户端启动和控制的长时间运行的进程时,它们应该使用程序(参见第 4.8 节)。方法的示例包括打开阀门或启动电机,以及更复杂的任务,例如根据提供的输入值计算某些模拟结果。通常,当一组参数用作输入或输出或两者时,或者在服务器中以定义的方式触发特殊操作时,使用方法是有意义的。OPC UA 中的方法仅提供方法的签名。没有标准化的方法来获取或设置 OPC UA 服务器方法的实现。
对象节点类的节点用于构造地址空间。除了使用 DisplayName 和 Description 等属性描述节点之外,对象不包含其他数据。对象的值使用变量公开。对象不像变量那样包含值属性。对象可用于对变量、方法或其他对象进行分组。尽管 OPC UA 没有定义明确的所有权概念,但方法和变量始终属于对象(或对象类型。参见第 2.5 节)。方法始终在对象的上下文中调用。除了包含的方法和变量之外,对象还可以是 EventNotifier。客户端可以订阅 EventNotifier 以接收事件(参见第 2.10 节)。
图 1.8 总结了包含对象、变量和方法以及生成事件的对象的概念。对象 Motor 包含一个变量 Status,用于标识电机是否正在运行。客户端可以订阅此变量,因此当电机状态发生变化时,始终会收到通知。此外,电机还有一些配置变量,归类在另一个名为 Configuration 的对象下。客户端可以读取或订阅这些变量,也可以通过写入变量来更改配置。客户端可以调用 Start 和 Stop 方法来启动或停止电机。此外,客户端可以订阅电机的事件。例如,当电机进入维护状态并且不再正常工作时,它可以生成事件。电机对象可以使用特定的 ReferenceType 连接到其他对象,在示例中,它只引用另一个对象 Object1(通过 MyReferenceType 类型的引用)。在这种情况下,被引用的对象不被视为电机的一部分。
对象、变量和方法概述
Object 节点类的唯一附加属性用于标识 Object 是否可以用作 EventNotifier,即客户端是否可以订阅 Object 以接收事件或读取或更新事件的历史事件。如表 1.3 所示。
属性 | 数据类型 | 描述 |
---|---|---|
包含表1.1中定义的所有公共属性 | ||
EventNotifier | Byte | 此属性表示一个位掩码,用于标识对象是否可用于订阅事件,以及事件的历史记录是否可访问和更改 |
变量提供真实数据,因此属性的数量要多得多。这些属性总结在表 1.4 中。
属性 | 数据类型 | 描述 |
---|---|---|
包含表1.1中定义的所有公共属性 | ||
Value | 未固定;由其他属性指定 | 变量的实际值。值的数据类型由 DataType、ValueRank 和 ArrayDimensions 属性指定 |
DataType | NodeId | DataType表示地址空间中的节点。此属性包含此类节点的 NodeId,从而定义Value属性的数据类型 |
ValueRank | Int32 | 标识值是否为数组,如果是数组,则允许指定数组的维度 |
ArrayDimensions | UInt32[] | 此可选属性允许指定数组的大小,并且仅当值是数组时才可使用。对于数组的每个维度,相应的条目定义维度的长度 |
AccessLevel | Byte | 一个位掩码,指示Value属性的当前值是否可读可写,以及值的历史记录是否可读可改 |
UserAccessLevel | Byte | 包含与 AccessLevel 相同的信息,但考虑了用户访问权限 |
MinimumSamplingInterval | Duration | 此可选属性提供 OPC UA 服务器检测Value属性更改的速度信息。对于不由服务器直接管理的值,例如温度传感器的温度,服务器可能需要扫描设备以查找更改(轮询),因此无法以比此最小间隔更快的速度检测更改 |
Historizing | Boolean | 指示服务器当前是否收集值的历史记录。AccessLevel 属性不提供该信息,它仅指定是否有一些历史记录可用 |
Value属性的数据类型由 DataType、ValueRank 和 ArrayDimensions 属性定义。之所以有三个属性,是因为 OPC UA 内置了对多维数组的支持。客户端可以只读取或写入数组的一部分,也可以订阅数组的一部分。因此,DataType 仅指定基本类型,其他属性定义是否使用 DataType 的数组或矩阵,以及数组或矩阵的大小(可选)。有关 DataType 的更多详细信息,请参见第 2.8 节。不使用引用来指示数据类型的原因是,某些变量可能经常更改数据类型,因此客户端可能希望订阅它们。在 OPC UA 中,跟踪引用的更改要困难得多,如第 2.11.3 节所述。
为了避免对定义Value的数据类型的属性产生混淆,我们在表 1.5 中提供了如何使用这些属性的示例。
值 | DataType | ValueRank | ArrayDimensions |
---|---|---|---|
"Just a String" | String | -1(Scalar) | - |
{1,2,3} | |||
{4,7,9,12} | Int16 | 1(OneDimension) | - |
{1,2,3} | |||
{3,4,8} | UInt16 | 1(OneDimension) | {3} |
1 | |||
{1,4,9} | |||
{1,2}{1,5} | UInt32 | -2(Any) | - |
{3,4}{1,2}{3,4} | Int32 | 2(two dimensions) | {2,3} |
{123,123} | |||
{1,2}{1,1}{2,4} | UInt64 | 0(OneOrMoreDimensions) | - |
WriteMask 和 AccessLevel、UserWriteMask 和 UserAccessLevel 之间的主要区别在于 AccessLevel 仅与Value属性相关。除了 WriteMask 指示的写入访问之外,它还捕获当前数据的读取访问以及对历史数据的读写访问。因此,可选的 WriteMask 属性排除了变量的Value属性,这意味着信息不会重复,并且客户端必须始终访问强制性的 AccessLevel 属性才能接收该信息。
方法的属性总结在表 1.6 中。对于方法节点类,地址空间模型中引入的概念已用于形成地址空间模型。方法的输入和输出参数不是在属性中描述的,而是在属于该方法的 OPC UA 变量中描述的。这样可以使除Value属性之外的所有属性数据类型保持简单,因为定义方法参数的复杂参数结构是在变量的Value属性中提供的。由于大多数方法都需要这些变量,表 1.6 不仅包含方法节点类的属性,还包含用于定义方法参数的标准变量(或更准确的标准特性,即第 2.6 节中描述的特殊变量)。
属性(Attribute) | 数据类型 | 描述 |
---|---|---|
包含表1.1中定义的所有公共属性 | ||
Executable | Boolean | 一个标志,指示该方法是否可以立即调用 |
UserExecutable | Boolean | 与可执行属性相同,但要考虑用户访问权限 |
特性(Property) | ||
InputArguments | Argument[] | 此可选属性定义该方法的输入参数数组。数组的顺序定义参数的顺序。如果未提供该属性,则该方法没有输入参数 |
OutputArguments | Argument[] | 与方法输出的输入参数相同 |
表 1.7 总结了Argument数据类型的结构。方法的每个参数的描述包含名称、文本描述和数据类型的定义。这里,使用与变量节点类相同的机制。
Name | 数据类型 | 描述 |
---|---|---|
Name | String | 参数名称 |
DataType | NodeId | DataType 节点的 NodeId |
ValueRank | Int32 | 指示参数是标量值、数组还是矩阵 |
ArrayDimensions | UInt32[] | 可选定义数组或矩阵的大小 |
Description | LocalizedText | 参数描述 |
让我们看看面向对象编程语言中的方法如何映射到方法节点类。目前,我们不考虑方法如何绑定到对象,这将在第 2.5 节介绍对象类型时完成。在图 1.9 中,使用伪代码显示了方法签名。此方法称为Encrypt,以key和data作为输入,并返回加密数据和加密数据的长度。图 1.9 也显示了到 OPC UA 的映射。在 OPC UA 中,创建了一个名为Encrypt的方法,该方法具有用于输入和输出参数的变量。方法的输入参数的描述由 InputArguments 变量的 Value 属性提供。方法的返回值和名为 length 的输出参数均由 OutputArguments 变量的Value属性提供。由于方法的返回值未命名,因此必须为该参数生成一个名称。在示例中,所有参数都没有描述。当然,如果有描述,则添加描述是合理的,例如,从方法的注释中。
将伪代码中的方法映射到 OPC UA
仅使用对象和变量即可提供 Classic OPC 的全部功能。通过使用 OPC UA 方法,您可以避免使用只写项来指定输入参数和启动方法,并使用只读项作为输出参数。
变量必须始终属于另一个节点。因此,它们必须被另一个节点引用(通过 HasComponent 或 HasProperty 引用类型)。第 2.6 节详细介绍了不同类型的变量,称为数据变量和特性。
方法必须属于一个对象(或对象类型),因此必须被另一个节点引用(通过 HasComponent 引用类型)。方法可以在对象(或对象类型)上被调用(该对象通过 HasComponent 引用该方法)。
每个对象和每个变量都必须有类型,即用一个 HasTypeDefinition 引用指向一个对象类型或变量类型(详细信息可在第 2.5 节中找到)。但是,这个要求很容易满足。如果没有可用的实际类型信息或由于某些原因不应公开,则可以使用 OPC UA 定义的基本类型。
Redisant提供互联网与物联网开发测试套件:
互联网与中间件:
- Redis Assistant
- ZooKeeper Assistant
- Kafka Assistant
- RocketMQ Assistant
- RabbitMQ Assistant
- Pulsar Assistant
- HBase Assistant
- NoSql Assistant
- Etcd Assistant
- Garnet Assistant
工业与物联网:
- MQTT Assistant
- Modbus 从站模拟器
- Modbus 主站模拟器
- IEC104/101 主站/客户端 模拟器
- IEC104/101 从站/服务端 模拟器
- IEC61850 客户端模拟器
- IEC61850 服务端模拟器
- DL/T 645 主站模拟器
- BACnet 浏览与模拟器
- COMTRADE 图表浏览
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.redisant.cn