2. OPC UA核心概念精讲

OPC UA 与传统的 Modbus、IEC 104 等协议最大的区别,在于它不只是"传值",而是先描述"值属于谁、是什么、和谁有关系"。这套描述机制就是地址空间(Address Space)。理解地址空间、节点、引用和信息模型这四个概念,是后续把储能站设备(PCS、BMS、EMS、空调、消防等)接入 OPC UA 的前提。

一、地址空间:服务器对外暴露的"对象世界"

OPC UA 服务器内部维护一个统一的地址空间,客户端通过 Browse(浏览)和 Read(读取)访问它。地址空间不是一张扁平的点表,而是一棵由节点和引用构成的图。它通常包含几个标准入口:

  • Objects:实例对象,如某台 PCS、某个电池簇。
  • Types:类型定义,如 ObjectType、VariableType,用于约束实例。
  • Views:视图,是对地址空间的子集投影,可按设备或按功能组织。

储能站集成时,我们通常把设备实例挂在 Objects 下,把自定义类型挂在 Types 下,再用 View 给不同角色(运维、调度、诊断)提供不同视角。

二、节点:地址空间的最小单元

地址空间中每个元素都是一个节点(Node),用 NodeId 唯一标识。NodeId 由命名空间索引(NamespaceIndex)和标识符(Identifier)组成,例如 ns=2;s=PCS01.ActivePower。节点有八种基本类别,储能集成中最常用的是:

  • Object:设备或部件,如 PCS01、BatteryCluster03。
  • Variable:可读写的数据点,如 ActivePower、SOC、CellVoltageMax。
  • Method:可被调用的操作,如 Start、Stop、Reset。
  • ObjectType / VariableType:类型定义,用于批量实例化。

每个节点都带有一组属性(Attribute),最常用的是 NodeId、BrowseName、DisplayName、DataType、ValueRank、AccessLevel。其中 DataType 决定客户端如何解析值,AccessLevel 决定是否可写,这两项在储能站联调时最容易出错。

三、引用:把节点连成有意义的结构

节点之间靠引用(Reference)连接。引用是有方向的、有类型的。常见引用类型包括:

  • Organizes:组织关系,如 Objects 文件夹下挂设备。
  • HasComponent:组成关系,如 PCS01 包含 ActivePower 变量。
  • HasProperty:属性关系,如变量带 EngineeringUnits。
  • HasTypeDefinition:实例指向其类型定义。

正是这些引用,让客户端可以"从一台 PCS 出发,顺着 HasComponent 找到它的所有测点",而不需要预先知道每个点的完整路径。这也是 OPC UA 相比点表协议更适合储能站这种多设备、多层级场景的原因。

四、信息模型:从"点"到"设备语义"

信息模型(Information Model)是地址空间 + 节点 + 引用的组合结果,它把原始数据组织成有语义的结构。OPC UA 提供了配套规范,如 DI(设备集成)、PLCopen、以及面向能源行业的 Companion Specification。储能站建模时,通常按"站—设备—部件—测点"四层组织:

StorageStation
 ├─ PCS01 (Object, Type: PowerConversionSystemType)
 │   ├─ ActivePower   (Variable, Double, kW, RW)
 │   ├─ ReactivePower (Variable, Double, kVar, RW)
 │   ├─ RunState      (Variable, Enum, R)
 │   └─ Start()       (Method)
 ├─ BatteryCluster03 (Object, Type: BatteryClusterType)
 │   ├─ SOC           (Variable, Double, %, R)
 │   ├─ SOH           (Variable, Double, %, R)
 │   └─ CellVoltageMax(Variable, Double, V, R)
 └─ HVAC01 (Object, Type: HVACType)
     └─ SupplyAirTemp (Variable, Double, ℃, R)

注意每个 Variable 都带 DataType、EngineeringUnits 和 AccessLevel,这些不是装饰,而是客户端正确显示和写入的依据。

五、与储能站设备模型的映射关系

把储能站实际设备映射到 OPC UA 地址空间,核心是三步:确定层级、确定类型、确定引用。下面这张图展示了从物理设备到地址空间的映射路径,以及各层使用的引用类型。

储能站物理设备 → OPC UA 地址空间映射 物理设备层 储能站 StorageStation PCS 01 功率变换系统 电池簇 03 BatteryCluster 空调 01 HVAC 测点/信号 映射 OPC UA 地址空间 Objects ns=0;i=85 StorageStation Object · ns=2;s=Station Organizes PCS01 Object BatteryCluster03 Object HVAC01 Object HasComponent ActivePower Double · kW · RW RunState Enum · R SOC Double · % · R CellVoltageMax Double · V · R SupplyAirTemp Double · ℃ · R HasComponent PowerConversion SystemType HasTypeDefinition Organizes / HasComponent 变量引用 类型定义

映射时有三条经验值得记住。第一,层级不要超过四层:站—设备—部件—测点,再深会让 Browse 路径过长,客户端遍历效率下降。第二,类型先行:先定义 PCS 类型、电池簇类型,再批量实例化,避免每台设备手工建点。第三,引用要成体系:设备用 HasComponent 挂测点,测点用 HasProperty 挂单位、量程、报警限值,这样客户端读一个变量就能拿到完整语义。

在储能站项目中,建议把 NodeId 的命名规则固定下来,例如 ns=2;s=<设备编号>.<测点名>,并写入集成规范。这样即使设备增减,客户端脚本也只需按规则拼接 NodeId,而不必维护一张易错的手工点表。

六、一个容易踩的坑:命名空间索引

NodeId 中的 NamespaceIndex 是服务器启动时动态分配的,不同服务器、不同重启后可能变化。因此客户端不应硬编码 ns=2,而应在连接后读取服务器的 NamespaceArray,按命名空间 URI 查找索引。储能站集成中,常见做法是给本站模型分配一个固定 URI,如 http://example.com/storage/,客户端按 URI 定位索引,再拼接标识符。

把地址空间、节点、引用、信息模型这四件事串起来看:地址空间是容器,节点是单元,引用是骨架,信息模型是语义。储能站设备模型映射的本质,就是用这四件工具,把物理世界里的"站—设备—部件—测点"忠实、可遍历、可扩展地搬到 OPC UA 服务器里。做到这一点,后续的数据采集、订阅、写入控制才有稳定的基础。