Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
- Forum
- Discussions
- Feature Requests & Product Improvement Ideas
- Recursive function for finding datanodes, not returning all datanodes
Recursive function for finding datanodes, not returning all datanodes
Your code does not write out nodes that have no sub-nodes (the test "if (NodeCollection.Count > 0)"). It only writes out that is about to browse into. The part with StreamWriter should best be placed between the EasyUAClient.Browse AND the call to RecursiveBrowse (and become its own loop to go through the NodeCollection).
Best regards
Please Log in or Create an account to join the conversation.
Can you please try to use our Connectivity Explorer app to view the same server? It uses the same underlying QuickOPC methods, so the purpose of this test is to determine whether "our own" code works well, or not - based on that, we will know whether to look further into your code, or elsewhere.
The Connectivity Explorer is accessible from the Start menu or the Launcher. Please locate or enter your server's URL in the Point Editor window, right-click on it, and select "Navigate: To Address Space Browser". The full address space tree should then open in its own window. Expand the nodes as needed - and let me know whether in this view, all nodes that you expect are there or not.
Best regards
Please Log in or Create an account to join the conversation.
//When a button is clicked, call this background worker
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
UAEndpointDescriptor endpointDescriptor = "opc.tcp://" + PCNameTextBox.Text + ":4880/[SystemName]";
UANodeElementCollection NodeCollection = new UANodeElementCollection();
//grab the collection of nodes from our endpoint
try
{
NodeCollection = CM100Client.Browse(
endpointDescriptor,
UAObjectIds.ObjectsFolder,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References })
);
}
catch (Exception ex)
{
//Exception handling
}
RecursiveBrowse(NodeCollection, endpointDescriptor);
}
//Recursive function for browsing data nodes
private void RecursiveBrowse(UANodeElementCollection NodeCollection, UAEndpointDescriptor endpointDescriptor)
{
//If it has children keep going
if (NodeCollection.Count > 0)
{
//Next recursively get the data from each node on the OPC server.
foreach (UANodeElement nodeElement in NodeCollection)
{
//Write to file, savepath comes from user input
using (StreamWriter sw = new StreamWriter(Path.Combine(savepath, "[SystemName]ServerNodes.txt"), true))
{
sw.WriteLine("DisplayName: " + nodeElement.DisplayName);
//Other things written to the file here
sw.WriteLine("");
}
//Browse for the data nodes that are children of this one and browse deeper into the tree
UANodeElementCollection NewNodeCollection = new UANodeElementCollection();
try
{
NewNodeCollection = NewNodeCollection = CM100Client.Browse(
endpointDescriptor,
nodeElement.NodeId,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References })
);
RecursiveBrowse(NewNodeCollection, endpointDescriptor);
}
catch (Exception ex)
{
ResultsTextBox.AppendText(Environment.NewLine + ex.ToString());
}
}
}
else
{
return;
}
}
Please Log in or Create an account to join the conversation.
Please post here your current code, I will review it.
Best regards
Please Log in or Create an account to join the conversation.
Upon further inspection I see that the namespace numbers are assigned strangely. For instance, MRegs and CM100Events share ns=3. Would this have any bearing on the browsing?
Please Log in or Create an account to join the conversation.
In reality, the second argument to Browse is UANodeDescriptor, which comprises of UANodeId, UABrowsePath, or both. And there is an implicit conversion operator from UANodeElement to UANodeDescriptor. So in fact, you can also just use one of the UANodeElement-s returned from the Browse in place of the UANodeDescriptor argument to the lower-level Browse.
Best regards
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
OPC UA browsing uses filters to specify what you want, because getting "everything" is actually not that common. Methods like BrowseDataNodes already have specific filters built in - so that's why you are not getting everything.
In order to get everything, you need use the Browse method, and pass it a filter that does not exclude anything. Following example shows just that - it is non-recursive, but you'll get the point.
// Shows how to obtain references of all kinds to nodes of all classes, from the "Server" node in the address space.
using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples._EasyUAClient
{
class Browse
{
public static void Main1()
{
UAEndpointDescriptor endpointDescriptor =
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
// or "http://opcua.demo-this.com:51211/UA/SampleServer" (not in .NET Standard)
// or "https://opcua.demo-this.com:51212/UA/SampleServer/"
// Instantiate the client object
var client = new EasyUAClient();
// Obtain nodes under "Server" node
UANodeElementCollection nodeElementCollection;
try
{
nodeElementCollection = client.Browse(
endpointDescriptor,
UAObjectIds.Server,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References }));
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
return;
}
// Display results
foreach (UANodeElement nodeElement in nodeElementCollection)
{
Debug.Assert(nodeElement != null);
Console.WriteLine();
Console.WriteLine("nodeElement.NodeId: {0}", nodeElement.NodeId);
Console.WriteLine("nodeElement.DisplayName: {0}", nodeElement.DisplayName);
}
}
}
}
Best regards
Please Log in or Create an account to join the conversation.
I am trying to create a function that will discover all of the available datanodes on an OPC server and document what is in them. The problem I am having is that most of the OPC nodes are not being read in. Attached is a picture showing what nodes I can and can't find.
Is there something wrong with how I call BrowseDataNodes?
Is there something wrong with my method for recursively
browsing the tree?
//When a button is clicked, call this background worker
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
UAEndpointDescriptor endpointDescriptor = "opc.tcp://" + PCNameTextBox.Text + ":4880/[SystemName]";
UANodeElementCollection NodeCollection = new UANodeElementCollection();
//grab the collection of nodes from our endpoint
try
{
NodeCollection = EasyOPCClient.BrowseDataNodes(endpointDescriptor);
}
catch (Exception ex)
{
//Exception handling
}
RecursiveBrowse(NodeCollection, endpointDescriptor);
}
//Recursive function for browsing data nodes
private void RecursiveBrowse(UANodeElementCollection NodeCollection, UAEndpointDescriptor endpointDescriptor)
{
//If it has children keep going
if (NodeCollection.Count > 0)
{
//Next recursively get the data from each node on the OPC server.
foreach (UANodeElement nodeElement in NodeCollection)
{
//Write to file, savepath comes from user input
using (StreamWriter sw = new StreamWriter(Path.Combine(savepath, "[SystemName]ServerNodes.txt"), true))
{
sw.WriteLine("DisplayName: " + nodeElement.DisplayName);
//Other things written to the file here
sw.WriteLine("");
}
//Browse for the data nodes that are children of this one and browse deeper into the tree
UANodeElementCollection NewNodeCollection = new UANodeElementCollection();
try
{
NewNodeCollection = EasyOPCClient.BrowseDataNodes(endpointDescriptor, nodeElement.NodeId);
RecursiveBrowse(NewNodeCollection, endpointDescriptor);
}
catch (Exception ex)
{
ResultsTextBox.AppendText(Environment.NewLine + ex.ToString());
}
}
}
else
{
return;
}
}
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- Feature Requests & Product Improvement Ideas
- Recursive function for finding datanodes, not returning all datanodes