我做了一个测试程序(修改了this代码)从我的opc ua服务器(siemens s7-1200)浏览到节点:
using (var session = Session.Create(config, new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)), false, "", 60000, null, null).GetAwaiter().GetResult())
{
Console.WriteLine("Step 3 - Browse the server namespace.");
ReferenceDescriptionCollection refs;
byte[] bts;
session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts, out refs);
Console.WriteLine("DisplayName: BrowseName, NodeClass");
foreach (var rd in refs.Where(r => r.DisplayName == "ServerInterfaces"))
{
Console.WriteLine("{0}: {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
ReferenceDescriptionCollection refs2;
byte[] bts2;
session.Browse(null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts2, out refs2);
foreach (var nextRd in refs2)
{
ReferenceDescriptionCollection refs3;
byte[] bts3;
Console.WriteLine("NameSpace+ {0}: {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
session.Browse(null, null, ExpandedNodeId.ToNodeId(nextRd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts3, out refs3);
foreach (var nextRd2 in refs3.Where(n => n.DisplayName != "Icon"))
{
NodeId nodeId = new NodeId(nextRd2.NodeId.ToString());
var value = session.ReadValue(nodeId);
Console.WriteLine("Node+ {0}: {1}, {2}, NodeId = {3}, Value = {4}", nextRd2.DisplayName, nextRd2.BrowseName, nextRd2.NodeClass, nextRd2.NodeId, value);
}
}
}
我面临的问题是数组。我的 OPC ua 服务器中有一组 INT。目前这是控制台显示的内容:
ServerInterfaces: 3:ServerInterfaces, Object
NameSpace+ Server interface_1: 4:Server interface_1, Object
Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
Node+ IntValue1: 4:IntValue1, Variable, NodeId = ns=4;i=7, Value = 100
这是我的预期输出:
ServerInterfaces: 3:ServerInterfaces, Object
NameSpace+ Server interface_1: 4:Server interface_1, Object
Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
Node+ read: 4:read[0], Variable, NodeId = ns=4;i=3, Value = 1
Node+ read: 4:read[1], Variable, NodeId = ns=4;i=4, Value = 1
Node+ read: 4:read[2], Variable, NodeId = ns=4;i=5, Value = 1
Node+ read: 4:read[3], Variable, NodeId = ns=4;i=6, Value = 1
Node+ IntValue1: 4:IntValue1, Variable, NodeId = ns=4;i=7, Value = 100
如何更改此代码(或新代码)以获得预期的输出?
我做了另一个程序来获取每个节点。奇怪的是我可以从一些自动生成的内容中得到一个数组:
ServerProfileArray: System.String[]
[0] Variable = http://opcfoundation.org/UA-Profile/Server/StandardUA
[1] Variable = http://opcfoundation.org/UA-Profile/Server/Methods
[2] Variable = http://opcfoundation.org/UA-Profile/Server/StandardEventSubscription
[3] Variable = http://opcfoundation.org/UA-Profile/Server/DataAccess
但是当我进行“阅读”时,它仍然不显示数组项:
read
read:
我想通了,所以更好的答案仍然值得赞赏(:
Using:
var references = session.FetchReferences(nodeId);
您可以从一个节点获取所有引用。您还将获得更多您可能不需要的信息,但您可以稍后将其过滤掉。
foreach (var ref3 in refs3.Where(n => n.DisplayName != "Icon"))
{
NodeId nodeId = new NodeId(ref3.NodeId.ToString());
var value = session.ReadValue(nodeId);
Console.WriteLine("----------------------");
Console.WriteLine("Node+ {0}: {1}, {2}, NodeId = {3}, Value = {4}", ref3.DisplayName, ref3.BrowseName, ref3.NodeClass, ref3.NodeId, value);
var references = session.FetchReferences(nodeId);
if (references != null)
{
Console.WriteLine("array");
foreach (var reference in references.Where(r => r.NodeClass.ToString() == "Variable"))
{
Console.WriteLine(reference.BrowseName + " NodeId: " + reference.NodeId.ToString());
}
}
Console.WriteLine("----------------------");
}
输出:
Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
array
4:[0] NodeId: ns=4;i=3
4:[1] NodeId: ns=4;i=4
4:[2] NodeId: ns=4;i=5
4:[3] NodeId: ns=4;i=6