Example #1
0
        public static LogEntry For(CreateMonitoredItemsRequest request)
        {
            LogEntry entry = new LogEntry("CreateMonitoredItemsRequest");

            entry.Add("RequestHeader", For(request.RequestHeader));
            entry.Add("SubscriptionID", For(request.SubscriptionId));
            entry.Add("TimestampsToReturn", For(request.TimestampsToReturn));
            entry.Add("ItemsToCreate", For(request.ItemsToCreate));
            return(entry);
        }
Example #2
0
        /// <summary>
        /// Receive StateChanged message.
        /// </summary>
        /// <param name="state">The service's CommunicationState.</param>
        public void OnStateChanged(CommunicationState state)
        {
            if (state == CommunicationState.Opened)
            {
                Task.Run(async() =>
                {
                    try
                    {
                        // create the subscription.
                        var subscriptionRequest = new CreateSubscriptionRequest
                        {
                            RequestedPublishingInterval = this.PublishingInterval,
                            RequestedMaxKeepAliveCount  = this.KeepAliveCount,
                            RequestedLifetimeCount      = Math.Max(this.LifetimeCount, 3 * this.KeepAliveCount),
                            PublishingEnabled           = true,
                            Priority = this.Priority
                        };
                        var subscriptionResponse = await this.Session.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);
                        var id = this.Id = subscriptionResponse.SubscriptionId;

                        // add the items.
                        if (this.MonitoredItems.Count > 0)
                        {
                            var items    = this.MonitoredItems.ToList();
                            var requests = items.Select(m => new MonitoredItemCreateRequest {
                                ItemToMonitor = new ReadValueId {
                                    NodeId = m.NodeId, AttributeId = m.AttributeId, IndexRange = m.IndexRange
                                }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters {
                                    ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter
                                }
                            }).ToArray();
                            var itemsRequest = new CreateMonitoredItemsRequest
                            {
                                SubscriptionId = id,
                                ItemsToCreate  = requests,
                            };
                            var itemsResponse = await this.Session.CreateMonitoredItemsAsync(itemsRequest).ConfigureAwait(false);
                            for (int i = 0; i < itemsResponse.Results.Length; i++)
                            {
                                var item   = items[i];
                                var result = itemsResponse.Results[i];
                                item.OnCreateResult(result);
                            }
                        }
                    }
                    catch (ServiceResultException ex)
                    {
                        Trace.TraceError($"Subscription error creating subscription '{this.GetType().Name}'. {ex.Message}");
                    }
                });
            }
        }
Example #3
0
        public async Task CreateMonitoredItemsAsync()
        {
            var response = new CreateMonitoredItemsResponse();
            var request  = new CreateMonitoredItemsRequest();
            var channel  = new TestRequestChannel(response);

            var ret = await channel.CreateMonitoredItemsAsync(request);

            ret
            .Should().BeSameAs(response);

            channel.Request
            .Should().BeSameAs(request);
        }
Example #4
0
        public async Task AddMonitoredItem()
        {
            var createItemsRequest = new CreateMonitoredItemsRequest
            {
                SubscriptionId     = subscriptions[0],                //  Subscription to add to.  May need to choose the subscription to add to if multiple subs per client
                TimestampsToReturn = TimestampsToReturn.Both,
                ItemsToCreate      = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest
                    {
                        ItemToMonitor = new ReadValueId {
                            AttributeId = AttributeIds.Value, NodeId = NodeId.Parse(_clientOptions.Tag)
                        },
                        MonitoringMode      = MonitoringMode.Reporting,
                        RequestedParameters = new MonitoringParameters {
                            ClientHandle = 42, QueueSize = 2, DiscardOldest = true, SamplingInterval = 1000
                        },
                    },
                },
            };
            var createItemResponse = await channel.CreateMonitoredItemsAsync(createItemsRequest);

            monitoredItems.Add(createItemResponse.Results[0].MonitoredItemId);
            _logger.LogInformation($"Monitored Item added: {monitoredItems[0]}");
            tokens.Add(channel
                       .Where(pr => pr.SubscriptionId == subscriptions[0])  //  Subscription to add to.  May need to choose the subscription to add to if multiple subs per client
                       .Subscribe(
                           pr =>
            {
                var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                foreach (var dcn in dcns)
                {
                    foreach (var min in dcn.MonitoredItems)
                    {
                        _logger.LogInformation($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                    }
                }
            },
                           ex => _logger.LogError($"Exception in publish response handler: {ex.GetBaseException().Message}")
                           ));
        }
Example #5
0
        /// <summary>
        /// The state machine manages the state of the subscription.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task StateMachineAsync(CancellationToken token = default)
        {
            while (!token.IsCancellationRequested)
            {
                await this.whenSubscribed.Task;

                this.progress.Report(CommunicationState.Opening);

                try
                {
                    if (this.endpointUrl is null)
                    {
                        throw new InvalidOperationException("The endpointUrl field must not be null. Please, use the Subscription attribute properly.");
                    }

                    // get a channel.
                    this.innerChannel = await this.application.GetChannelAsync(this.endpointUrl, token);

                    try
                    {
                        // create the subscription.
                        var subscriptionRequest = new CreateSubscriptionRequest
                        {
                            RequestedPublishingInterval = this.publishingInterval,
                            RequestedMaxKeepAliveCount  = this.keepAliveCount,
                            RequestedLifetimeCount      = Math.Max(this.lifetimeCount, 3 * this.keepAliveCount),
                            PublishingEnabled           = true
                        };
                        var subscriptionResponse = await this.innerChannel.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                        // link up the dataflow blocks
                        var id        = this.subscriptionId = subscriptionResponse.SubscriptionId;
                        var linkToken = this.innerChannel.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id);

                        try
                        {
                            // create the monitored items.
                            var items = this.monitoredItems.ToList();
                            if (items.Count > 0)
                            {
                                var requests = items.Select(m => new MonitoredItemCreateRequest {
                                    ItemToMonitor = new ReadValueId {
                                        NodeId = ExpandedNodeId.ToNodeId(m.NodeId, this.InnerChannel.NamespaceUris), AttributeId = m.AttributeId, IndexRange = m.IndexRange
                                    }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters {
                                        ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter
                                    }
                                }).ToArray();

                                //split requests array to MaxMonitoredItemsPerCall chunks
                                int maxmonitoreditemspercall = 100;
                                MonitoredItemCreateRequest[] requests_chunk;
                                int chunk_size;
                                for (int i_chunk = 0; i_chunk < requests.Length; i_chunk += maxmonitoreditemspercall)
                                {
                                    chunk_size     = Math.Min(maxmonitoreditemspercall, requests.Length - i_chunk);
                                    requests_chunk = new MonitoredItemCreateRequest[chunk_size];
                                    Array.Copy(requests, i_chunk, requests_chunk, 0, chunk_size);

                                    var itemsRequest = new CreateMonitoredItemsRequest
                                    {
                                        SubscriptionId = id,
                                        ItemsToCreate  = requests_chunk,
                                    };
                                    var itemsResponse = await this.innerChannel.CreateMonitoredItemsAsync(itemsRequest);

                                    if (itemsResponse.Results is { } results)
                                    {
                                        for (int i = 0; i < results.Length; i++)
                                        {
                                            var item   = items[i];
                                            var result = results[i];

                                            if (result is null)
                                            {
                                                this.logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. The result is null.");
                                                continue;
                                            }

                                            item.OnCreateResult(result);
                                            if (StatusCode.IsBad(result.StatusCode))
                                            {
                                                this.logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. {StatusCodes.GetDefaultMessage(result.StatusCode)}");
                                            }
                                        }
                                    }
                                }
                            }

                            this.progress.Report(CommunicationState.Opened);

                            // wait here until channel is closing, unsubscribed or token cancelled.
                            try
                            {
                                await Task.WhenAny(
                                    this.WhenChannelClosingAsync(this.innerChannel, token),
                                    this.whenUnsubscribed.Task);
                            }
                            catch
                            {
                            }
                            finally
                            {
                                this.progress.Report(CommunicationState.Closing);
                            }
                        }
                        catch (Exception ex)
                        {
                            this.logger?.LogError($"Error creating MonitoredItems. {ex.Message}");
                            this.progress.Report(CommunicationState.Faulted);
                        }
                        finally
                        {
                            linkToken.Dispose();
                        }

                        if (this.innerChannel.State == CommunicationState.Opened)
                        {
                            try
                            {
                                // delete the subscription.
                                var deleteRequest = new DeleteSubscriptionsRequest
                                {
                                    SubscriptionIds = new uint[] { id }
                                };
                                await this.innerChannel.DeleteSubscriptionsAsync(deleteRequest);
                            }
                            catch (Exception ex)
                            {
                                this.logger?.LogError($"Error deleting subscription. {ex.Message}");
                                await Task.Delay(2000);
                            }
                        }

                        this.progress.Report(CommunicationState.Closed);
                    }
                    catch (Exception ex)
                    {
                        this.logger?.LogError($"Error creating subscription. {ex.Message}");
                        this.progress.Report(CommunicationState.Faulted);
                        await Task.Delay(2000);
                    }
                }
                catch (Exception ex)
                {
                    this.logger?.LogTrace($"Error getting channel. {ex.Message}");
                    this.progress.Report(CommunicationState.Faulted);
                    await Task.Delay(2000);
                }
            }
        }
Example #6
0
 /// <summary>
 /// Initializes the message with the body.
 /// </summary>
 public CreateMonitoredItemsMessage(CreateMonitoredItemsRequest CreateMonitoredItemsRequest)
 {
     this.CreateMonitoredItemsRequest = CreateMonitoredItemsRequest;
 }
Example #7
0
        /// <summary>
        /// The state machine manages the state of the subscription.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task StateMachineAsync(CancellationToken token = default(CancellationToken))
        {
            while (!token.IsCancellationRequested)
            {
                await this.whenSubscribed.Task;

                this.progress.Report(CommunicationState.Opening);

                try
                {
                    // get a channel.
                    this.innerChannel = await this.application.GetChannelAsync(this.endpointUrl, token);

                    try
                    {
                        // create the subscription.
                        var subscriptionRequest = new CreateSubscriptionRequest
                        {
                            RequestedPublishingInterval = this.publishingInterval,
                            RequestedMaxKeepAliveCount  = this.keepAliveCount,
                            RequestedLifetimeCount      = Math.Max(this.lifetimeCount, 3 * this.keepAliveCount),
                            PublishingEnabled           = true
                        };
                        var subscriptionResponse = await this.innerChannel.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(true);

                        // link up the dataflow blocks
                        var id        = this.subscriptionId = subscriptionResponse.SubscriptionId;
                        var linkToken = this.innerChannel.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id);

                        try
                        {
                            // create the monitored items.
                            var items = this.monitoredItems.ToList();
                            if (items.Count > 0)
                            {
                                var requests = items.Select(m => new MonitoredItemCreateRequest {
                                    ItemToMonitor = new ReadValueId {
                                        NodeId = m.NodeId, AttributeId = m.AttributeId, IndexRange = m.IndexRange
                                    }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters {
                                        ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter
                                    }
                                }).ToArray();
                                var itemsRequest = new CreateMonitoredItemsRequest
                                {
                                    SubscriptionId = id,
                                    ItemsToCreate  = requests,
                                };
                                var itemsResponse = await this.innerChannel.CreateMonitoredItemsAsync(itemsRequest);

                                for (int i = 0; i < itemsResponse.Results.Length; i++)
                                {
                                    var item   = items[i];
                                    var result = itemsResponse.Results[i];
                                    item.OnCreateResult(result);
                                    if (StatusCode.IsBad(result.StatusCode))
                                    {
                                        this.logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. {StatusCodes.GetDefaultMessage(result.StatusCode)}");
                                    }
                                }
                            }

                            this.progress.Report(CommunicationState.Opened);

                            // wait here until channel is closing, unsubscribed or token cancelled.
                            try
                            {
                                await Task.WhenAny(
                                    this.WhenChannelClosingAsync(this.innerChannel, token),
                                    this.whenUnsubscribed.Task);
                            }
                            catch
                            {
                            }
                            finally
                            {
                                this.progress.Report(CommunicationState.Closing);
                            }
                        }
                        catch (Exception ex)
                        {
                            this.logger?.LogError($"Error creating MonitoredItems. {ex.Message}");
                            this.progress.Report(CommunicationState.Faulted);
                        }
                        finally
                        {
                            linkToken.Dispose();
                        }

                        if (this.innerChannel.State == CommunicationState.Opened)
                        {
                            try
                            {
                                // delete the subscription.
                                var deleteRequest = new DeleteSubscriptionsRequest
                                {
                                    SubscriptionIds = new uint[] { id }
                                };
                                await this.innerChannel.DeleteSubscriptionsAsync(deleteRequest);
                            }
                            catch (Exception ex)
                            {
                                this.logger?.LogError($"Error deleting subscription. {ex.Message}");
                                await Task.Delay(2000);
                            }
                        }

                        this.progress.Report(CommunicationState.Closed);
                    }
                    catch (Exception ex)
                    {
                        this.logger?.LogError($"Error creating subscription. {ex.Message}");
                        this.progress.Report(CommunicationState.Faulted);
                        await Task.Delay(2000);
                    }
                }
                catch (Exception ex)
                {
                    this.logger?.LogTrace($"Error getting channel. {ex.Message}");
                    this.progress.Report(CommunicationState.Faulted);
                    await Task.Delay(2000);
                }
            }
        }
Example #8
0
        public async Task TransferSubscription()
        {
            var channel1 = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new UserNameIdentity("root", "secret"),
                EndpointUrl,
                loggerFactory: loggerFactory);

            await channel1.OpenAsync();

            logger.LogInformation($"Opened session with endpoint '{channel1.RemoteEndpoint.EndpointUrl}'.");
            logger.LogInformation($"SecurityPolicy: '{channel1.RemoteEndpoint.SecurityPolicyUri}'.");
            logger.LogInformation($"SecurityMode: '{channel1.RemoteEndpoint.SecurityMode}'.");
            logger.LogInformation($"Activated session '{channel1.SessionId}'.");

            // create the keep alive subscription.
            var subscriptionRequest = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = 1000f,
                RequestedMaxKeepAliveCount  = 30,
                RequestedLifetimeCount      = 30 * 3,
                PublishingEnabled           = true,
            };
            var subscriptionResponse = await channel1.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

            var id = subscriptionResponse.SubscriptionId;

            void onPublish(PublishResponse pr)
            {
                // loop thru all the data change notifications and log them.
                var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();

                foreach (var dcn in dcns)
                {
                    foreach (var min in dcn.MonitoredItems)
                    {
                        logger.LogInformation($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                    }
                }
            }

            void onPublishError(Exception ex)
            {
                logger.LogInformation("Exception in publish response handler: {0}", ex.GetBaseException().Message);
            }

            var token = channel1
                        .Where(pr => pr.SubscriptionId == id)
                        .Subscribe(onPublish, onPublishError);

            var itemsRequest = new CreateMonitoredItemsRequest
            {
                SubscriptionId = id,
                ItemsToCreate  = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest {
                        ItemToMonitor = new ReadValueId {
                            NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                        }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                            ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                        }
                    }
                },
            };
            var itemsResponse = await channel1.CreateMonitoredItemsAsync(itemsRequest);

            await Task.Delay(3000);

            var channel2 = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new UserNameIdentity("root", "secret"),
                EndpointUrl);

            await channel2.OpenAsync();

            var token2 = channel2
                         .Where(pr => pr.SubscriptionId == id)
                         .Subscribe(onPublish, onPublishError);

            var transferRequest = new TransferSubscriptionsRequest
            {
                SubscriptionIds   = new[] { id },
                SendInitialValues = true
            };
            var transferResult = await channel2.TransferSubscriptionsAsync(transferRequest);

            StatusCode.IsGood(transferResult.Results[0].StatusCode)
            .Should().BeTrue();
            logger.LogInformation($"Transfered subscriptions to new client.");

            await Task.Delay(3000);

            logger.LogInformation($"Closing session '{channel1.SessionId}'.");
            await channel1.CloseAsync();

            logger.LogInformation($"Closing session '{channel2.SessionId}'.");
            await channel2.CloseAsync();
        }
Example #9
0
        /// <summary>
        /// Begins an asynchronous invocation of the CreateMonitoredItems service.
        /// </summary>
        public IAsyncResult BeginCreateMonitoredItems(
            RequestHeader                        requestHeader,
            uint                                 subscriptionId,
            TimestampsToReturn                   timestampsToReturn,
            MonitoredItemCreateRequestCollection itemsToCreate,
            AsyncCallback                        callback,
            object                               asyncState)
        {
            CreateMonitoredItemsRequest request = new CreateMonitoredItemsRequest();

            request.RequestHeader      = requestHeader;
            request.SubscriptionId     = subscriptionId;
            request.TimestampsToReturn = timestampsToReturn;
            request.ItemsToCreate      = itemsToCreate;

            UpdateRequestHeader(request, requestHeader == null, "CreateMonitoredItems");

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginCreateMonitoredItems(new CreateMonitoredItemsMessage(request), callback, asyncState);
        }
Example #10
0
        /// <summary>
        /// Invokes the CreateMonitoredItems service.
        /// </summary>
        public virtual ResponseHeader CreateMonitoredItems(
            RequestHeader                           requestHeader,
            uint                                    subscriptionId,
            TimestampsToReturn                      timestampsToReturn,
            MonitoredItemCreateRequestCollection    itemsToCreate,
            out MonitoredItemCreateResultCollection results,
            out DiagnosticInfoCollection            diagnosticInfos)
        {
            CreateMonitoredItemsRequest request = new CreateMonitoredItemsRequest();
            CreateMonitoredItemsResponse response = null;

            request.RequestHeader      = requestHeader;
            request.SubscriptionId     = subscriptionId;
            request.TimestampsToReturn = timestampsToReturn;
            request.ItemsToCreate      = itemsToCreate;

            UpdateRequestHeader(request, requestHeader == null, "CreateMonitoredItems");

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.SendRequest(request);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (CreateMonitoredItemsResponse)genericResponse;
                }
                else
                {
                    CreateMonitoredItemsResponseMessage responseMessage = InnerChannel.CreateMonitoredItems(new CreateMonitoredItemsMessage(request));

                    if (responseMessage == null || responseMessage.CreateMonitoredItemsResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.CreateMonitoredItemsResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                results         = response.Results;
                diagnosticInfos = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(request, response, "CreateMonitoredItems");
            }

            return response.ResponseHeader;
        }
Example #11
0
        private static async Task ConnectAndPublish(CancellationToken token = default)
        {
            var discoveryUrl = "opc.tcp://localhost:48010"; // UaCppServer - see  http://www.unified-automation.com/

            var appDescription = new ApplicationDescription()
            {
                ApplicationName = "MyHomework",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:MyHomework",
                ApplicationType = ApplicationType.Client,
            };

            var certificateStore = new DirectoryStore(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Workstation.ConsoleApp", "pki"));

            while (!token.IsCancellationRequested)
            {
                var channel = new UaTcpSessionChannel(
                    appDescription,
                    certificateStore,
                    new AnonymousIdentity(),
                    discoveryUrl);
                try
                {
                    await channel.OpenAsync();

                    var subscriptionRequest = new CreateSubscriptionRequest
                    {
                        RequestedPublishingInterval = 1000,
                        RequestedMaxKeepAliveCount  = 10,
                        RequestedLifetimeCount      = 30,
                        PublishingEnabled           = true
                    };
                    var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                    var id = subscriptionResponse.SubscriptionId;

                    var itemsToCreate = new MonitoredItemCreateRequest[]
                    {
                        new MonitoredItemCreateRequest {
                            ItemToMonitor = new ReadValueId {
                                NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                            }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                                ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                            }
                        }
                    };
                    var itemsRequest = new CreateMonitoredItemsRequest
                    {
                        SubscriptionId = id,
                        ItemsToCreate  = itemsToCreate,
                    };
                    var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                    var subtoken = channel.Where(pr => pr.SubscriptionId == id).Subscribe(
                        pr =>
                    {
                        var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                        foreach (var dcn in dcns)
                        {
                            foreach (var min in dcn.MonitoredItems)
                            {
                                Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                            }
                        }
                    },
                        // need to handle error when server closes
                        ex => { });

                    try
                    {
                        Task.WaitAny(new Task[] { channel.Completion }, token);
                    }
                    catch (OperationCanceledException) { }

                    var request = new DeleteSubscriptionsRequest
                    {
                        SubscriptionIds = new uint[] { id }
                    };
                    await channel.DeleteSubscriptionsAsync(request);

                    subtoken.Dispose();

                    await channel.CloseAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error connecting and publishing. {ex.Message}");
                    await channel.AbortAsync();

                    try
                    {
                        await Task.Delay(5000, token);
                    }
                    catch (TaskCanceledException) { }
                }
            }
        }
Example #12
0
        public async Task CreateDataSubscription()
        {
            // describe this client application.
            var clientDescription = new ApplicationDescription
            {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };

            // place to store certificates
            var certificateStore = new DirectoryStore("./pki");

            // create a 'UaTcpSessionChannel', a client-side channel that opens a 'session' with the server.
            var channel = new UaTcpSessionChannel(
                clientDescription,
                certificateStore,
                new AnonymousIdentity(),      // the anonymous identity
                "opc.tcp://localhost:48010"); // the endpoint of Unified Automation's UaCPPServer.

            try
            {
                // try opening a session and reading a few nodes.
                await channel.OpenAsync();

                Console.WriteLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'.");

                // build a CreateSubscriptionRequest. See 'OPC UA Spec Part 4' paragraph 5.13.2
                var req = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 1000.0, // intervals are in milliseconds
                    RequestedMaxKeepAliveCount  = 30,
                    RequestedLifetimeCount      = 30 * 3,
                    PublishingEnabled           = true,
                };
                var res = await channel.CreateSubscriptionAsync(req);

                // the result will return the server's subscription id. You will needs this to
                // add monitored items.
                var id = res.SubscriptionId;
                Console.WriteLine($"Created subscription '{id}'.");

                // build a CreateMonitoredItemsRequest. See 'OPC UA Spec Part 4' paragraph 5.12.2
                var req2 = new CreateMonitoredItemsRequest
                {
                    SubscriptionId     = id,
                    TimestampsToReturn = TimestampsToReturn.Both,
                    ItemsToCreate      = new MonitoredItemCreateRequest[]
                    {
                        new MonitoredItemCreateRequest
                        {
                            ItemToMonitor = new ReadValueId {
                                AttributeId = AttributeIds.Value, NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime)
                            },
                            MonitoringMode = MonitoringMode.Reporting,
                            // specify a unique ClientHandle. The ClientHandle is returned in the PublishResponse
                            RequestedParameters = new MonitoringParameters {
                                ClientHandle = 42, QueueSize = 2, DiscardOldest = true, SamplingInterval = 1000.0
                            },
                        },
                    },
                };
                var res2 = await channel.CreateMonitoredItemsAsync(req2);

                Console.WriteLine("\nSubscribe to PublishResponse stream.");

                // when the session is open, the client sends a stream of PublishRequests to the server.
                // You can subscribe to all the PublishResponses -or- subscribe to the responses from
                // a single subscription.
                var token = channel
                            // receive just the subscription we just created
                            .Where(pr => pr.SubscriptionId == id)
                            // subscribe with an 'OnNext' function, and an 'OnError' function
                            .Subscribe(
                    pr =>
                {
                    // loop thru all the data change notifications and write them out.
                    var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var dcn in dcns)
                    {
                        foreach (var min in dcn.MonitoredItems)
                        {
                            Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                        }
                    }
                },
                    ex => Console.WriteLine("Exception in publish response handler: {0}", ex.GetBaseException().Message)
                    );

                // publish for 5 seconds and then close.
                await Task.Delay(5000);

                Console.WriteLine($"\nClosing session '{channel.SessionId}'.");
                await channel.CloseAsync();
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();

                Console.WriteLine(ex.Message);
            }
        }
Example #13
0
        public async Task CreateEventSubscription()
        {
            // describe this client application.
            var clientDescription = new ApplicationDescription
            {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };

            // place to store certificates
            var certificateStore = new DirectoryStore("./pki");

            // create a 'UaTcpSessionChannel', a client-side channel that opens a 'session' with the server.
            var channel = new UaTcpSessionChannel(
                clientDescription,
                certificateStore,
                new AnonymousIdentity(),      // the anonymous identity
                "opc.tcp://localhost:48010"); // the endpoint of Unified Automation's UaCPPServer.

            try
            {
                // try opening a session and reading a few nodes.
                await channel.OpenAsync();

                Console.WriteLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'.");

                // build a CreateSubscriptionRequest. See 'OPC UA Spec Part 4' paragraph 5.13.2
                var req = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 500.0, // intervals are in milliseconds
                    RequestedMaxKeepAliveCount  = 30,
                    RequestedLifetimeCount      = 30 * 3,
                    PublishingEnabled           = true,
                };
                var res = await channel.CreateSubscriptionAsync(req);

                // the result will return the server's subscription id. You will needs this to
                // add monitored items.
                var id = res.SubscriptionId;
                Console.WriteLine($"Created subscription '{id}'.");

                // build a CreateMonitoredItemsRequest. See 'OPC UA Spec Part 4' paragraph 5.12.2
                var req2 = new CreateMonitoredItemsRequest
                {
                    SubscriptionId     = id,
                    TimestampsToReturn = TimestampsToReturn.Both,
                    ItemsToCreate      = new MonitoredItemCreateRequest[]
                    {
                        new MonitoredItemCreateRequest
                        {
                            ItemToMonitor = new ReadValueId {
                                AttributeId = AttributeIds.EventNotifier, NodeId = NodeId.Parse(ObjectIds.Server)
                            },
                            MonitoringMode = MonitoringMode.Reporting,
                            // specify a unique ClientHandle. The ClientHandle is returned in the PublishResponse
                            RequestedParameters = new MonitoringParameters {
                                ClientHandle = 42, SamplingInterval = -1.0, QueueSize = 1000, DiscardOldest = true,
                                // events require an EventFilter with a SelectClause (a list of fields to receive)
                                Filter = new EventFilter {
                                    SelectClauses = EventHelper.GetSelectClauses <BaseEvent>()
                                }
                            },
                        },
                    },
                };
                var res2 = await channel.CreateMonitoredItemsAsync(req2);

                Console.WriteLine("\nSubscribe to PublishResponse stream.");

                // when the session is open, the client sends a stream of PublishRequests to the server.
                // You can subscribe to all the PublishResponses -or- subscribe to the responses from
                // a single subscription.
                var token = channel
                            // receive responses for the subscription we just created
                            .Where(pr => pr.SubscriptionId == id)
                            // subscribe with an 'OnNext' function, and an 'OnError' function
                            .Subscribe(
                    pr =>
                {
                    // loop thru all the event notifications and write them out.
                    var enls = pr.NotificationMessage.NotificationData.OfType <EventNotificationList>();
                    foreach (var enl in enls)
                    {
                        foreach (var efl in enl.Events)
                        {
                            var ev = EventHelper.Deserialize <BaseEvent>(efl.EventFields);
                            Console.WriteLine($"time: {ev.Time}, src: {ev.SourceName}, msg: {ev.Message}, sev: {ev.Severity}");
                        }
                    }
                },
                    ex => Console.WriteLine("Exception in publish response handler: {0}", ex.GetBaseException().Message)
                    );

                // publish for 5 seconds and then close.
                for (int i = 0; i < 10; i++)
                {
                    // trigger an event on the Unified Automation server.
                    var writeResult = await channel.WriteAsync(
                        new WriteRequest
                    {
                        // Write true, false, true, false, ...
                        NodesToWrite = new[] {
                            new WriteValue {
                                NodeId      = NodeId.Parse("ns=2;s=Demo.Events.Trigger_BaseEvent"),
                                AttributeId = AttributeIds.Value,
                                Value       = new DataValue(i % 2 == 0)
                            }
                        }
                    }
                        );

                    await Task.Delay(500);
                }

                Console.WriteLine($"\nClosing session '{channel.SessionId}'.");
                await channel.CloseAsync();
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();

                Console.WriteLine(ex.Message);
            }
        }
Example #14
0
        private static async Task TestAsync()
        {
            var discoveryUrl = "opc.tcp://*****:*****@"%LOCALAPPDATA%\Workstation.ConsoleApp\pki")),
                       userIdentity,
                       remoteEndpoint))
            {
                try
                {
                    await session.OpenAsync();
                }
                catch (ServiceResultException ex)
                {
                    if ((uint)ex.HResult == StatusCodes.BadSecurityChecksFailed)
                    {
                        Console.WriteLine("Error connecting to endpoint. Did the server reject our certificate?");
                    }

                    throw ex;
                }

                Console.WriteLine("Step 5 - Browse the server namespace.");
                Console.WriteLine("+ Root");
                BrowseRequest browseRequest = new BrowseRequest
                {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = NodeId.Parse(ObjectIds.RootFolder), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                              } },
                };
                BrowseResponse browseResponse = await session.BrowseAsync(browseRequest);

                foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                {
                    Console.WriteLine("  + {0}: {1}, {2}", rd1.DisplayName, rd1.BrowseName, rd1.NodeClass);
                    browseRequest = new BrowseRequest
                    {
                        NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                      NodeId = ExpandedNodeId.ToNodeId(rd1.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                  } },
                    };
                    browseResponse = await session.BrowseAsync(browseRequest);

                    foreach (var rd2 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                    {
                        Console.WriteLine("    + {0}: {1}, {2}", rd2.DisplayName, rd2.BrowseName, rd2.NodeClass);
                        browseRequest = new BrowseRequest
                        {
                            NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                          NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                      } },
                        };
                        browseResponse = await session.BrowseAsync(browseRequest);

                        foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                        {
                            Console.WriteLine("      + {0}: {1}, {2}", rd3.DisplayName, rd3.BrowseName, rd3.NodeClass);
                        }
                    }
                }

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 6 - Create a subscription.");
                var subscriptionRequest = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 1000,
                    RequestedMaxKeepAliveCount  = 10,
                    RequestedLifetimeCount      = 30,
                    PublishingEnabled           = true
                };
                var subscriptionResponse = await session.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                var id = subscriptionResponse.SubscriptionId;

                Console.WriteLine("Step 7 - Add items to the subscription.");
                var itemsToCreate = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest {
                        ItemToMonitor = new ReadValueId {
                            NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                        }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                            ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                        }
                    }
                };
                var itemsRequest = new CreateMonitoredItemsRequest
                {
                    SubscriptionId = id,
                    ItemsToCreate  = itemsToCreate,
                };
                var itemsResponse = await session.CreateMonitoredItemsAsync(itemsRequest).ConfigureAwait(false);

                Console.WriteLine("Step 8 - Publish the subscription.");
                var publishRequest = new PublishRequest
                {
                    SubscriptionAcknowledgements = new SubscriptionAcknowledgement[0]
                };
                Console.WriteLine("Press any key to delete the subscription...");
                while (!Console.KeyAvailable)
                {
                    var publishResponse = await session.PublishAsync(publishRequest).ConfigureAwait(false);

                    // loop thru all the data change notifications
                    var dcns = publishResponse.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var dcn in dcns)
                    {
                        foreach (var min in dcn.MonitoredItems)
                        {
                            Console.WriteLine($"clientHandle: {min.ClientHandle}; value: {min.Value}");
                        }
                    }

                    publishRequest = new PublishRequest
                    {
                        SubscriptionAcknowledgements = new[] { new SubscriptionAcknowledgement {
                                                                   SequenceNumber = publishResponse.NotificationMessage.SequenceNumber, SubscriptionId = publishResponse.SubscriptionId
                                                               } }
                    };
                }

                Console.ReadKey(true);

                Console.WriteLine("Step 9 - Delete the subscription.");
                var request = new DeleteSubscriptionsRequest
                {
                    SubscriptionIds = new uint[] { id }
                };
                await session.DeleteSubscriptionsAsync(request).ConfigureAwait(false);

                Console.WriteLine("Press any key to close the session...");
                Console.ReadKey(true);
                Console.WriteLine("Step 10 - Close the session.");
                await session.CloseAsync();
            }
        }
        /// <summary>
        /// Creates the subscriptions on the server.
        /// </summary>
        /// <param name="token">A cancellation token. </param>
        /// <returns>A task.</returns>
        private async Task AutoCreateSubscriptionsAsync(CancellationToken token = default(CancellationToken))
        {
            var tcs = new TaskCompletionSource <bool>();
            NotifyCollectionChangedEventHandler handler = async(o, e) =>
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (var subscription in e.NewItems.OfType <Subscription>())
                    {
                        var target = subscription.Target;
                        if (target == null)
                        {
                            continue;
                        }

                        try
                        {
                            // create the subscription.
                            var subscriptionRequest = new CreateSubscriptionRequest
                            {
                                RequestedPublishingInterval = subscription.PublishingInterval,
                                RequestedMaxKeepAliveCount  = subscription.KeepAliveCount,
                                RequestedLifetimeCount      = Math.Max(subscription.LifetimeCount, 3 * subscription.KeepAliveCount),
                                PublishingEnabled           = subscription.PublishingEnabled
                            };
                            var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                            var id = subscription.SubscriptionId = subscriptionResponse.SubscriptionId;

                            // add the items.
                            if (subscription.MonitoredItems.Count > 0)
                            {
                                var items    = subscription.MonitoredItems.ToList();
                                var requests = items.Select(m => new MonitoredItemCreateRequest {
                                    ItemToMonitor = new ReadValueId {
                                        NodeId = m.NodeId, AttributeId = m.AttributeId, IndexRange = m.IndexRange
                                    }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters {
                                        ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter
                                    }
                                }).ToArray();
                                var itemsRequest = new CreateMonitoredItemsRequest
                                {
                                    SubscriptionId = id,
                                    ItemsToCreate  = requests,
                                };
                                var itemsResponse = await this.CreateMonitoredItemsAsync(itemsRequest).ConfigureAwait(false);

                                for (int i = 0; i < itemsResponse.Results.Length; i++)
                                {
                                    var item   = items[i];
                                    var result = itemsResponse.Results[i];
                                    item.OnCreateResult(target, result);
                                    if (StatusCode.IsBad(result.StatusCode))
                                    {
                                        this.Logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. {StatusCodes.GetDefaultMessage(result.StatusCode)}");
                                    }
                                }
                            }
                        }
                        catch (ServiceResultException ex)
                        {
                            this.Logger?.LogError($"Error creating subscription. {ex.Message}");
                            this.innerChannel.Fault(ex);
                        }
                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    try
                    {
                        // delete the subscriptions.
                        var request = new DeleteSubscriptionsRequest
                        {
                            SubscriptionIds = e.OldItems.OfType <Subscription>().Select(s => s.SubscriptionId).ToArray()
                        };
                        await this.DeleteSubscriptionsAsync(request).ConfigureAwait(false);
                    }
                    catch (ServiceResultException ex)
                    {
                        this.Logger?.LogError($"Error deleting subscriptions. {ex.Message}");
                    }
                }
            };

            using (token.Register(state => ((TaskCompletionSource <bool>)state).TrySetResult(true), tcs, false))
            {
                try
                {
                    handler.Invoke(this.subscriptions, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this.subscriptions.ToList()));
                    this.subscriptions.CollectionChanged += handler;
                    await tcs.Task;
                }
                finally
                {
                    this.subscriptions.CollectionChanged -= handler;
                    foreach (var subscription in this.subscriptions)
                    {
                        subscription.SubscriptionId = 0;
                    }
                }
            }
        }
Example #16
0
        public async Task TestSubscription()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                loggerFactory: loggerFactory);

            await channel.OpenAsync();

            logger.LogInformation($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
            logger.LogInformation($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
            logger.LogInformation($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
            logger.LogInformation($"Activated session '{channel.SessionId}'.");

            var req = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = 1000.0,
                RequestedMaxKeepAliveCount  = 30,
                RequestedLifetimeCount      = 30 * 3,
                PublishingEnabled           = true,
            };
            var res = await channel.CreateSubscriptionAsync(req);

            var id = res.SubscriptionId;

            logger.LogInformation($"Created subscription '{id}'.");

            var req2 = new CreateMonitoredItemsRequest
            {
                SubscriptionId     = id,
                TimestampsToReturn = TimestampsToReturn.Both,
                ItemsToCreate      = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest
                    {
                        ItemToMonitor = new ReadValueId {
                            AttributeId = AttributeIds.Value, NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime)
                        },
                        MonitoringMode      = MonitoringMode.Reporting,
                        RequestedParameters = new MonitoringParameters {
                            ClientHandle = 42, QueueSize = 2, DiscardOldest = true, SamplingInterval = 500.0
                        },
                    },
                },
            };
            var res2 = await channel.CreateMonitoredItemsAsync(req2);

            logger.LogInformation("Subscribe to PublishResponse stream.");
            var numOfResponses = 0;

            void onPublish(PublishResponse pr)
            {
                numOfResponses++;

                // loop thru all the data change notifications and log them.
                var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();

                foreach (var dcn in dcns)
                {
                    foreach (var min in dcn.MonitoredItems)
                    {
                        logger.LogInformation($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                    }
                }
            }

            void onPublishError(Exception ex)
            {
                logger.LogInformation("Exception in publish response handler: {0}", ex.GetBaseException().Message);
            }

            var token = channel
                        .Where(pr => pr.SubscriptionId == id)
                        .Subscribe(onPublish, onPublishError);

            await Task.Delay(5000);

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();

            numOfResponses
            .Should().BeGreaterThan(0);
        }
Example #17
0
        public static async Task ReadSubscribed(CancellationToken token = default(CancellationToken))
        {
            {
                // setup logger
                var loggerFactory = new LoggerFactory();
                loggerFactory.AddConsole(LogLevel.Information);
                //var logger = loggerFactory?.CreateLogger<Program>();

                // Describe this app.
                var appDescription = new ApplicationDescription()
                {
                    ApplicationName = "DataLoggingConsole",
                    ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:DataLoggingConsole",
                    ApplicationType = ApplicationType.Client,
                };

                // Create a certificate store on disk.

                // Create array of NodeIds to log.
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        // Discover endpoints.
                        var getEndpointsRequest = new GetEndpointsRequest
                        {
                            EndpointUrl = discoveryUrl,
                            ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                        };
                        var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest)
                                                   .ConfigureAwait(false);

                        if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0)
                        {
                            throw new InvalidOperationException($"'{discoveryUrl}' returned no endpoints.");
                        }

                        // Choose the endpoint with highest security level.
                        var remoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

                        // Create a session with the server.
                        var channel = new UaTcpSessionChannel(appDescription, certificateStore,
                                                              async e => GetIUserIdentity(remoteEndpoint).GetAwaiter().GetResult(),
                                                              remoteEndpoint, loggerFactory);
                        try
                        {
                            await channel.OpenAsync();

                            var subscriptionRequest = new CreateSubscriptionRequest
                            {
                                RequestedPublishingInterval = 1000,
                                RequestedMaxKeepAliveCount  = 10,
                                RequestedLifetimeCount      = 30,
                                PublishingEnabled           = true
                            };
                            var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                            var id = subscriptionResponse.SubscriptionId;

                            var itemsToCreate = new MonitoredItemCreateRequest[]
                            {
                                #region MonitoredItems

                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Admin.ProdProcessedCount"), AttributeId = AttributeIds.Value
                                    },                                                                                                               //ProdProcessedCount
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 1, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },


                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[0].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Next batch ID
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 2, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },

                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[1].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Next product ID
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 3, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[2].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Amount of product in next batch
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 4, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[2].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Humidity
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 5, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[3].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Temperature
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 6, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[4].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Vibration
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 7, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.MachSpeed"), AttributeId = AttributeIds.Value
                                    },                                                                                                       //MachineSpeed
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 8, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value
                                    },                                                                                                          //state
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 9, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value
                                    },                                                                                                          //cmdCtrln
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 10, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                }

                                #endregion
                            };


                            var itemsRequest = new CreateMonitoredItemsRequest
                            {
                                SubscriptionId = id,
                                ItemsToCreate  = itemsToCreate,
                            };
                            var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                            var subToken = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
                            {
                                // loop through all the data change notifications
                                var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                                foreach (var dcn in dcns)
                                {
                                    foreach (var min in dcn.MonitoredItems)
                                    {
                                        switch (min.ClientHandle)
                                        {
                                        case 1:
                                            prodProc = (int)min.Value.Value;
                                            time     = (DateTime)min.Value.ServerTimestamp;
                                            break;

                                        case 2:
                                            time        = (DateTime)min.Value.ServerTimestamp;
                                            nextBatchID = (float)min.Value.Value;
                                            break;

                                        case 3:
                                            time          = (DateTime)min.Value.ServerTimestamp;
                                            nextProductID = (float)min.Value.Value;
                                            break;

                                        case 4:
                                            time = (DateTime)min.Value.ServerTimestamp;
                                            nextProductAmount = (float)min.Value.Value;
                                            break;

                                        case 5:
                                            time     = (DateTime)min.Value.ServerTimestamp;
                                            humidity = (float)min.Value.Value;
                                            break;

                                        case 6:
                                            time        = (DateTime)min.Value.ServerTimestamp;
                                            temperature = (float)min.Value.Value;
                                            break;

                                        case 7:
                                            time      = (DateTime)min.Value.ServerTimestamp;
                                            vibration = (float)min.Value.Value;
                                            break;

                                        case 8:
                                            time         = (DateTime)min.Value.ServerTimestamp;
                                            machinespeed = (float)min.Value.Value;
                                            break;

                                        case 9:
                                            time  = (DateTime)min.Value.ServerTimestamp;
                                            State = (int)min.Value.Value;
                                            break;

                                        case 10:
                                            cmdctrl = (int)min.Value.Value;
                                            time    = (DateTime)min.Value.ServerTimestamp;
                                            break;
                                        }
                                    }
                                }
                            });

                            while (!token.IsCancellationRequested)
                            {
                                await Task.Delay(500);
                            }
                        }
                        catch
                        {
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    //try
                    //{
                    //    await Task.Delay(cycleTime, token);
                    //}
                    //catch
                    //{
                    //}
                }
            }
        }
Example #18
0
        /// <summary>
        /// Creates and adds one or more MonitoredItems to a Subscription.
        /// </summary>
        /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param>
        /// <param name="request">A <see cref="CreateMonitoredItemsRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="CreateMonitoredItemsResponse"/>.</returns>
        public static async Task <CreateMonitoredItemsResponse> CreateMonitoredItemsAsync(this IRequestChannel channel, CreateMonitoredItemsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            return((CreateMonitoredItemsResponse)await channel.RequestAsync(request).ConfigureAwait(false));
        }
        /// <summary>
        /// Creates and adds one or more MonitoredItems to a Subscription.
        /// </summary>
        /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param>
        /// <param name="request">A <see cref="CreateMonitoredItemsRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="CreateMonitoredItemsResponse"/>.</returns>
        public static async Task <CreateMonitoredItemsResponse> CreateMonitoredItemsAsync(this IRequestChannel channel, CreateMonitoredItemsRequest request, CancellationToken token = default)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return((CreateMonitoredItemsResponse)await channel.RequestAsync(request, token).ConfigureAwait(false));
        }
Example #20
0
        public static async Task Run(CancellationToken cancelToken, Action onValueChanged)
        {
            var clientDescription = new ApplicationDescription {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };
            var channel = new UaTcpSessionChannel(
                clientDescription,
                null,
                new AnonymousIdentity(),
                "opc.tcp://localhost:4840",
                SecurityPolicyUris.None
                );

            try {
                await channel.OpenAsync();

                // --------------------------------
                var res = await channel.CreateSubscriptionAsync(
                    new CreateSubscriptionRequest {
                    RequestedPublishingInterval = 1000.0,     // ms
                    RequestedMaxKeepAliveCount  = 30,
                    RequestedLifetimeCount      = 30 * 3,
                    PublishingEnabled           = true,
                },
                    cancelToken
                    );

                var id = res.SubscriptionId;
                var btnBrowseHandle = (uint)42;
                var rq = new CreateMonitoredItemsRequest {
                    SubscriptionId     = id,
                    TimestampsToReturn = TimestampsToReturn.Both,
                    ItemsToCreate      = new MonitoredItemCreateRequest[] {
                        new MonitoredItemCreateRequest {
                            ItemToMonitor = new ReadValueId {
                                NodeId      = NodeId.Parse("ns=6;s=::AsGlobalPV:dbgBtnBrowsePrograms"),
                                AttributeId = AttributeIds.Value
                            },
                            MonitoringMode = MonitoringMode.Reporting,
                            // Specify a unique ClientHandle,
                            // which will be returned in the PublishResponse.
                            RequestedParameters = new MonitoringParameters {
                                ClientHandle = btnBrowseHandle, QueueSize = 2, DiscardOldest = true, SamplingInterval = 1000.0
                            },
                        },
                    },
                };
                var res2 = await channel.CreateMonitoredItemsAsync(rq);

                var isInError = false;
                var token     = channel
                                // While session is open, the client sends a stream of PublishRequests to the server.
                                // You can subscribe to all the PublishResponses.
                                .Where(response => response.SubscriptionId == id)
                                .Subscribe(
                    onNext: response => {
                    var notifications = response.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var notification in notifications)
                    {
                        foreach (var item in notification.MonitoredItems)
                        {
                            if (item.ClientHandle == btnBrowseHandle)
                            {
                                if ((bool)item.Value.Value)
                                {
                                    onValueChanged();
                                }
                            }
                        }
                    }
                },
                    onError: ex => {
                    isInError = true;
                }
                    );
                while (!cancelToken.IsCancellationRequested && !isInError)
                {
                    await Task.Delay(500);
                }
                await channel.CloseAsync();
            }
            catch (Exception ex) {
                await channel.AbortAsync();

                Console.WriteLine(ex.Message);
            }
        }
Example #21
0
        private static async Task TestAsync()
        {
            var loggerFactory = new LoggerFactory();

            loggerFactory.AddDebug(LogLevel.Trace);

            var discoveryUrl = "opc.tcp://localhost:26543"; // Workstation.NodeServer

            //var discoveryUrl = "opc.tcp://localhost:48010"; // UaCppServer - see  http://www.unified-automation.com/
            //var discoveryUrl = "opc.tcp://localhost:16664"; // open62541

            Console.WriteLine("Step 1 - Describe this app.");
            var appDescription = new ApplicationDescription()
            {
                ApplicationName = "MyHomework",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:MyHomework",
                ApplicationType = ApplicationType.Client,
            };

            Console.WriteLine("Step 2 - Create a certificate store.");
            var certificateStore = new DirectoryStore(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Workstation.ConsoleApp", "pki"));

            Console.WriteLine("Step 3 - Create a session with your server.");
            var channel = new UaTcpSessionChannel(
                appDescription,
                certificateStore,
                ShowSignInDialog,
                discoveryUrl,
                loggerFactory: loggerFactory);

            try
            {
                await channel.OpenAsync();

                Console.WriteLine($"  Opened channel with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                Console.WriteLine($"  SecurityPolicyUri: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                Console.WriteLine($"  SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                Console.WriteLine($"  UserIdentity: '{channel.UserIdentity}'.");

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 4 - Browse the server namespace.");
                Console.WriteLine("+ Root");
                BrowseRequest browseRequest = new BrowseRequest
                {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = NodeId.Parse(ObjectIds.RootFolder), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                              } },
                };
                BrowseResponse browseResponse = await channel.BrowseAsync(browseRequest);

                foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                {
                    Console.WriteLine("  + {0}: {1}, {2}", rd1.DisplayName, rd1.BrowseName, rd1.NodeClass);
                    browseRequest = new BrowseRequest
                    {
                        NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                      NodeId = ExpandedNodeId.ToNodeId(rd1.NodeId, channel.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                  } },
                    };
                    browseResponse = await channel.BrowseAsync(browseRequest);

                    foreach (var rd2 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                    {
                        Console.WriteLine("    + {0}: {1}, {2}", rd2.DisplayName, rd2.BrowseName, rd2.NodeClass);
                        browseRequest = new BrowseRequest
                        {
                            NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                          NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, channel.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                      } },
                        };
                        browseResponse = await channel.BrowseAsync(browseRequest);

                        foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                        {
                            Console.WriteLine("      + {0}: {1}, {2}", rd3.DisplayName, rd3.BrowseName, rd3.NodeClass);
                        }
                    }
                }

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 5 - Create a subscription.");
                var subscriptionRequest = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 1000,
                    RequestedMaxKeepAliveCount  = 10,
                    RequestedLifetimeCount      = 30,
                    PublishingEnabled           = true
                };
                var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                var id = subscriptionResponse.SubscriptionId;

                Console.WriteLine("Step 6 - Add items to the subscription.");
                var itemsToCreate = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest {
                        ItemToMonitor = new ReadValueId {
                            NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                        }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                            ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                        }
                    }
                };
                var itemsRequest = new CreateMonitoredItemsRequest
                {
                    SubscriptionId = id,
                    ItemsToCreate  = itemsToCreate,
                };
                var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                Console.WriteLine("Step 7 - Subscribe to PublishResponse stream.");
                var token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
                {
                    // loop thru all the data change notifications
                    var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var dcn in dcns)
                    {
                        foreach (var min in dcn.MonitoredItems)
                        {
                            Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                        }
                    }
                });

                Console.WriteLine("Press any key to delete the subscription...");
                while (!Console.KeyAvailable)
                {
                    await Task.Delay(500);
                }

                Console.ReadKey(true);

                Console.WriteLine("Step 8 - Delete the subscription.");
                var request = new DeleteSubscriptionsRequest
                {
                    SubscriptionIds = new uint[] { id }
                };
                await channel.DeleteSubscriptionsAsync(request);

                token.Dispose();

                Console.WriteLine("Press any key to close the session...");
                Console.ReadKey(true);

                Console.WriteLine("Step 9 - Close the session.");
                await channel.CloseAsync();
            }
            catch (ServiceResultException ex)
            {
                if ((uint)ex.HResult == StatusCodes.BadSecurityChecksFailed)
                {
                    Console.WriteLine("Error connecting to endpoint. Did the server reject our certificate?");
                }

                await channel.AbortAsync();

                throw;
            }
        }