Exemple #1
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);
            }
        }
Exemple #2
0
        public async Task TransferSubscriptions()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();

            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };

            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);

            var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

            IUserIdentity selectedUserIdentity = new UserNameIdentity("root", "secret");

            var channel = new UaTcpSessionChannel(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint);

            Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
            Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
            Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
            await channel.OpenAsync();

            Console.WriteLine($"Activated session '{channel.SessionId}'.");
            var req = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = 1000,
                RequestedMaxKeepAliveCount  = 20,
                PublishingEnabled           = true
            };
            var res = await channel.CreateSubscriptionAsync(req);

            Console.WriteLine($"Created subscription '{res.SubscriptionId}'.");

            Console.WriteLine($"Aborting session '{channel.SessionId}'.");
            await channel.AbortAsync();

            var channel2 = new UaTcpSessionChannel(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint);

            await channel2.OpenAsync();

            Console.WriteLine($"Activated session '{channel2.SessionId}'.");

            var req2 = new TransferSubscriptionsRequest
            {
                SubscriptionIds = new[] { res.SubscriptionId }
            };
            var res2 = await channel2.TransferSubscriptionsAsync(req2);

            Console.WriteLine($"Transferred subscription result '{res2.Results[0].StatusCode}'.");
            Console.WriteLine($"Closing session '{channel2.SessionId}'.");
            await channel2.CloseAsync();

            Assert.IsTrue(StatusCode.IsGood(res2.Results[0].StatusCode));
        }
Exemple #3
0
        public async Task ConnnectToAllEndpoints()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();

            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };

            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);

            // for each endpoint and user identity type, try creating a session and reading a few nodes.
            foreach (var selectedEndpoint in getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel))
            {
                foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens)
                {
                    IUserIdentity selectedUserIdentity;
                    switch (selectedTokenPolicy.TokenType)
                    {
                    case UserTokenType.UserName:
                        selectedUserIdentity = new UserNameIdentity("root", "secret");
                        break;

                    case UserTokenType.Certificate:
                        selectedUserIdentity = new X509Identity(localCertificate);
                        break;

                    default:
                        selectedUserIdentity = new AnonymousIdentity();
                        break;
                    }

                    var channel = new UaTcpSessionChannel(
                        this.localDescription,
                        localCertificate,
                        selectedUserIdentity,
                        selectedEndpoint);

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

                        Console.WriteLine($"Closing session '{channel.SessionId}'.");
                        await channel.CloseAsync();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error opening session '{channel.SessionId}'. {ex.Message}");
                    }
                }
            }
        }
Exemple #4
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();
        }
        public async Task WriteIndexRange()
        {
            // 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 WriteRequest. See 'OPC UA Spec Part 4' paragraph 5.10.4
                var writeRequest = new WriteRequest
                {
                    // set the NodesToWrite to an array of WriteValues.
                    NodesToWrite = new[] {
                        // construct a WriteValue from a NodeId, AttributeId and DataValue.
                        new WriteValue {
                            // use a saved NodeId or Parse the nodeId from a string.
                            // e.g. "ns=2;s=Demo.Static.Scalar.Double"
                            NodeId = NodeId.Parse("ns=2;s=Demo.CTT.AllProfiles.Arrays.Double"),
                            // variable class nodes have a Value attribute.
                            AttributeId = AttributeIds.Value,
                            // ask to write an slice of the underlying array
                            IndexRange = "1:2",
                            // the DataValue type has to match the underlying array type exactly.
                            Value = new DataValue(new double[] { 41.0, 42.0 }),
                        }
                    }
                };
                // send the WriteRequest to the server.
                var writeResult = await channel.WriteAsync(writeRequest);

                // 'Results' will be a array of status codes, one for every WriteValue.
                var result = writeResult.Results[0];

                Console.WriteLine($"Write result: {result}");

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

                Console.WriteLine(ex.Message);
            }
        }
Exemple #6
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) { }
                }
            }
        }
Exemple #7
0
        public async Task ReadHistorical()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                "opc.tcp://localhost:48010",
                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 historyReadRequest = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadRawModifiedDetails
                {
                    StartTime      = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime        = DateTime.UtcNow,
                    ReturnBounds   = true,
                    IsReadModified = false
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory")
                    }
                },
            };
            var historyReadResponse = await channel.HistoryReadAsync(historyReadRequest);

            var result = historyReadResponse.Results[0];

            StatusCode.IsGood(result.StatusCode)
            .Should().BeTrue();
            logger.LogInformation($"HistoryRead response status code: {result.StatusCode}, HistoryData count: {((HistoryData)result.HistoryData).DataValues.Length}.");

            if (false) // UaCPPserver does not appear to store event history.
            {
                var historyReadRequest2 = new HistoryReadRequest
                {
                    HistoryReadDetails = new ReadEventDetails
                    {
                        StartTime = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                        EndTime   = DateTime.UtcNow,
                        Filter    = new EventFilter // Use EventHelper to select all the fields of AlarmCondition.
                        {
                            SelectClauses = EventHelper.GetSelectClauses <AlarmCondition>()
                        }
                    },
                    NodesToRead = new[]
                    {
                        new HistoryReadValueId
                        {
                            NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory")
                        }
                    },
                };
                var historyReadResponse2 = await channel.HistoryReadAsync(historyReadRequest2);

                var result2 = historyReadResponse2.Results[0];
                StatusCode.IsGood(result2.StatusCode)
                .Should().BeTrue();
                logger.LogInformation($"HistoryRead response status code: {result2.StatusCode}, HistoryEvent count: {((HistoryEvent)result2.HistoryData).Events.Length}.");

                // Use EventHelper to create AlarmConditions from the HistoryEventFieldList
                var alarms = ((HistoryEvent)result2.HistoryData).Events.Select(e => EventHelper.Deserialize <AlarmCondition>(e.EventFields));
            }
            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
Exemple #8
0
        private static async Task TestAsync(CancellationToken token = default(CancellationToken))
        {
            var discoveryUrl = $"opc.tcp://localhost:26543";
            var cycleTime    = 5000;

            // 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.
            var certificateStore = new DirectoryStore(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DataLoggingConsole", "pki"));

            // Create array of NodeIds to log.
            var nodeIds = new[]
            {
                NodeId.Parse("i=2258")
            };

            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();

                    // Choose a User Identity.
                    IUserIdentity userIdentity = null;
                    if (remoteEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.Anonymous))
                    {
                        userIdentity = new AnonymousIdentity();
                    }
                    else if (remoteEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.UserName))
                    {
                        // If a username / password is requested, provide from .config file.
                        userIdentity = new UserNameIdentity("root", "secret");
                    }
                    else
                    {
                        throw new InvalidOperationException("Server must accept Anonymous or UserName identity.");
                    }

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

                        RegisterNodesResponse registerNodesResponse = null;

                        if (true) // True registers the nodeIds to improve performance of the server.
                        {
                            // Register array of nodes to read.
                            var registerNodesRequest = new RegisterNodesRequest
                            {
                                NodesToRegister = nodeIds
                            };
                            registerNodesResponse = await session.RegisterNodesAsync(registerNodesRequest);
                        }

                        // Prepare read request.
                        var readRequest = new ReadRequest
                        {
                            NodesToRead = (registerNodesResponse?.RegisteredNodeIds ?? nodeIds)
                                          .Select(n => new ReadValueId {
                                NodeId = n, AttributeId = AttributeIds.Value
                            })
                                          .ToArray()
                        };

                        while (!token.IsCancellationRequested)
                        {
                            // Read the nodes.
                            var readResponse = await session.ReadAsync(readRequest).ConfigureAwait(false);

                            // Write the results.
                            for (int i = 0; i < readRequest.NodesToRead.Length; i++)
                            {
                                logger?.LogInformation($"{nodeIds[i]}; value: {readResponse.Results[i]}");
                            }

                            try
                            {
                                await Task.Delay(cycleTime, token);
                            }
                            catch { }
                        }
                        await session.CloseAsync();
                    }
                    catch
                    {
                        await session.AbortAsync();

                        throw;
                    }
                }
                catch (Exception ex)
                {
                    logger?.LogError(ex.Message);
                }

                try
                {
                    await Task.Delay(cycleTime, token);
                }
                catch { }
            }
        }
Exemple #9
0
        private async Task <bool> TryConnect()
        {
            if (connection != null)
            {
                return(true);
            }

            if (string.IsNullOrEmpty(config.Address))
            {
                return(false);
            }

            try {
                var getEndpointsRequest = new GetEndpointsRequest {
                    EndpointUrl = config.Address,
                    ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                };

                GetEndpointsResponse endpoints = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest);

                EndpointDescription[] noSecurityEndpoints = endpoints.Endpoints.Where(e => e.SecurityPolicyUri == SecurityPolicyUris.None).ToArray();

                var(endpoint, userIdentity) = FirstEndpointWithLogin(noSecurityEndpoints);

                if (endpoint == null || userIdentity == null)
                {
                    throw new Exception("No matching endpoint");
                }

                var channel = new UaTcpSessionChannel(
                    this.appDescription,
                    null,
                    userIdentity,
                    endpoint,
                    loggerFactory);

                await channel.OpenAsync();

                this.connection = channel;

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

                ItemInfo[] nodesNeedingResolve = mapId2Info.Values.Where(n => n.Node == null).ToArray();
                if (nodesNeedingResolve.Length > 0)
                {
                    PrintLine($"Resolving node ids for {nodesNeedingResolve.Length} items...");

                    TranslateBrowsePathsToNodeIdsRequest req = new TranslateBrowsePathsToNodeIdsRequest()
                    {
                        BrowsePaths = nodesNeedingResolve.Select(n => new BrowsePath()
                        {
                            StartingNode = n.StartingNode,
                            RelativePath = n.RelativePath
                        }).ToArray()
                    };
                    TranslateBrowsePathsToNodeIdsResponse resp = await connection.TranslateBrowsePathsToNodeIdsAsync(req);

                    if (resp.Results.Length != nodesNeedingResolve.Length)
                    {
                        LogWarn("Mismatch", "TranslateBrowsePathsToNodeIds failed");
                    }
                    else
                    {
                        for (int i = 0; i < resp.Results.Length; ++i)
                        {
                            BrowsePathResult x = resp.Results[i];
                            if (StatusCode.IsGood(x.StatusCode) && x.Targets.Length > 0)
                            {
                                NodeId id = x.Targets[0].TargetId.NodeId;
                                nodesNeedingResolve[i].Node = id;
                                PrintLine($"Resolved item '{nodesNeedingResolve[i].Name}' => {id}");
                            }
                            else
                            {
                                PrintLine($"Could not resolve item '{nodesNeedingResolve[i].Name}'!");
                            }
                        }
                    }
                }
                return(true);
            }
            catch (Exception exp) {
                Exception baseExp = exp.GetBaseException() ?? exp;
                LogWarn("OpenChannel", "Open channel error: " + baseExp.Message, dataItem: null, details: baseExp.StackTrace);
                await CloseChannel();

                return(false);
            }
        }
Exemple #10
0
        public async Task SessionTimeoutCausesFault()
        {
            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = EndpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };

            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest);

            var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

            var           selectedTokenType = selectedEndpoint.UserIdentityTokens[0].TokenType;
            IUserIdentity selectedUserIdentity;

            switch (selectedTokenType)
            {
            case UserTokenType.UserName:
                selectedUserIdentity = new UserNameIdentity("root", "secret");
                break;

            //case UserTokenType.Certificate:
            //    selectedUserIdentity = new X509Identity(localCertificate);
            //    break;

            default:
                selectedUserIdentity = new AnonymousIdentity();
                break;
            }

            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                async e => selectedUserIdentity,
                selectedEndpoint,
                loggerFactory: this.loggerFactory,
                options: new UaTcpSessionChannelOptions {
                SessionTimeout = 10000
            });

            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($"Activated session '{channel.SessionId}'.");

            // server should close session due to inactivity
            await Task.Delay(20000);

            // should throw exception
            var readRequest = new ReadRequest {
                NodesToRead = new[] { new ReadValueId {
                                          NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value
                                      } }
            };
            await channel.ReadAsync(readRequest);

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
Exemple #11
0
        public async Task ReadHistorical()
        {
            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                null,
                EndpointUrl);

            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($"Activated session '{channel.SessionId}'.");

            var historyReadRequest = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadRawModifiedDetails
                {
                    StartTime      = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime        = DateTime.UtcNow,
                    ReturnBounds   = true,
                    IsReadModified = false
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=MyLevel")
                    }
                },
            };
            var historyReadResponse = await channel.HistoryReadAsync(historyReadRequest);

            var result = historyReadResponse.Results[0];

            Assert.IsTrue(StatusCode.IsGood(result.StatusCode));
            Console.WriteLine($"HistoryRead response status code: {result.StatusCode}, HistoryData count: {((HistoryData)result.HistoryData.Body).DataValues.Length}.");

            var historyReadRequest2 = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadEventDetails
                {
                    StartTime = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime   = DateTime.UtcNow,
                    Filter    = new EventFilter // Use EventHelper to select all the fields of AlarmCondition.
                    {
                        SelectClauses = EventHelper.GetSelectClauses <AlarmCondition>()
                    }
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=MyDevice")
                    }
                },
            };
            var historyReadResponse2 = await channel.HistoryReadAsync(historyReadRequest2);

            var result2 = historyReadResponse2.Results[0];

            Assert.IsTrue(StatusCode.IsGood(result2.StatusCode));
            Console.WriteLine($"HistoryRead response status code: {result2.StatusCode}, HistoryEvent count: {((HistoryEvent)result2.HistoryData.Body).Events.Length}.");

            // Use EventHelper to create AlarmConditions from the HistoryEventFieldList
            var alarms = ((HistoryEvent)result2.HistoryData.Body).Events.Select(e => EventHelper.Deserialize <AlarmCondition>(e.EventFields));

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
Exemple #12
0
        public async Task ConnnectToAllEndpoints()
        {
            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };

            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);

            // for each endpoint and user identity type, try creating a session and reading a few nodes.
            foreach (var selectedEndpoint in getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel))
            {
                foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens)
                {
                    IUserIdentity selectedUserIdentity;
                    switch (selectedTokenPolicy.TokenType)
                    {
                    case UserTokenType.UserName:
                        selectedUserIdentity = new UserNameIdentity("root", "secret");
                        break;

                    //case UserTokenType.Certificate:
                    //    selectedUserIdentity = new X509Identity(localCertificate);
                    //    break;

                    case UserTokenType.Anonymous:
                        selectedUserIdentity = new AnonymousIdentity();
                        break;

                    default:
                        continue;
                    }

                    var channel = new UaTcpSessionChannel(
                        this.localDescription,
                        this.certificateStore,
                        selectedUserIdentity,
                        selectedEndpoint,
                        loggerFactory: this.loggerFactory,
                        timeoutHint: 60000);

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

                    try
                    {
                        await channel.OpenAsync();

                        Console.WriteLine($"Closing session '{channel.SessionId}'.");
                        await channel.CloseAsync();
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            }
        }
Exemple #13
0
        private async Task <UaTcpSessionChannel> CreateChannelAsync(string endpointUrl, CancellationToken token = default(CancellationToken))
        {
            try
            {
                this.logger?.LogTrace($"Begin creating UaTcpSessionChannel for {endpointUrl}");
                await this.CheckSuspension(token).ConfigureAwait(false);

                EndpointDescription endpoint;
                var mappedEndpoint = this.MappedEndpoints?.LastOrDefault(m => m.RequestedUrl == endpointUrl);
                if (mappedEndpoint != null)
                {
                    endpoint = mappedEndpoint.Endpoint;
                }
                else
                {
                    endpoint = new EndpointDescription {
                        EndpointUrl = endpointUrl
                    };
                }

                var channel = new UaTcpSessionChannel(
                    this.LocalDescription,
                    this.CertificateStore,
                    this.UserIdentityProvider,
                    endpoint,
                    this.LoggerFactory,
                    this.Options,
                    this.AdditionalTypes);

                channel.Faulted += (s, e) =>
                {
                    this.logger?.LogTrace($"Error creating UaTcpSessionChannel for {endpointUrl}. OnFaulted");
                    var ch = (UaTcpSessionChannel)s;
                    try
                    {
                        ch.AbortAsync().Wait();
                    }
                    catch
                    {
                    }
                };

                channel.Closing += (s, e) =>
                {
                    this.logger?.LogTrace($"Removing UaTcpSessionChannel for {endpointUrl} from channelMap.");
                    Lazy <Task <UaTcpSessionChannel> > value;
                    this.channelMap.TryRemove(endpointUrl, out value);
                };

                await channel.OpenAsync(token).ConfigureAwait(false);

                this.logger?.LogTrace($"Success creating UaTcpSessionChannel for {endpointUrl}.");
                return(channel);
            }
            catch (Exception ex)
            {
                this.logger?.LogTrace($"Error creating UaTcpSessionChannel for {endpointUrl}. {ex.Message}");
                Lazy <Task <UaTcpSessionChannel> > value;
                this.channelMap.TryRemove(endpointUrl, out value);
                throw;
            }
        }
        public async Task BrowseObjectFolder()
        {
            // 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(),
                "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 BrowseRequest. See 'OPC UA Spec Part 4' section 5.8.2
                var browseRequest = new BrowseRequest
                {
                    NodesToBrowse = new[] {
                        new BrowseDescription {
                            // gather references of this nodeid.
                            NodeId = NodeId.Parse(ObjectIds.ObjectsFolder),
                            // include just 'Forward' references
                            BrowseDirection = BrowseDirection.Forward,
                            // include 'HierarchicalReferences'
                            ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences),
                            // include 'HierarchicalReferences' and all subtypes of 'HierarchicalReferences'
                            IncludeSubtypes = true,
                            // include all classes of node
                            NodeClassMask = (uint)NodeClass.Unspecified,
                            // return reference descriptions with all the fields filled out
                            ResultMask = (uint)BrowseResultMask.All,
                        }
                    },
                    RequestedMaxReferencesPerNode = 1000
                };

                // send the request to the server
                var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false);

                Console.WriteLine("\n+ Objects, 0:Objects, Object, i=85");

                Assert.IsNotNull(browseResponse.Results[0].References);
                foreach (var rd in browseResponse.Results[0].References)
                {
                    Console.WriteLine("   + {0}, {1}, {2}, {3}", rd.DisplayName, rd.BrowseName, rd.NodeClass, rd.NodeId);
                }

                // it is good practice to be prepared to receive a continuationPoint.
                // ContinuationPoints are returned when the server has more information
                // than can be delivered in current response.
                // To test this code, you can reduce the above RequestedMaxReferencesPerNode
                // to 1.
                var cp = browseResponse.Results[0].ContinuationPoint;
                while (cp != null)
                {
                    var browseNextRequest = new BrowseNextRequest {
                        ContinuationPoints = new[] { cp }, ReleaseContinuationPoints = false
                    };
                    var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest);

                    Assert.IsNotNull(browseNextResponse.Results[0].References);
                    foreach (var rd in browseNextResponse.Results[0].References)
                    {
                        Console.WriteLine("   + {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                    }
                    cp = browseNextResponse.Results[0].ContinuationPoint;
                }

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

                Console.WriteLine(ex.Message);
            }
        }
Exemple #15
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);
            }
        }
        /// <summary>
        /// Most important method - reading the tags.
        /// </summary>
        public async Task <List <Tag> > OPCReadAsync(string OPCAdress)
        {
            //Preparing data to connect to OPC server
            Tags = new List <Tag>();
            var loggerFactory = new LoggerFactory();

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

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

            var channel = new UaTcpSessionChannel(
                appDescription,
                certificateStore,
                new AnonymousIdentity(), //by now doesn't support signing in
                OPCAdress,
                loggerFactory: loggerFactory);

            try
            {
                Stopwatch stopwatch = new Stopwatch(); //measuring operations time
                stopwatch.Start();

                await channel.OpenAsync(); //opening channel

                OnNewEvent(new LogEventArgs("Connected to OPC Server"));

                //opening OPC tree branches to find actual tags - only proper for B&R X20 PLC
                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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[0].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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[1].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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[0].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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[0].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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[1].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);

                browseRequest = new BrowseRequest {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = ExpandedNodeId.ToNodeId(browseResponse.Results[0].References[10].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 browseResponse0 = await channel.BrowseAsync(browseRequest);

                int nestingLevel = 0;                                                       //nesting level counter
                Tag tag          = new Tag();                                               //initializing first tag
                int allTagsCount = browseResponse0.Results[0].References.Length - 1;        //for counting progress percentage

                for (int i = browseResponse0.Results[0].References.Length - 1; i >= 0; i--) //first level loop
                {
                    var rd = browseResponse0.Results[0].References[i];
                    if (Tags.Count > 0 && rd.DisplayName.ToString() == Tags[0].Name)
                    {
                        break;
                    }                                                                           //to avoid getting the same tags second time

                    nestingLevel = 0;
                    ReadValueId[] items = new ReadValueId[1];
                    items[0] = new ReadValueId {
                        NodeId = NodeId.Parse(rd.NodeId.ToString()), AttributeId = AttributeIds.DataType
                    };
                    ReadRequest readRequest = new ReadRequest {
                        NodesToRead = items
                    };
                    ReadResponse readResponse = await channel.ReadAsync(readRequest);


                    if (string.IsNullOrEmpty(tag.Name))
                    {
                        tag = new Tag(rd.DisplayName.ToString());
                    }


                    if (readResponse.Results[0].Value != null)
                    {
                        tag.ConversionFunction = Typ(readResponse.Results[0].Value.ToString());
                    }

                    browseRequest = new BrowseRequest {
                        NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                      NodeId = ExpandedNodeId.ToNodeId(rd.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 rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0]) //second level loop (nesting=1)
                    {
                        if (!rd1.NodeId.ToString().Contains("#"))
                        {
                            nestingLevel = 1;
                            tag          = await ReadTag(new ReferenceDescription[] { rd, rd1 }, channel, tag);

                            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]) //third level loop (nesting=2)
                            {
                                if (!rd2.NodeId.ToString().Contains("#"))
                                {
                                    nestingLevel = 2;
                                    tag          = await ReadTag(new ReferenceDescription[] { rd, rd1, rd2 }, channel, tag);

                                    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]) //fourth level loop (nesting=3)
                                    {
                                        if (!rd3.NodeId.ToString().Contains("#"))
                                        {
                                            nestingLevel = 3;
                                            tag          = await ReadTag(new ReferenceDescription[] { rd, rd1, rd2, rd3 }, channel, tag);
                                        }
                                        else if (rd3.NodeId.ToString().Contains("#EngineeringUnits"))
                                        {
                                            await ReadUnit(new ReferenceDescription[] { rd, rd1, rd2, rd3 }, channel, tag);
                                        }

                                        if (nestingLevel == 3 && !string.IsNullOrEmpty(tag.Name))
                                        {
                                            tag = SaveTag(tag);
                                        }
                                    }
                                }
                                else if (rd2.NodeId.ToString().Contains("#EngineeringUnits"))
                                {
                                    await ReadUnit(new ReferenceDescription[] { rd, rd1, rd2 }, channel, tag);
                                }


                                if (nestingLevel == 2 && !string.IsNullOrEmpty(tag.Name))
                                {
                                    tag = SaveTag(tag);
                                }
                            }
                        }

                        else if (rd1.NodeId.ToString().Contains("#EngineeringUnits"))
                        {
                            await ReadUnit(new ReferenceDescription[] { rd, rd1 }, channel, tag);
                        }


                        if (nestingLevel == 1 && !string.IsNullOrEmpty(tag.Name))
                        {
                            tag = SaveTag(tag);
                        }
                    }
                    if (nestingLevel == 0 && !string.IsNullOrEmpty(tag.Name))
                    {
                        tag = SaveTag(tag);
                    }

                    OnProgressChanged(new ProgressChangedArgs((allTagsCount - i) * 100 / allTagsCount)); //computing progress percentage
                }


                await channel.CloseAsync(); //closing the channel

                stopwatch.Stop();

                OnNewEvent(new LogEventArgs(Tags.Count + " tags read, time elapsed: " + stopwatch.Elapsed.TotalSeconds.ToString("F3") + " s"));
            }
            catch (Exception ex)
            {
                OnNewEvent(new LogEventArgs("Error connecting to OPC server."));
                await channel.AbortAsync();
            }

            return(Tags);
        }
Exemple #17
0
        private static async Task TestAsync()
        {
            // var discoveryUrl = "opc.tcp://localhost:48010"; // UaCppServer - see  http://www.unified-automation.com/
            var discoveryUrl = $"opc.tcp://localhost:26543"; // Workstation.RobotServer

            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);

            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;
            }
        }
Exemple #18
0
        public async Task SetChanel()
        {
            var clientDescription = new ApplicationDescription
            {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = Workstation.ServiceModel.Ua.ApplicationType.Client
            };

            channel = new UaTcpSessionChannel(
                clientDescription,
                null, // no x509 certificates
                //new AnonymousIdentity(),
                new UserNameIdentity("admin", "wago"),
                url,
                SecurityPolicyUris.None);

            try
            {
                await channel.OpenAsync();

                var readRequestGetName = new Workstation.ServiceModel.Ua.ReadRequest
                {
                    NodesToRead = new[] {
                        new Workstation.ServiceModel.Ua.ReadValueId {
                            NodeId      = Workstation.ServiceModel.Ua.NodeId.Parse(Workstation.ServiceModel.Ua.VariableIds.Server_ServerStatus),
                            AttributeId = AttributeIds.Value
                        }
                    }
                };
                var readResultName = await channel.ReadAsync(readRequestGetName);

                var serverStatusGetName = readResultName.Results[0].GetValueOrDefault <Workstation.ServiceModel.Ua.ServerStatusDataType>();
                serverName = serverStatusGetName.BuildInfo.ProductName;


                ReadValueId[] reads = new ReadValueId[itemsNames.Count];
                int           index = 0;
                names = new String[itemsNames.Count];
                foreach (string name in itemsNames)
                {
                    reads[index] = new Workstation.ServiceModel.Ua.ReadValueId
                    {
                        NodeId      = Workstation.ServiceModel.Ua.NodeId.Parse("ns=4;s=|var|" + serverName + "." + name),
                        AttributeId = AttributeIds.Value
                    };
                    //MessageBox.Show(itemsNames.Count.ToString());
                    names[index] = name;
                    index++;
                }
                readRequest = new Workstation.ServiceModel.Ua.ReadRequest
                {
                    NodesToRead = reads
                };
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();

                MessageBox.Show(ex.Message);
            }
        }
        public async Task VectorAdd()
        {
            // 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://*****:*****@"  ------------------");
                Console.WriteLine($"  {result}");

                Console.WriteLine($"\nClosing session '{channel.SessionId}'.");
                await channel.CloseAsync();
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();
                Console.WriteLine(ex.Message);
            }
        }
Exemple #20
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();
            }
        }
Exemple #21
0
        public async Task StackTest()
        {
            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 readRequest = new ReadRequest
            {
                NodesToRead = new[]
                {
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Boolean")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.SByte")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Int16")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Int32")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Int64")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Byte")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.UInt16")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.UInt32")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.UInt64")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Float")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Double")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.String")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.DateTime")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.Guid")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.ByteString")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.XmlElement")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.LocalizedText")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Scalar.QualifiedName")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Boolean")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.SByte")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Int16")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Int32")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Int64")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Byte")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.UInt16")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.UInt32")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.UInt64")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Float")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Double")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.String")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.DateTime")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Guid")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.ByteString")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.XmlElement")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.LocalizedText")
                    },
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.QualifiedName")
                    },
                },
            };

            readRequest = new ReadRequest
            {
                NodesToRead = new[]
                {
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("i=11494")
                    },
                },
            };
            var sw = new Stopwatch();

            sw.Restart();
            for (int i = 0; i < 1; i++)
            {
                var readResponse = await channel.ReadAsync(readRequest);

                foreach (var result in readResponse.Results)
                {
                    StatusCode.IsGood(result.StatusCode)
                    .Should().BeTrue();
                    var obj = result.GetValue();
                }
            }

            sw.Stop();
            logger.LogInformation($"{sw.ElapsedMilliseconds} ms");

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
Exemple #22
0
        public async Task SessionTimeoutCausesFault()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();

            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };

            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);

            var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

            var           selectedTokenType = selectedEndpoint.UserIdentityTokens[0].TokenType;
            IUserIdentity selectedUserIdentity;

            switch (selectedTokenType)
            {
            case UserTokenType.UserName:
                selectedUserIdentity = new UserNameIdentity("root", "secret");
                break;

            case UserTokenType.Certificate:
                selectedUserIdentity = new X509Identity(localCertificate);
                break;

            default:
                selectedUserIdentity = new AnonymousIdentity();
                break;
            }

            var channel = new UaTcpSessionChannel(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint,
                sessionTimeout: 10000);

            Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
            Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
            Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
            await channel.OpenAsync();

            Console.WriteLine($"Activated session '{channel.SessionId}'.");

            // server should close session due to inactivity
            await Task.Delay(20000);

            // should throw exception
            var readRequest = new ReadRequest {
                NodesToRead = new[] { new ReadValueId {
                                          NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value
                                      } }
            };
            await channel.ReadAsync(readRequest);

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
        public async Task TestSubscription()
        {
            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                loggerFactory: this.loggerFactory);

            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($"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;

            Console.WriteLine($"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);

            Console.WriteLine("Subscribe to PublishResponse stream.");
            var numOfResponses = 0;
            var token          = channel.Where(pr => pr.SubscriptionId == id).Subscribe(
                pr =>
            {
                numOfResponses++;

                // 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}");
                    }
                }
            },
                ex =>
            {
                Console.WriteLine("Exception in publish response handler: {0}", ex.GetBaseException().Message);
            });

            await Task.Delay(5000);

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();

            numOfResponses
            .Should().BeGreaterThan(0);
        }
        public async Task ReadIndexRange()
        {
            // 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 ReadRequest. See 'OPC UA Spec Part 4' paragraph 5.10.2
                var readRequest = new ReadRequest
                {
                    // set the NodesToRead to an array of ReadValueIds.
                    NodesToRead = new[] {
                        // construct a ReadValueId from a NodeId and AttributeId.
                        new ReadValueId {
                            // use a saved NodeId or Parse the nodeId from a string.
                            // e.g. "ns=2;s=Demo.Static.Scalar.Double"
                            NodeId = NodeId.Parse("ns=2;s=Demo.CTT.AllProfiles.Arrays.Double"),
                            // variable class nodes have a Value attribute.
                            AttributeId = AttributeIds.Value,
                            // ask to read a range of the underlying array
                            IndexRange = "1:2"
                        }
                    }
                };
                // send the ReadRequest to the server.
                var readResult = await channel.ReadAsync(readRequest);

                // 'Results' will be an array of DataValues, one for every ReadValueId.
                // A DataValue holds the sampled value, timestamps and quality status code.
                var result = readResult.Results[0].GetValueOrDefault <double[]>();

                Console.WriteLine($"Read result: {string.Join(' ', result)}");

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

                Console.WriteLine(ex.Message);
            }
        }