public async Task ValidateCertificateExisting() { using (var dirServer = TempDirectory.Create("Server")) using (var dirClient = TempDirectory.Create("Client")) { var storeServer = new DirectoryStore(dirServer.Name, createLocalCertificateIfNotExist: true); var storeClient = new DirectoryStore(dirClient.Name, acceptAllRemoteCertificates: false); var server = new ApplicationDescription { ApplicationUri = "http://hostname/server", }; // First we create a certificate var(cert, _) = await storeServer.GetLocalCertificateAsync(server); CopyAll(dirServer.Name + @"/own/certs", dirClient.Name + @"/trusted"); // The certificate is now in the expected directory // hence it should be accepted var ret = await storeClient.ValidateRemoteCertificateAsync(cert); ret .Should().BeTrue(); } }
public async Task InvalidApplicationDescription() { var store = new DirectoryStore("tmp"); await store.Invoking(s => s.GetLocalCertificateAsync(null)) .Should().ThrowAsync <ArgumentNullException>(); }
public override ExitCode Execute() { try { switch (AdditionalArgs.Count) { case 1: // Verify a directory inside the store Store.Verify(new ManifestDigest(AdditionalArgs[0]), Handler); break; case 2: // Verify an arbitrary directory DirectoryStore.VerifyDirectory(AdditionalArgs[0], new ManifestDigest(AdditionalArgs[1]), Handler); break; } } catch (DigestMismatchException ex) { Handler.Output(Resources.VerifyImplementation, ex.Message); return(ExitCode.DigestMismatch); } return(ExitCode.OK); }
public async Task ValidateCertificateNotExisting() { using (var dirServer = TempDirectory.Create("Server")) using (var dirClient = TempDirectory.Create("Client", false)) { var storeServer = new DirectoryStore(dirServer.Name, createLocalCertificateIfNotExist: true); var storeClient = new DirectoryStore(dirClient.Name, acceptAllRemoteCertificates: false); var server = new ApplicationDescription { ApplicationUri = "http://hostname/server", }; // First we create a certificate var(cert, _) = await storeServer.GetLocalCertificateAsync(server); // The certificate is not in the expected directory // hence it should not be accepted var ret = await storeClient.ValidateRemoteCertificateAsync(cert); ret .Should().BeFalse(); Directory.EnumerateFiles(dirClient.Name + @"/rejected") .Should().HaveCount(1); } }
private ExitCode Verify() { try { switch (AdditionalArgs.Count) { case 1: throw new OptionException(Resources.MissingArguments + Environment.NewLine + "verify [DIRECTORY] DIGEST" + Environment.NewLine + Resources.StoreVerfiyTryAuditInstead, ""); case 2: // Verify a directory inside the store Store.Verify(new ManifestDigest(AdditionalArgs[1]), Handler); break; case 3: // Verify an arbitrary directory DirectoryStore.VerifyDirectory(AdditionalArgs[1], new ManifestDigest(AdditionalArgs[2]), Handler); break; default: throw new OptionException(Resources.TooManyArguments + Environment.NewLine + "verify [DIRECTORY] DIGEST", ""); } } catch (DigestMismatchException ex) { Handler.Output(Resources.VerifyImplementation, ex.Message); return(ExitCode.DigestMismatch); } return(ExitCode.OK); }
public async Task ValidateCertificateNull() { using (var dir = TempDirectory.Create()) { var store = new DirectoryStore(dir.Name, acceptAllRemoteCertificates: false); await store.Invoking(s => s.ValidateRemoteCertificateAsync(null)) .Should().ThrowAsync <ArgumentNullException>(); } }
public void Constructor() { var store = new DirectoryStore("tmp"); store.AcceptAllRemoteCertificates .Should().BeTrue(); store.CreateLocalCertificateIfNotExist .Should().BeTrue(); }
public async Task InvalidApplicationUri(string uri) { var store = new DirectoryStore("tmp"); var app = new ApplicationDescription { ApplicationUri = uri, }; await store.Invoking(s => s.GetLocalCertificateAsync(app)) .Should().ThrowAsync <ArgumentOutOfRangeException>(); }
public async Task ValidateCertificateAcceptAll() { using (var dir = TempDirectory.Create()) { var store = new DirectoryStore(dir.Name, acceptAllRemoteCertificates: true); var ret = await store.ValidateRemoteCertificateAsync(null); ret .Should().BeTrue(); } }
/// <summary> /// Deletes this temporary directory from the <see cref="IStore"/> it is located in. /// </summary> /// <param name="handler">A callback object used when the the user needs to be asked questions or informed about IO tasks.</param> /// <exception cref="DirectoryNotFoundException">The directory could be found in the store.</exception> /// <exception cref="IOException">The directory could not be deleted.</exception> /// <exception cref="UnauthorizedAccessException">Write access to the store is not permitted.</exception> public override void Delete(ITaskHandler handler) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion handler.RunTask(new SimpleTask(string.Format(Resources.DeletingDirectory, _path), () => { DirectoryStore.DisableWriteProtection(_path); Directory.Delete(_path, recursive: true); })); }
public void DownloadPackage([NotNull] string fastPackageReference, [NotNull] string location) { Directory.CreateDirectory(location); typeof(OneGetCommand).WriteEmbeddedFile("import.bat", Path.Combine(location, "import.bat")); FeedCache = new DiskFeedCache(Path.Combine(location, "interfaces"), OpenPgp); Store = new DirectoryStore(Path.Combine(location, "implementations"), useWriteProtection: false); FeedManager.Refresh = true; var requirements = ParseReference(fastPackageReference); var selections = Solve(requirements); Fetcher.Fetch(SelectionsManager.GetUncachedImplementations(selections)); SelfUpdateCheck(); }
public async Task CreateNoCertificate() { var store = new DirectoryStore("nocert", createLocalCertificateIfNotExist: false); var app = new ApplicationDescription { ApplicationUri = "http://hostname/appname", }; var(cert, key) = await store.GetLocalCertificateAsync(app); cert .Should().BeNull(); key .Should().BeNull(); }
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 ); }
public override ExitCode Execute() { string path = GetPath(); // Init new store to ensure the target is suitable Store = new DirectoryStore(path); var dirs = GetImplementationDirs().ToList(); if (dirs.AddIfNew(path)) { SetImplementationDirs(dirs); return ExitCode.OK; } else { Log.Warn(string.Format(Resources.AlreadyInImplDirs, path)); return ExitCode.NoChanges; } }
public override ExitCode Execute() { string path = GetPath(); // Init new store to ensure the target is suitable Store = new DirectoryStore(path); var dirs = GetImplementationDirs().ToList(); if (dirs.AddIfNew(path)) { SetImplementationDirs(dirs); return(ExitCode.OK); } else { Log.Warn(string.Format(Resources.AlreadyInImplDirs, path)); return(ExitCode.NoChanges); } }
public async Task CertificateDirectoryStructure() { using (var dir = TempDirectory.Create()) { var store = new DirectoryStore(dir.Name, createLocalCertificateIfNotExist: true); var app = new ApplicationDescription { ApplicationUri = "http://hostname/appname", }; await store.GetLocalCertificateAsync(app); Directory.EnumerateFiles(dir.Name + @"/own/certs") .Should().HaveCount(1); Directory.EnumerateFiles(dir.Name + @"/own/private") .Should().HaveCount(1); } }
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); } }
public async Task LoadCertificate() { using (var dir = TempDirectory.Create()) { var store = new DirectoryStore(dir.Name, createLocalCertificateIfNotExist: true); var app = new ApplicationDescription { ApplicationUri = "urn:hostname:appname", }; var(cert1, key1) = await store.GetLocalCertificateAsync(app); var(cert2, key2) = await store.GetLocalCertificateAsync(app); cert1 .Should().Be(cert2); key1 .Should().Be(key2); } }
public async Task CreateCertificate() { using (var dir = TempDirectory.Create()) { var store = new DirectoryStore(dir.Name, createLocalCertificateIfNotExist: true); var app = new ApplicationDescription { ApplicationUri = "http://hostname/appname", }; var(cert, key) = await store.GetLocalCertificateAsync(app); cert .Should().NotBeNull(); key .Should().NotBeNull(); cert.SubjectDN.ToString() .Should().Be("CN=appname,DC=hostname"); } }
public void ShouldHandleRelativePaths() { // Change the working directory string oldWorkingDir = Environment.CurrentDirectory; Environment.CurrentDirectory = _tempDir; try { _store = new DirectoryStore("."); ShouldAllowToAddFolder(); } finally { // Restore the original working directory Environment.CurrentDirectory = oldWorkingDir; } }
public void SetUp() { _handler = new MockTaskHandler(); _tempDir = new TemporaryDirectory("0install-unit-tests"); _store = new DirectoryStore(_tempDir); }
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); } }
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 { } } }
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; } }
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); } }
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); } }
/// <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); }
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); } }
public void DownloadPackage([NotNull] string fastPackageReference, [NotNull] string location) { Directory.CreateDirectory(location); this.GetEmbedded("import.bat").CopyToFile(Path.Combine(location, "import.bat")); FeedCache = new DiskFeedCache(Path.Combine(location, "interfaces"), OpenPgp); Store = new DirectoryStore(Path.Combine(location, "implementations"), useWriteProtection: false); FeedManager.Refresh = true; var requirements = ParseReference(fastPackageReference); var selections = Solve(requirements); Fetcher.Fetch(SelectionsManager.GetUncachedImplementations(selections)); SelfUpdateCheck(); }
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); } }
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); } }
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); } }
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) { } } } }