从 OPC UA 服务器读取结构化数据

Posted

技术标签:

【中文标题】从 OPC UA 服务器读取结构化数据【英文标题】:Read structured data from OPC UA server 【发布时间】:2021-02-08 12:57:02 【问题描述】:

我正在尝试使用opc-ua-client 库从 OPC UA 服务器读取一些数据。设法连接到服务器并读取一些简单的变量,但在读取结构化值时遇到问题。但是,我可以使用 3rd 方工具(例如,UAExpert)浏览这些结构化值。

这是代码sn-p:

var readRequest = new ReadRequest

    NodesToRead = new[]  new ReadValueId  NodeId = NodeId.Parse(nodeId), AttributeId = AttributeIds.Value  
;
var response = channel.ReadAsync(readRequest).Result;

var result = response.Results[0].GetValueOrDefault<ExtensionObject>();

重点是:我应该如何将 ExtensionObject 转换为底层的真实对象?响应的主体被二进制序列化为 System.Byte[] 字段,并且不知道如何反序列化它。我知道结构的字段和类型,所以在代码中定义(甚至用服务器提供的命名空间装饰)如下:

    [BinaryEncodingId("nsu=urn:OMRON:NxOpcUaServer:FactoryAutomation;i=5005")]
    private class MES_WRITE_STRUCT : Structure
    
        uint Message_NUM  get; set; 
        //Some other fields
        DateTime Time_Stamp  get; set; 
    

到目前为止我尝试过(但失败了)的事情:

蛮力演员:

var eObject = (MES_WRITE_STRUCT)result.GetValueOrDefault<ExtensionObject>();

将响应读取为预期类型,而不是使用通用对象:

var eObject = result.GetValueOrDefault<MES_WRITE_STRUCT>();

使用 Variant 属性而不是 Value(结果与 使用值):

result.Variant.GetValue();

创建一个二进制阅读器并尝试将其反序列化为预期的 类。

也许我使用了错误的方法,应该以不同的方式阅读结构化值。甚至该库也不支持结构化变量(可用的文档不多)。或者只是在 .NET 中定义自定义类时使用了不正确的类型,因此强制转换失败。

我完全被卡住了,欢迎提供任何信息或指导。

PS:我没有绑定到这个库,可以切换到另一个库(最好没有许可证,但如果真的值得考虑购买)。

【问题讨论】:

如果您找到了解决方案,您能否分享有关此问题的任何更新? 【参考方案1】:

一种方法是使用您希望使用的信息模型的 XML 描述(所谓的nodesets)并使用来自 OPC Foundation 的 model compiler 从中生成 C# 类。这些类可以集成到您的解决方案中并用于反序列化。

可以找到示例(使用 OPC 基金会库)here

【讨论】:

你有我可以看看的例子吗? 该示例已作为我的消息的一部分链接,here 是另一个。【参考方案2】:

另一种方法是 OPC Foundation .NET Standard 客户端,它有一个名为 complex client 的扩展库 nuget 包。它包含从字典 (V1.03) 或使用 DataTypeDefinition (V1.04) 从服务器读取结构化类型定义的逻辑。 基于获得的类型定义,可以发出结构化类型的类,以便在运行时对扩展对象中的字节字符串进行编码/解码。如果复杂的客户端难以解码您的结构化类型,请打开问题。

【讨论】:

以上是关于从 OPC UA 服务器读取结构化数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 opc ua 从 PLC 读取信号?

OPC UA open62541历史数据读取客户端未编译

opc-ua milo项目的骆驼路线

使用 C# 客户端读取 OPC UA 节点属性值

我应该从哪里开始使用 OPC-UA 客户端?

iNeuOS工业互联平台,增加OPC UA驱动,同步和订阅方式读取数据