如何在node-opcua中向Wago PLC(750-8202)写入Variant类型数据?
node-opcua写入WAGO PLC ExtensionObject类型节点的正确方式
你遇到的错误是因为写入ExtensionObject类型时,没有按node-opcua要求的格式构造ExtensionObject实例——缺少类型标识(typeId),且没有传入完整的结构体数据。从读取结果看,目标节点是自定义结构体Telerupteur,写入时需要严格匹配该结构体的类型定义和完整字段。
解决步骤
- 获取
Telerupteur类型的NodeId:可以通过读取目标节点的DataType属性得到该结构体的类型NodeId,也能在WAGO PLC的工程配置里查找该自定义类型的节点标识(格式通常为ns=...;i=...或ns=...;s=...)。 - 构造完整的ExtensionObject写入数据:node-opcua要求ExtensionObject类型的value必须包含
typeId(指向结构体类型的NodeId)和body(结构体的完整数据,即使只修改单个字段,也要保留其他字段的当前值或默认值)。
修正后的代码示例
// 假设通过读取DataType属性获取到Telerupteur类型的NodeId为"ns=4;i=1234" const telerupteurTypeId = "ns=4;i=1234"; // 构造完整的结构体数据,仅修改需要更新的manual_switch字段 const telerupteurData = { nomTechnique: "Lumiere_Bureau", nom: "Bureau", manual_switch: true, manual_ON: false, manual_OFF: false, export_state: true }; // 执行写入操作 const statusCode = await this.session.write({ nodeId: "ns=4;s=|var|WAGO 780-8202.Maison_V3.Telerupteurs.Bureau", attributeId: AttributeIds.Value, // 直接使用node-opcua的枚举值,不要加引号 value: { sourceTimestamp: new Date(), // 传入Date实例,而非字符串 value: { dataType: DataType.ExtensionObject, // 使用node-opcua的DataType枚举 value: { typeId: telerupteurTypeId, body: telerupteurData } } } });
关键注意事项
- typeId必须准确:这是PLC端定义的
Telerupteur结构体的唯一标识,没有它node-opcua无法正确序列化数据。 - 结构体字段要完整:WAGO PLC要求写入自定义结构体时必须传入所有字段,仅传修改字段会导致数据不合法。
- 避免语法错误:
sourceTimestamp直接传new Date()实例,不要加引号;attributeId和dataType使用node-opcua提供的枚举值,确保代码已引入对应模块。
内容的提问来源于stack exchange,提问作者Alexis Jotz
相关产品推荐
相关产品推荐

