将动态结构写入 OPC UA 服务器(c#、.NetStandard)

问题描述 投票:0回答:1

我是 OPC UA 的新手,可能会完全错误,但也许这里有人可以帮助我。我有一个在西门子 S7-1500 PLC 上运行的 OPC UA 服务器,并使用我的 C# 应用程序连接到它。我的应用程序是一个向 PLC 提供配置数据的控制软件。编写基本数据类型就像一个魅力,基本类型的数组也是如此。我面临的问题是 PLC 将具有在我的应用程序编译时未知的自定义结构。这就是为什么我实现了一个系统来动态创建反映 PLC 自定义结构的对象。这样,当 PLC 端引入新的自定义结构时,我不必发布应用程序的新版本。 当写入自定义结构时,我将应用程序中的日期编码为字节数组。这对于单个结构体来说效果很好。但是当我尝试编写此类自定义结构的数组时,我收到 BadTypeMismatch 错误。

这是我编写结构的代码的样子:

var nodeId = GetNodeId(path);
Dictionary<uint, DataValue> nodeAttributes = ReadNodeAttributes(nodeId.ToString());
DataTypeNode dataTypeNode = (DataTypeNode)ReadNode(nodeAttributes[Attributes.DataType].ToString());

//Get the structure definition
StructureDefinition structureDefinition = (StructureDefinition)dataTypeNode.DataTypeDefinition.Body;
ExtensionObject ExtensionObject = new ExtensionObject();
ExtensionObject.TypeId = structureDefinition.DefaultEncodingId;
ExtensionObject.Body = ConvertParameterToByteArray(parameter);
DataValue dataValue = new DataValue(ExtensionObject);

//Setup for the WriteValue
WriteValue writeValue = new WriteValue();
writeValue.NodeId = nodeId;
writeValue.Value = dataValue;
writeValue.AttributeId = Attributes.Value;
//Add the created value to the collection
collection.Add(writeValue);

我想编写一个此类结构的数组,我只需创建一个字节数组,从元素的数量开始,然后是各个结构的串联字节数组。我哪里错了?

c# .net-standard opc-ua
1个回答
0
投票

我终于知道如何解决我的问题了。我现在正在读取数组第一个元素的结构信息,并使用此信息告诉 OPC UA 服务器如何解释数组的每个元素。我仍然不知道为什么我需要首先告诉 OPC UA 服务器如何解释数据,因为它已经知道应该得到什么。 下面是我的代码,以防其他人遇到类似问题。

var innerNode = GetNodeId(path+"[0]");
Dictionary<uint, DataValue> nodeAttributes = ReadNodeAttributes(nodeId.ToString());
DataTypeNode dataTypeNode = (DataTypeNode)ReadNode(nodeAttributes[Attributes.DataType].ToString());

//Get the structure definition
StructureDefinition structureDefinition = (StructureDefinition)dataTypeNode.DataTypeDefinition.Body;

ExtensionObject[] values = new ExtensionObject[customTable.Count];
int i = 0;
foreach (IStructParameter param in customTable)
{
    values[i] = new ExtensionObject();
    values[i].TypeId = structureDefinition.DefaultEncodingId; ;
    values[i].Body = ConvertParameterToByteArray(param);
    i++;
}
WriteValue writeValue = new WriteValue();
writeValue.NodeId = nodeId;
DataValue dataValue = new DataValue(values);
writeValue.Value = dataValue;
writeValue.AttributeId = Attributes.Value;
//Add the created value to the collection
collection.Add(writeValue);
© www.soinside.com 2019 - 2024. All rights reserved.