/// <summary> /// Queries the GDS for any servers matching the criteria. /// </summary> /// <param name="startingRecordId">The id of the first record to return.</param> /// <param name="maxRecordsToReturn">The max records to return.</param> /// <param name="applicationName">The filter applied to the application name.</param> /// <param name="applicationUri">The filter applied to the application uri.</param> /// <param name="productUri">The filter applied to the product uri.</param> /// <param name="serverCapabilities">The filter applied to the server capabilities.</param> /// <returns>A enumarator used to access the results.</returns> public IList <ServerOnNetwork> QueryServers( uint startingRecordId, uint maxRecordsToReturn, string applicationName, string applicationUri, string productUri, IList <string> serverCapabilities) { if (!IsConnected) { Connect(); } var outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.Gds.MethodIds.Directory_QueryServers, m_session.NamespaceUris), startingRecordId, maxRecordsToReturn, applicationName, applicationUri, productUri, serverCapabilities); ServerOnNetwork[] servers = null; if (outputArguments.Count > 1) { servers = (ServerOnNetwork[])ExtensionObject.ToArray(outputArguments[1] as ExtensionObject[], typeof(ServerOnNetwork)); } return(servers); }
/// <summary> /// Searches the server for servers. /// </summary> private void Search() { Session session = ServerCTRL.Session; if (session == null) { return; } NodeId elementId = null; ReferenceDescription reference = SystemElementBTN.SelectedReference; if (reference != null && !reference.NodeId.IsAbsolute) { elementId = (NodeId)reference.NodeId; } ushort namespaceIndex = (ushort)session.NamespaceUris.GetIndex(Namespaces.OpcUaGds); IList <object> outputArguments = session.Call( new NodeId(GdsId_Directory, namespaceIndex), new NodeId(GdsId_RootDirectoryEntryType_QueryServers, namespaceIndex), elementId, ProcessFilter(ApplicationNameCB, ApplicationNameTB), ProcessFilter(MachineNameCB, MachineNameTB), ProcessFilter(ApplicationUriCB, ApplicationUriTB), ProcessFilter(ProductUriCB, ProductUriTB)); if (outputArguments != null && outputArguments.Count == 1) { ExtensionObject[] extensions = outputArguments[0] as ExtensionObject[]; ApplicationDescription[] descriptions = (ApplicationDescription[])ExtensionObject.ToArray(extensions, typeof(ApplicationDescription)); UpdateResults(descriptions); } }
internal static async Task <Tuple <Argument[], Argument[]> > GetMethodArgumentsFromNodeId(this UaSession session, NodeId nodeId) { var inputArguments = new Argument[0]; var outputArguments = new Argument[0]; var translateRequest = new TranslateBrowsePathsToNodeIdsRequest { BrowsePaths = { new BrowsePath { StartingNode = nodeId, RelativePath = new RelativePath(ReferenceTypeIds.HasProperty, "InputArguments") }, new BrowsePath{ StartingNode = nodeId, RelativePath = new RelativePath(ReferenceTypeIds.HasProperty, "OutputArguments") } } }; var translateResponse = await session.TranslateBrowsePathsToNodeIdsAsync(translateRequest); if (StatusCode.IsGood(translateResponse.Results[0].StatusCode) && translateResponse.Results[0].Targets.Count > 0) { var argNodeId = ExpandedNodeId.ToNodeId(translateResponse.Results[0].Targets[0].TargetId, session.NamespaceUris); var readRequest = new ReadRequest { NodesToRead = { new ReadValueId { NodeId = argNodeId, AttributeId = Attributes.Value } } }; var readResponse = await session.ReadAsync(readRequest); if (StatusCode.IsGood(readResponse.Results[0].StatusCode)) { var value = readResponse.Results[0].GetValue <ExtensionObject[]>(null); if (value != null) { inputArguments = (Argument[])ExtensionObject.ToArray(value, typeof(Argument)); } } } if (StatusCode.IsGood(translateResponse.Results[1].StatusCode) && translateResponse.Results[1].Targets.Count > 0) { var argNodeId = ExpandedNodeId.ToNodeId(translateResponse.Results[1].Targets[0].TargetId, session.NamespaceUris); var readRequest = new ReadRequest { NodesToRead = { new ReadValueId { NodeId = argNodeId, AttributeId = Attributes.Value } } }; var readResponse = await session.ReadAsync(readRequest); if (StatusCode.IsGood(readResponse.Results[0].StatusCode)) { var value = readResponse.Results[0].GetValue <ExtensionObject[]>(null); if (value != null) { outputArguments = (Argument[])ExtensionObject.ToArray(value, typeof(Argument)); } } } return(Tuple.Create(inputArguments, outputArguments)); }
internal ServerOnNetwork[] QueryServers( ref DateTime lastResetTime, ref uint startingRecordId, uint maxRecordsToReturn, string applicationName, string applicationUri, string productUri, IList <string> serverCapabilities) { if (!IsConnected) { Connect(null); } var outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.Gds.MethodIds.Directory_QueryServers, m_session.NamespaceUris), startingRecordId, maxRecordsToReturn, applicationName, applicationUri, productUri, serverCapabilities); ServerOnNetwork[] servers = null; if (outputArguments.Count > 0) { if (lastResetTime != DateTime.MinValue && lastResetTime < (DateTime)outputArguments[0]) { throw new InvalidOperationException("Enumeration cannot continue because the Server has reset its index."); } lastResetTime = (DateTime)outputArguments[0]; } if (outputArguments.Count > 1) { servers = (ServerOnNetwork[])ExtensionObject.ToArray(outputArguments[1] as ExtensionObject[], typeof(ServerOnNetwork)); } if (servers != null && servers.Length > 0) { startingRecordId = servers[servers.Length - 1].RecordId + 1; } return(servers); }
/// <summary> /// Queries the GDS for any servers matching the criteria. /// </summary> /// <param name="startingRecordId">The id of the first record to return.</param> /// <param name="maxRecordsToReturn">The max records to return.</param> /// <param name="applicationName">The filter applied to the application name.</param> /// <param name="applicationUri">The filter applied to the application uri.</param> /// <param name="applicationType">The filter applied to the application uri.</param> /// <param name="productUri">The filter applied to the product uri.</param> /// <param name="serverCapabilities">The filter applied to the server capabilities.</param> /// <param name="lastCounterResetTime">The time when the counter was last changed.</param> /// <param name="nextRecordId">The id of the next record.</param> /// <returns>A enumerator used to access the results.</returns> public IList <ApplicationDescription> QueryApplications( uint startingRecordId, uint maxRecordsToReturn, string applicationName, string applicationUri, uint applicationType, string productUri, IList <string> serverCapabilities, out DateTime lastCounterResetTime, out uint nextRecordId) { lastCounterResetTime = DateTime.MinValue; nextRecordId = 0; if (!IsConnected) { Connect(); } var outputArguments = Session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory, Session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.Gds.MethodIds.Directory_QueryApplications, Session.NamespaceUris), startingRecordId, maxRecordsToReturn, applicationName, applicationUri, applicationType, productUri, serverCapabilities); ApplicationDescription[] applications = null; if (outputArguments.Count >= 3) { lastCounterResetTime = (DateTime)outputArguments[0]; nextRecordId = (uint)outputArguments[1]; applications = (ApplicationDescription[])ExtensionObject.ToArray(outputArguments[2] as ExtensionObject[], typeof(ApplicationDescription)); } return(applications); }
/// <summary> /// Finds the applications with the specified application uri. /// </summary> /// <param name="applicationUri">The application URI.</param> /// <returns>The matching application.</returns> public ApplicationRecordDataType[] FindApplication(string applicationUri) { if (!IsConnected) { Connect(); } var outputArguments = Session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory, Session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.Gds.MethodIds.Directory_FindApplications, Session.NamespaceUris), applicationUri); ApplicationRecordDataType[] applications = null; if (outputArguments.Count > 0) { applications = (ApplicationRecordDataType[])ExtensionObject.ToArray(outputArguments[0] as ExtensionObject[], typeof(ApplicationRecordDataType)); } return(applications); }
/// <summary> /// Reads the arguments for the method. /// </summary> private void ReadArguments(NodeId nodeId) { m_inputArguments = null; m_outputArguments = null; // build list of references to browse. BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.NodeClassMask = (uint)NodeClass.Variable; nodeToBrowse.ResultMask = (uint)BrowseResultMask.BrowseName; nodesToBrowse.Add(nodeToBrowse); // find properties. ReferenceDescriptionCollection references = ClientUtils.Browse(m_session, null, nodesToBrowse, false); // build list of properties to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; references != null && ii < references.Count; ii++) { ReferenceDescription reference = references[ii]; // ignore out of server references. if (reference.NodeId.IsAbsolute) { continue; } // ignore other properties. if (reference.BrowseName != Opc.Ua.BrowseNames.InputArguments && reference.BrowseName != Opc.Ua.BrowseNames.OutputArguments) { continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = (NodeId)reference.NodeId; nodeToRead.AttributeId = Attributes.Value; nodeToRead.Handle = reference; nodesToRead.Add(nodeToRead); } // method has no arguments. if (nodesToRead.Count == 0) { return; } // read the arguments. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // save the results. for (int ii = 0; ii < results.Count; ii++) { ReferenceDescription reference = (ReferenceDescription)nodesToRead[ii].Handle; if (StatusCode.IsGood(results[ii].StatusCode)) { if (reference.BrowseName == Opc.Ua.BrowseNames.InputArguments) { m_inputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument)); } if (reference.BrowseName == Opc.Ua.BrowseNames.OutputArguments) { m_outputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument)); } } } // set default values for input arguments. if (m_inputArguments != null) { foreach (Argument argument in m_inputArguments) { argument.Value = TypeInfo.GetDefaultValue(argument.DataType, argument.ValueRank, m_session.TypeTree); } } }
/// <summary> /// Collects the child methods of a Node. /// </summary> private bool CollectMethods(Node node, bool testErrors, List <TestMethod> methods) { if (node == null || node.NodeClass != NodeClass.Method) { return(true); } MethodNode method = node as MethodNode; IList <INode> parents = Session.NodeCache.Find( node.NodeId, ReferenceTypeIds.HasComponent, true, true); for (int ii = 0; ii < parents.Count; ii++) { ObjectNode parent = parents[ii] as ObjectNode; if (parent != null && method != null) { if (!testErrors && parent.BrowseName.Name != "MethodTest") { continue; } bool found = false; for (int jj = 0; jj < methods.Count; jj++) { if (Object.ReferenceEquals(method, methods[jj].Method)) { found = true; break; } } if (found) { continue; } TestMethod test = new TestMethod(); test.Parent = parent; test.Method = method; test.InputArguments = new Argument[0]; test.OutputArguments = new Argument[0]; test.Inputs = new List <object>(); methods.Add(test); if (methods.Count % 25 == 0) { Log("Found for {0} Methods to Call", methods.Count); } IList <INode> properties = Session.NodeCache.Find( method.NodeId, ReferenceTypeIds.HasProperty, false, true); for (int jj = 0; jj < properties.Count; jj++) { VariableNode property = properties[jj] as VariableNode; if (property != null) { if (property.BrowseName == BrowseNames.InputArguments) { if (property.Value.Value == null) { DataValue value = Session.ReadValue(property.NodeId); property.Value = value.WrappedValue; } test.InputArguments = (Argument[])ExtensionObject.ToArray(property.Value.Value as Array, typeof(Argument)); if (test.InputArguments == null) { Log( "Could not read input arguments for method '{0}'. NodeId = {1}, Method = {2}", test.Parent, test.Parent.NodeId, test.Method); return(false); } continue; } if (property.BrowseName == BrowseNames.OutputArguments) { if (property.Value.Value == null) { DataValue value = Session.ReadValue(property.NodeId); property.Value = value.WrappedValue; } test.OutputArguments = (Argument[])ExtensionObject.ToArray(property.Value.Value as Array, typeof(Argument)); if (test.OutputArguments == null) { Log( "Could not read output arguments for method '{0}'. NodeId = {1}, Method = {2}", test.Parent, test.Parent.NodeId, test.Method); return(false); } continue; } } } } } return(true); }
/// <summary> /// Updates the list of references. /// </summary> private void UpdateArguments(Session session, NodeId nodeId) { ArgumentsLV.Items.Clear(); // need to fetch the node ids for the argument properties. BrowsePathCollection browsePaths = new BrowsePathCollection(); foreach (string browseName in new string[] { BrowseNames.InputArguments, BrowseNames.OutputArguments }) { BrowsePath browsePath = new BrowsePath(); browsePath.StartingNode = nodeId; browsePath.Handle = browseName; RelativePathElement element = new RelativePathElement(); element.ReferenceTypeId = ReferenceTypeIds.HasProperty; element.IsInverse = false; element.IncludeSubtypes = true; element.TargetName = browseName; browsePath.RelativePath.Elements.Add(element); browsePaths.Add(browsePath); } // translate property names. BrowsePathResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.TranslateBrowsePathsToNodeIds( null, browsePaths, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, browsePaths); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths); // create a list of values to read. ReadValueIdCollection valuesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < results.Count; ii++) { if (StatusCode.IsBad(results[ii].StatusCode) || results[ii].Targets.Count <= 0) { continue; } ReadValueId valueToRead = new ReadValueId(); valueToRead.NodeId = (NodeId)results[ii].Targets[0].TargetId; valueToRead.AttributeId = Attributes.Value; valueToRead.Handle = browsePaths[ii].Handle; valuesToRead.Add(valueToRead); } // read the values. if (valuesToRead.Count > 0) { DataValueCollection values = null; session.Read( null, 0, TimestampsToReturn.Neither, valuesToRead, out values, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead); // update the list control. for (int ii = 0; ii < values.Count; ii++) { // all structures are wrapped in extension objects. ExtensionObject[] extensions = values[ii].GetValue <ExtensionObject[]>(null); if (extensions != null) { // convert to an argument structure. Argument[] arguments = (Argument[])ExtensionObject.ToArray(extensions, typeof(Argument)); UpdateList(session, arguments, (string)valuesToRead[ii].Handle); } } } // auto size the columns. for (int ii = 0; ii < ArgumentsLV.Columns.Count; ii++) { ArgumentsLV.Columns[ii].Width = -2; } }
public virtual NodeState BindNodeStates(IDictionary <NodeId, IList <IReference> > externalReferences, NodeState nodeState, ref NodeStateCollection nodeStateCollectionToBind) { switch (nodeState.NodeClass) { case NodeClass.Object: if (!(nodeState is BaseObjectState baseObjectState)) { return(nodeState); } _previousBaseNode = baseObjectState; //Bind previous method now since it will be cleared if (_previousMethod != null) { int index = nodeStateCollectionToBind.FindIndex(x => x.NodeId == _previousMethod.NodeId); if (index == -1) { nodeStateCollectionToBind.Add(_previousMethod); } else { nodeStateCollectionToBind[index] = _previousMethod; } } // ensure the process object can be found via the server object. if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out IList <IReference> references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, _previousBaseNode.NodeId)); _previousMethod = null; break; case NodeClass.DataType: if (!(nodeState is DataTypeState dataTypeState)) { return(nodeState); } BindNodeStateActions(dataTypeState); _previousDataType = dataTypeState; int index2 = nodeStateCollectionToBind.FindIndex(x => x.NodeId == _previousDataType.NodeId); if (index2 == -1) { nodeStateCollectionToBind.Add(_previousDataType); } else { nodeStateCollectionToBind[index2] = _previousDataType; } break; case NodeClass.Method: if (!(nodeState is MethodState methodState)) { return(nodeState); } BindNodeStateActions(methodState); _previousBaseNode?.AddChild(methodState); if (_previousMethod != null) { int index = nodeStateCollectionToBind.FindIndex(x => x.NodeId == _previousMethod.NodeId); if (index == -1) { nodeStateCollectionToBind.Add(_previousMethod); } else { nodeStateCollectionToBind[index] = _previousMethod; } } _previousMethod = methodState; return(methodState); case NodeClass.Variable: if (_previousMethod != null) { if (!(nodeState is PropertyState propertyState)) { return(nodeState); } BindNodeStateActions(propertyState); if (propertyState.DisplayName == BrowseNames.InputArguments) { _previousMethod.InputArguments = new PropertyState <Argument[]>(_previousMethod) { NodeId = propertyState.NodeId, BrowseName = propertyState.BrowseName, DisplayName = propertyState.DisplayName, TypeDefinitionId = propertyState.TypeDefinitionId, ReferenceTypeId = propertyState.ReferenceTypeId, DataType = propertyState.DataType, ValueRank = propertyState.ValueRank, Value = ExtensionObject.ToArray(propertyState.Value, typeof(Argument)) as Argument[], OnReadUserAccessLevel = OnReadUserAccessLevel, OnSimpleWriteValue = OnWriteValue }; } else if (propertyState.DisplayName == BrowseNames.OutputArguments) { _previousMethod.OutputArguments = new PropertyState <Argument[]>(_previousMethod) { NodeId = propertyState.NodeId, BrowseName = propertyState.BrowseName, DisplayName = propertyState.DisplayName, TypeDefinitionId = propertyState.TypeDefinitionId, ReferenceTypeId = propertyState.ReferenceTypeId, DataType = propertyState.DataType, ValueRank = propertyState.ValueRank, Value = ExtensionObject.ToArray(propertyState.Value, typeof(Argument)) as Argument[], OnReadUserAccessLevel = OnReadUserAccessLevel, OnSimpleWriteValue = OnWriteValue }; } } break; default: if (_previousBaseNode != null) { int index = nodeStateCollectionToBind.FindIndex(x => x.NodeId == _previousBaseNode.NodeId); if (index == -1) { nodeStateCollectionToBind.Add(_previousBaseNode); } else { nodeStateCollectionToBind[index] = _previousBaseNode; } } if (_previousMethod != null) { int index = nodeStateCollectionToBind.FindIndex(x => x.NodeId == _previousMethod.NodeId); if (index == -1) { nodeStateCollectionToBind.Add(_previousMethod); } else { nodeStateCollectionToBind[index] = _previousMethod; } } _previousBaseNode = null; _previousMethod = null; break; } return(nodeState); }