/// <summary> /// Check whether valid node and return service result if not. /// </summary> /// <param name="endpoint"></param> /// <param name="request"></param> /// <returns></returns> private Task <ServiceResultModel> TestPublishNodeAsync(EndpointModel endpoint, PublishStartRequestModel request) { // Test whether value exists and fail if not return(_opc.ExecuteServiceAsync(endpoint, null, TimeSpan.FromSeconds(10), async session => { var readNode = request.Item.NodeId.ToNodeId(session.MessageContext); if (NodeId.IsNull(readNode)) { throw new ArgumentException(nameof(request.Item.NodeId)); } var diagnostics = new List <OperationResultModel>(); var response = await session.ReadAsync( (request.Header?.Diagnostics).ToStackModel(), 0, TimestampsToReturn.Both, new ReadValueIdCollection { new ReadValueId { NodeId = readNode, AttributeId = Attributes.Value } }); OperationResultEx.Validate("Publish_" + readNode, diagnostics, response.Results.Select(r => r.StatusCode), response.DiagnosticInfos, false); SessionClientEx.Validate(response.Results, response.DiagnosticInfos); if (response.Results == null || response.Results.Count == 0) { return diagnostics.ToServiceModel(request.Header?.Diagnostics, session.MessageContext); } return null; })); }
/// <summary> /// Load references /// </summary> /// <param name="nodeModel"></param> /// <param name="ct"></param> /// <returns></returns> public async Task FetchReferencesAsync(BaseNodeModel nodeModel, CancellationToken ct) { try { // Read node with value var response = await _client.ExecuteServiceAsync(_endpoint, _elevation, _priority, ct, session => { _encoder.Context.UpdateFromSession(session); return(session.BrowseAsync(_diagnostics.ToStackModel(), null, nodeModel.NodeId, 0u, Opc.Ua.BrowseDirection.Both, ReferenceTypeIds.References, true, 0u)); }); SessionClientEx.Validate(response.Results, response.DiagnosticInfos); OperationResultEx.Validate("Browse_" + nodeModel.NodeId, Diagnostics, response.Results.Select(r => r.StatusCode), null, false); while (true) { foreach (var reference in response.Results[0].References) { nodeModel.AddReference(reference.ReferenceTypeId, !reference.IsForward, reference.NodeId); _references++; } if (response.Results[0].ContinuationPoint == null) { break; } response = await _client.ExecuteServiceAsync(_endpoint, _elevation, _priority, ct, session => { _encoder.Context.UpdateFromSession(session); return(session.BrowseNextAsync(_diagnostics.ToStackModel(), false, new ByteStringCollection { response.Results[0].ContinuationPoint })); }); SessionClientEx.Validate(response.Results, response.DiagnosticInfos); OperationResultEx.Validate("BrowseNext_" + nodeModel.NodeId, Diagnostics, response.Results.Select(r => r.StatusCode), null, false); } } catch (Exception ex) { _logger.Error(ex, "Failed browsing node object for node {nodeId}.", nodeModel.NodeId); } }
/// <inheritdoc/> public async Task <(ServiceResultModel, string)> CallMethodAsync( string method, string request, DiagnosticsModel diagnostics) { if (string.IsNullOrEmpty(request)) { throw new ArgumentNullException(nameof(request)); } if (string.IsNullOrEmpty(method)) { throw new ArgumentNullException(nameof(method)); } return(await _client.ExecuteServiceAsync(_endpoint, null, async session => { var results = new List <OperationResultModel>(); var methodCalls = new CallMethodRequestCollection { new CallMethodRequest { ObjectId = new NodeId(kMethodCallObject, 2), MethodId = new NodeId(kMethodCallMethod, 2), InputArguments = new VariantCollection { new Variant(method), new Variant(request) } } }; var result = await session.CallAsync(diagnostics.ToStackModel(), methodCalls); OperationResultEx.Validate("CallMethod", results, result.Results.Select(r => r.StatusCode), result.DiagnosticInfos, methodCalls, false); var diagResult = results.ToServiceModel(diagnostics, session.MessageContext); if (!StatusCode.IsGood(result.Results[0].StatusCode)) { _logger.Error("Call returned with error {status}", result.Results[0].StatusCode); return (diagResult, null); } if (result.Results[0].OutputArguments?.Count == 1) { var response = result.Results[0].OutputArguments[0].ToString(); return (diagResult, response); } return (diagResult, null); })); }