private NodeId GetAggregateFunctionsObjectId(Session session)
{
// build the list of browse paths to follow by parsing the relative paths.
BrowsePathCollection browsePaths = m_mapper.GetRemoteBrowsePaths(
Opc.Ua.ObjectIds.Server_ServerCapabilities,
"/HistoryServerCapabilities/AggregateFunctions");
// make the call to the server.
BrowsePathResultCollection results;
DiagnosticInfoCollection diagnosticInfos;
ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
null,
browsePaths,
out results,
out diagnosticInfos);
// ensure that the server returned valid results.
Session.ValidateResponse(results, browsePaths);
Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);
NodeId aggregateFunctionsNodeId = Opc.Ua.ObjectIds.Server_ServerCapabilities_AggregateFunctions;
for (int ii = 0; ii < results.Count; ii++)
{
// check if the start node actually exists.
if (StatusCode.IsBad(results[ii].StatusCode))
{
Utils.Trace("HistoryServer does not provide the ServerCapabilities object.");
continue;
}
// an empty list is returned if no node was found.
if (results[ii].Targets.Count == 0)
{
Utils.Trace("HistoryServer does not provide the AggregateFunctions folder.");
continue;
}
// Multiple matches are possible, however, the node that matches the type model is the
// one we are interested in here. The rest can be ignored.
BrowsePathTarget target = results[ii].Targets[0];
if (target.RemainingPathIndex != UInt32.MaxValue || target.TargetId.IsAbsolute)
{
Utils.Trace("HistoryServer does not provide the AggregateFunctions folder.");
continue;
}
// convert to a local node.
aggregateFunctionsNodeId = ExpandedNodeId.ToNodeId(target.TargetId, session.NamespaceUris);
}
return aggregateFunctionsNodeId;
}