コード例 #1
0
        public async Task DatapoolReadOpcWriteAsync(OpcDatapoolModel dataModel, UaTcpSessionChannel channel)
        {
            // Read the Thermo tag value and write to the OPC Server
            DataValue value;

            switch (dataModel.TagInfo.Type)
            {
            case Thermo.Datapool.Datapool.dpTypes.FLOAT:
                value = new DataValue(new Variant(dataModel.TagInfo.AsDouble), sourceTimestamp: DateTime.Now, serverTimestamp: DateTime.Now);
                break;

            case Thermo.Datapool.Datapool.dpTypes.INT:
                value = new DataValue(new Variant(dataModel.TagInfo.AsInt), sourceTimestamp: DateTime.Now);
                break;

            case Thermo.Datapool.Datapool.dpTypes.STRING:
                value = new DataValue(new Variant(dataModel.TagInfo.AsString), sourceTimestamp: DateTime.Now);
                break;

            case Thermo.Datapool.Datapool.dpTypes.BOOL:
                value = new DataValue(new Variant(dataModel.TagInfo.AsBoolean), sourceTimestamp: DateTime.Now);
                break;

            default:
                throw new InvalidCastException($"Cannot write {dataModel.TagInfo.Type} data type to OPC.");
            }
            var writeRequest = new WriteRequest {
                NodesToWrite = new WriteValue[] { new WriteValue {
                                                      NodeId = dataModel.NodeId, Value = value, AttributeId = AttributeIds.Value
                                                  } }
            };
            var response = await channel.WriteAsync(writeRequest);
        }
コード例 #2
0
        public async Task Polling()
        {
            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 {
                                          NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value
                                      } }
            };

            for (int i = 0; i < 10; i++)
            {
                var readResult = await channel.ReadAsync(readRequest);

                logger.LogInformation("Read {0}", readResult.Results[0].GetValueOrDefault <DateTime>());
                await Task.Delay(1000);
            }

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
コード例 #3
0
        public async Task Read()
        {
            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 {
                                          NodeId = NodeId.Parse(VariableIds.Server_ServerStatus), AttributeId = AttributeIds.Value
                                      } }
            };
            var readResult = await channel.ReadAsync(readRequest);

            var serverStatus = readResult.Results[0].GetValueOrDefault <ServerStatusDataType>();

            logger.LogInformation("Server status:");
            logger.LogInformation("  ProductName: {0}", serverStatus.BuildInfo.ProductName);
            logger.LogInformation("  SoftwareVersion: {0}", serverStatus.BuildInfo.SoftwareVersion);
            logger.LogInformation("  ManufacturerName: {0}", serverStatus.BuildInfo.ManufacturerName);
            logger.LogInformation("  State: {0}", serverStatus.State);
            logger.LogInformation("  CurrentTime: {0}", serverStatus.CurrentTime);

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
コード例 #4
0
        /// <summary>
        /// Reads first/next level of tag tree.
        /// </summary>
        async Task <Tag> ReadTag(ReferenceDescription[] rds, UaTcpSessionChannel channel, Tag tag)
        {
            ReadValueId[] items = new ReadValueId[1];
            items[0] = new ReadValueId {
                NodeId = NodeId.Parse(rds.Last().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(rds.Take(rds.Length - 1).ToList());
            }
            tag.NestedName(rds.Last().DisplayName);

            if (rds.Length > 2)
            {
                tag.Group4 = rds[1].DisplayName.ToString();
            }
            if (rds.Length > 1)
            {
                tag.Group3 = rds[0].DisplayName.ToString();
            }

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

            return(tag);
        }
コード例 #5
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;

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

            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                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();
        }
コード例 #6
0
        private async Task <UaTcpSessionChannel> CreateChannelAsync(string endpointUrl, CancellationToken token = default)
        {
            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.");
                    this.channelMap.TryRemove(endpointUrl, out Lazy <Task <UaTcpSessionChannel> > 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}");
                throw;
            }
        }
コード例 #7
0
ファイル: UnitTest1.cs プロジェクト: hhdang/opc-ua-client
        public async Task ConnnectToAllEndpoints()
        {
            // 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);

            // 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,
                        async e => selectedUserIdentity,
                        selectedEndpoint,
                        loggerFactory: this.loggerFactory,
                        options: new UaTcpSessionChannelOptions {
                        TimeoutHint = 60000
                    });

                    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}'.");

                    Console.WriteLine($"Closing session '{channel.SessionId}'.");
                    await channel.CloseAsync();
                }
            }
        }
コード例 #8
0
ファイル: OPCUAHelper.cs プロジェクト: dgiot/dgiot_dtu
        private static async Task ConnectAsync()
        {
            channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                null,
                EndpointUrl);

            await channel.OpenAsync();
        }
コード例 #9
0
        public async Task StructureTest()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                loggerFactory: loggerFactory);

            await channel.OpenAsync();

            var readRequest = new ReadRequest
            {
                NodesToRead = new[]
                {
                    new ReadValueId {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Structure")
                    },
                },
            };

            var readResponse = await channel.ReadAsync(readRequest);

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

            // reading this node returns an array of ExtensionObjects
            var obj = readResponse.Results[0].Value;

            // create new DataValue for writing.  Most servers reject writing values with timestamps.
            var newValue = new DataValue(obj);

            var writeRequest = new WriteRequest
            {
                NodesToWrite = new[]
                {
                    new WriteValue {
                        AttributeId = AttributeIds.Value, NodeId = NodeId.Parse("ns=2;s=Demo.Static.Arrays.Structure"), Value = newValue
                    },
                },
            };
            var writeResponse = await channel.WriteAsync(writeRequest);

            foreach (var result in writeResponse.Results)
            {
                StatusCode.IsGood(result)
                .Should().BeTrue();
            }

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
コード例 #10
0
        public async Task ConnnectToEndpointsWithNoSecurityAndWithNoCertificate()
        {
            // 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.Where(e => e.SecurityMode == MessageSecurityMode.None))
            {
                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,
                        null,
                        selectedUserIdentity,
                        selectedEndpoint,
                        loggerFactory: this.loggerFactory);

                    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}'.");

                    await channel.OpenAsync();

                    Console.WriteLine($"Closing session '{channel.SessionId}'.");
                    await channel.CloseAsync();
                }
            }
        }
コード例 #11
0
 public BrowseTagsViewModel(ReferenceDescription node, UaTcpSessionChannel currentChannel, ITagBrower _parent, bool loadChildren = false)
 {
     parent = _parent;
     TreeViewItemViewModelHelpers.InitializeChildren(this, loadChildren);
     //TreeViewItemViewModelHelpers.CheckForEndTag(this, node);
     Node = new OpcTagModel()
     {
         Node = node
     };
     channel = currentChannel;
 }
コード例 #12
0
 private async Task CloseChannel()
 {
     if (connection == null)
     {
         return;
     }
     try {
         await connection.CloseAsync();
     }
     catch (Exception) { }
     connection = null;
 }
コード例 #13
0
        /// <summary>
        /// Reads tag unit.
        /// </summary>
        async Task ReadUnit(ReferenceDescription[] rds, UaTcpSessionChannel channel, Tag tag)
        {
            ReadValueId[] unit = new ReadValueId[1];
            unit[0] = new ReadValueId {
                NodeId = NodeId.Parse(rds.Last().NodeId.ToString()), AttributeId = AttributeIds.Value
            };
            ReadRequest unitRequest = new ReadRequest {
                NodesToRead = unit
            };
            ReadResponse unitResponse = await channel.ReadAsync(unitRequest);

            ExtensionObject EO = (ExtensionObject)unitResponse.Results[0].Value;
            EUInformation   EU = (EUInformation)EO.Body;

            tag.Unit = EU.DisplayName; //zapis jednostki
        }
コード例 #14
0
        public async Task BrowseObjects()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                SecurityPolicyUris.None,
                loggerFactory: loggerFactory);

            await channel.OpenAsync();

            var rds           = new List <ReferenceDescription>();
            var browseRequest = new BrowseRequest {
                NodesToBrowse = new[] { new BrowseDescription {
                                            NodeId = ExpandedNodeId.ToNodeId(ExpandedNodeId.Parse(ObjectIds.ObjectsFolder), channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Unspecified, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true
                                        } }, RequestedMaxReferencesPerNode = 1000
            };
            var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false);

            rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References));
            var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray();

            while (continuationPoints.Length > 0)
            {
                var browseNextRequest = new BrowseNextRequest {
                    ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false
                };
                var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest);

                rds.AddRange(browseNextResponse.Results.Where(result => result.References != null).SelectMany(result => result.References));
                continuationPoints = browseNextResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray();
            }

            rds
            .Should().NotBeEmpty();

            logger.LogInformation("+ Objects, 0:Objects, Object");
            foreach (var rd in rds)
            {
                logger.LogInformation("   + {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
            }

            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
コード例 #15
0
        public async Task VectorAdd()
        {
            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                new AnonymousIdentity(),
                "opc.tcp://*****:*****@"  ------------------");
            Console.WriteLine($"  {result}");

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

            result.Z
            .Should().Be(6.0);
        }
コード例 #16
0
 public void ConfigureClient()
 {
     clientDescription = new ApplicationDescription
     {
         ApplicationName = _clientOptions.ApplicationName,
         ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:{_clientOptions.ApplicationName}",
         ApplicationType = ApplicationType.Client
     };
     certificateStore = new DirectoryStore("./pki");
     channel          = new UaTcpSessionChannel(
         clientDescription,
         null,
         new AnonymousIdentity(),
         _clientOptions.Endpoint,    //server endpoint
         SecurityPolicyUris.None,
         _loggerFactory
         );
 }
コード例 #17
0
ファイル: OPC.cs プロジェクト: krzyfre/HMI
        public static async Task <bool> StartOPC()
        {
            var clientDescription = new ApplicationDescription
            {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };

            try
            {
                if (channel != null)
                {
                    channel.CloseAsync();
                }
            }
            catch { }


            // create a 'UaTcpSessionChannel', a client-side channel that opens a 'session' with the server.
            channel = new UaTcpSessionChannel(
                clientDescription,
                null,                    // no x509 certificates
                new AnonymousIdentity(), // no user identity

                //IP serwera
                path,                     // the public endpoint of a server at opcua.rocks.
                SecurityPolicyUris.None); // no encryption
            try
            {
                // try opening a session and reading a few nodes.
                await channel.OpenAsync();

                //HMI_SuctionCup1
                return(true);
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();

                Console.WriteLine(ex.Message);
                return(true);
            }
        }
コード例 #18
0
        public async Task ConnectWithSecurity()
        {
            // 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();

                // success! client session opened with these settings.
                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}'.");

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

                Console.WriteLine(ex.Message);
            }
        }
コード例 #19
0
        public async Task BrowseRoot()
        {
            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                SecurityPolicyUris.None,
                loggerFactory: this.loggerFactory);

            await channel.OpenAsync();

            var rds           = new List <ReferenceDescription>();
            var browseRequest = new BrowseRequest {
                NodesToBrowse = new[] { new BrowseDescription {
                                            NodeId = ExpandedNodeId.ToNodeId(ExpandedNodeId.Parse(ObjectIds.RootFolder), channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Unspecified, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true
                                        } }, RequestedMaxReferencesPerNode = 1000
            };
            var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false);

            rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References));
            var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray();

            while (continuationPoints.Length > 0)
            {
                var browseNextRequest = new BrowseNextRequest {
                    ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false
                };
                var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest);

                rds.AddRange(browseNextResponse.Results.Where(result => result.References != null).SelectMany(result => result.References));
                continuationPoints = browseNextResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray();
            }

            Assert.IsTrue(rds.Count == 3);

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
コード例 #20
0
        /// <summary>
        /// Signals the channel state is Closing.
        /// </summary>
        /// <param name="channel">The session channel. </param>
        /// <param name="token">A cancellation token. </param>
        /// <returns>A task.</returns>
        private async Task WhenChannelClosingAsync(UaTcpSessionChannel channel, CancellationToken token = default(CancellationToken))
        {
            var          tcs     = new TaskCompletionSource <bool>();
            EventHandler handler = (o, e) =>
            {
                tcs.TrySetResult(true);
            };

            using (token.Register(state => ((TaskCompletionSource <bool>)state).TrySetCanceled(), tcs, false))
            {
                try
                {
                    channel.Closing += handler;
                    if (channel.State == CommunicationState.Opened)
                    {
                        await tcs.Task;
                    }
                }
                finally
                {
                    channel.Closing -= handler;
                }
            }
        }
コード例 #21
0
ファイル: OpcUaClient.cs プロジェクト: SAJB-Inc/OpcUaWinForms
        public static async Task Run(CancellationToken cancelToken, Action onValueChanged)
        {
            var clientDescription = new ApplicationDescription {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };
            var channel = new UaTcpSessionChannel(
                clientDescription,
                null,
                new AnonymousIdentity(),
                "opc.tcp://localhost:4840",
                SecurityPolicyUris.None
                );

            try {
                await channel.OpenAsync();

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

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

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

                Console.WriteLine(ex.Message);
            }
        }
コード例 #22
0
        /// <summary>
        /// The state machine manages the state of the subscription.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task StateMachineAsync(CancellationToken token = default(CancellationToken))
        {
            while (!token.IsCancellationRequested)
            {
                await this.whenSubscribed.Task;

                this.progress.Report(CommunicationState.Opening);

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

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

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

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

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

                            this.progress.Report(CommunicationState.Opened);

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

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

                        this.progress.Report(CommunicationState.Closed);
                    }
                    catch (Exception ex)
                    {
                        this.logger?.LogError($"Error creating subscription. {ex.Message}");
                        this.progress.Report(CommunicationState.Faulted);
                        await Task.Delay(2000);
                    }
                }
                catch (Exception ex)
                {
                    this.logger?.LogTrace($"Error getting channel. {ex.Message}");
                    this.progress.Report(CommunicationState.Faulted);
                    await Task.Delay(2000);
                }
            }
        }
コード例 #23
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(),
                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);
            }
        }
コード例 #24
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();
        }
コード例 #25
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")
                    },
                },
            };

            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();
        }
コード例 #26
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();
        }
コード例 #27
0
        public async Task TestSubscription()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                EndpointUrl,
                loggerFactory: loggerFactory);

            await channel.OpenAsync();

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

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

            var id = res.SubscriptionId;

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

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

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

            void onPublish(PublishResponse pr)
            {
                numOfResponses++;

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

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

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

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

            await Task.Delay(5000);

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

            numOfResponses
            .Should().BeGreaterThan(0);
        }
コード例 #28
0
        public async Task ReadHistoryRawValues()
        {
            // 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}'.");

                Console.WriteLine("\nCheck if DataLogger active.");

                // check if DataLoggerActive is true. If not, then call method StartLogging.
                var req = new ReadRequest
                {
                    NodesToRead = new[] {
                        new ReadValueId {
                            NodeId = NodeId.Parse("ns=2;s=Demo.History.DataLoggerActive"), AttributeId = AttributeIds.Value
                        }
                    },
                };
                var res = await channel.ReadAsync(req);

                if (StatusCode.IsBad(res.Results[0].StatusCode))
                {
                    throw new InvalidOperationException("Error reading 'Demo.History.DataLoggerActive'. ");
                }
                var isActive = res.Results[0].GetValueOrDefault <bool>();

                if (!isActive)
                {
                    Console.WriteLine("Activating DataLogger.");

                    var req1 = new CallRequest
                    {
                        MethodsToCall = new[] {
                            new CallMethodRequest {
                                ObjectId = NodeId.Parse("ns=2;s=Demo.History"), // parent node
                                MethodId = NodeId.Parse("ns=2;s=Demo.History.StartLogging")
                            },
                        },
                    };
                    var res1 = await channel.CallAsync(req1);

                    if (StatusCode.IsBad(res1.Results[0].StatusCode))
                    {
                        throw new InvalidOperationException("Error calling method 'Demo.History.StartLogging'.");
                    }
                    Console.WriteLine("Note: Datalogger has just been activated, so there will be little or no history data to read.");
                    Console.WriteLine("      Try again in 1 minute.");
                }

                Console.WriteLine("\nReading history for last 1 minute(s).");

                // A continuation point is returned if there are more values to return than the
                // limit set by parameter NumValuesPerNode. A client should continue calling HistoryRead
                // until the continuation point returns null.
                byte[] cp = null;

                do
                {
                    var req2 = new HistoryReadRequest
                    {
                        HistoryReadDetails = new ReadRawModifiedDetails
                        {
                            StartTime        = DateTime.UtcNow.Add(TimeSpan.FromSeconds(-60)), // set start time to 1 minute ago
                            EndTime          = DateTime.UtcNow,
                            NumValuesPerNode = 100,                                            // sets limit. if there are more values to return then a continuation point is returned.
                            ReturnBounds     = false,                                          // set true to return interpolated values for the start and end times
                        },
                        TimestampsToReturn        = TimestampsToReturn.Both,
                        ReleaseContinuationPoints = false, // set true to abandon returning any remaining values from this interval
                        NodesToRead = new[] {
                            new HistoryReadValueId {
                                NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory"), ContinuationPoint = cp
                            },
                        },
                    };

                    var res2 = await channel.HistoryReadAsync(req2);

                    if (StatusCode.IsGood(res2.Results[0].StatusCode))
                    {
                        var historyData = res2.Results[0].HistoryData as HistoryData;

                        Console.WriteLine($"Found {historyData.DataValues.Length} value(s) for node '{req2.NodesToRead[0].NodeId}':");

                        foreach (var dv in historyData.DataValues)
                        {
                            Console.WriteLine($"Read {dv.Value}, q: {dv.StatusCode}, ts: {dv.SourceTimestamp}");
                        }

                        cp = res2.Results[0].ContinuationPoint;
                        // if ContinuationPoint is null, then there is no more data to return.
                        if (cp == null)
                        {
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine($"HistoryRead return statuscode: {res2.Results[0].StatusCode}");
                        break;
                    }
                } while (cp != null); // loop while ContinuationPoint is not null.

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

                Console.WriteLine(ex.Message);
            }
        }
コード例 #29
0
        private static async Task TestAsync()
        {
            var loggerFactory = new LoggerFactory();

            loggerFactory.AddDebug(LogLevel.Trace);

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

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

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

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

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

            try
            {
                await channel.OpenAsync();

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

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

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

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

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

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

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

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

                var id = subscriptionResponse.SubscriptionId;

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

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

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

                Console.ReadKey(true);

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

                token.Dispose();

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

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

                await channel.AbortAsync();

                throw;
            }
        }
コード例 #30
0
        /// <summary>
        /// Opens a session with the remote endpoint.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task OpenAsync(CancellationToken token = default(CancellationToken))
        {
            await this.semaphore.WaitAsync(token).ConfigureAwait(false);

            try
            {
                if (this.RemoteEndpoint == null)
                {
                    // If specific endpoint is not provided, use discovery to select endpoint with highest
                    // security level.
                    try
                    {
                        this.Logger?.LogInformation($"Discovering endpoints of '{this.discoveryUrl}'.");
                        var getEndpointsRequest = new GetEndpointsRequest
                        {
                            EndpointUrl = this.discoveryUrl,
                            ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                        };
                        var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false);

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

                        this.RemoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();
                        this.Logger?.LogTrace($"Success discovering endpoints of '{this.discoveryUrl}'.");
                    }
                    catch (Exception ex)
                    {
                        this.Logger?.LogError($"Error discovering endpoints of '{this.discoveryUrl}'. {ex.Message}");
                        throw;
                    }
                }

                // throw here to exit state machine.
                token.ThrowIfCancellationRequested();

                // evaluate the user identity provider (may show a dialog).
                var userIdentity = await this.UserIdentityProvider(this.RemoteEndpoint);

                try
                {
                    this.linkToken?.Dispose();
                    if (this.innerChannel != null && this.innerChannel.State != CommunicationState.Closed)
                    {
                        await this.innerChannel.AbortAsync();
                    }

                    this.innerChannel = new UaTcpSessionChannel(
                        this.LocalDescription,
                        this.CertificateStore,
                        userIdentity,
                        this.RemoteEndpoint,
                        this.loggerFactory,
                        this.SessionTimeout,
                        this.TimeoutHint,
                        this.DiagnosticsHint,
                        this.LocalReceiveBufferSize,
                        this.LocalSendBufferSize,
                        this.LocalMaxMessageSize,
                        this.LocalMaxChunkCount);

                    await this.innerChannel.OpenAsync(token).ConfigureAwait(false);

                    this.linkToken = this.pendingRequests.LinkTo(this.innerChannel);

                    //// create an internal subscription.
                    //var subscriptionRequest = new CreateSubscriptionRequest
                    //{
                    //    RequestedPublishingInterval = DefaultPublishingInterval,
                    //    RequestedMaxKeepAliveCount = DefaultKeepaliveCount,
                    //    RequestedLifetimeCount = (uint)(this.SessionTimeout / DefaultPublishingInterval),
                    //    PublishingEnabled = true,
                    //    Priority = 0
                    //};
                    //var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);
                    //this.subscriptionId = subscriptionResponse.SubscriptionId;
                }
                catch (Exception ex)
                {
                    this.Logger?.LogError($"Error opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'. {ex.Message}");
                    throw;
                }
            }
            finally
            {
                this.semaphore.Release();
            }
        }