private void ConnectionAgent() { while (!_connectionEnd.WaitOne(0) && !Connected) try { URL url = new URL(_OpcSection.Server.Name); _Server = new Opc.Da.Server(new OpcCom.Factory(), null); _Server.Connect(url, new ConnectData(new NetworkCredential())); _groupRead = (Subscription)_Server.CreateSubscription(_GroupReadState); _groupWrite = (Subscription)_Server.CreateSubscription(_GroupWriteState); for (int i = 0; i < _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags.Count; i++) { _Items[i] = new Opc.Da.Item(); //_Items[i].ItemName = String.Format("{0}{1}", _OpcSection.Server.Channel, _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name); _Items[i].ItemName = _OpcSection.Server.Channel + "." + _OpcSection.Server.Device + "." + _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name; //string itmNam = String.Format("{0}]{1}", _OpcSection.Server.Channel, _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name); _logger.LogInfo(/*Mtd*/ ": recognized element " + _Items[i].ItemName); } _Items = _groupRead.AddItems(_Items); _groupRead.DataChanged += new DataChangedEventHandler(Group_DataChanged); } catch (Exception ex) { _logger.LogError(ex); } }
private void WriteData(string itemName, int value) { groupWrite.RemoveItems(groupWrite.Items); List <Item> writeList = new List <Item>(); List <ItemValue> valueList = new List <ItemValue>(); Item itemToWrite = new Item(); itemToWrite.ItemName = itemName; ItemValue itemValue = new ItemValue(itemToWrite); itemValue.Value = value; writeList.Add(itemToWrite); valueList.Add(itemValue); //IMPORTANT: //#1: assign the item to the group so the items gets a ServerHandle groupWrite.AddItems(writeList.ToArray()); // #2: assign the server handle to the ItemValue for (int i = 0; i < valueList.Count; i++) { valueList[i].ServerHandle = groupWrite.Items[i].ServerHandle; } // #3: write groupWrite.Write(valueList.ToArray()); }
public int ReadValue(string tag) { if (!Connected) { return(-1); } tag = _OpcSection.Server.Channel + "." + _OpcSection.Server.Device + "." + tag; //tag = _OpcSection.Server.Channel + tag; _logger.LogInfo("OPC - Read Tag: " + tag); //_logger.LogInfo(/*Mtd*/ ": " + tag); Item[] itemToRead = new Item[1]; itemToRead[0] = new Item(); itemToRead[0].ItemName = tag; bool itemFound = false; foreach (Item item in _groupRead.Items) { if (item.ItemName == itemToRead[0].ItemName) { itemToRead[0].ServerHandle = item.ServerHandle; itemFound = true; break; } } if (!itemFound) { int /*original length before AddItems*/ len = _groupWrite.Items.Length; try { ItemResult[] itmRsl = _groupWrite.AddItems(itemToRead); if (/*OK?*/ _groupWrite.Items.Length > len) { itemToRead[0].ServerHandle = _groupWrite.Items[_groupWrite.Items.Length - 1].ServerHandle; } else { string /*diagnostic message*/ msg = MethodBase.GetCurrentMethod().Name + ": " + itemToRead[0].ItemName + " rejected; " + itmRsl[0].DiagnosticInfo; _logger.LogError(/*Mtd*/ ": " + Utilities.TextTidy(msg)); return(-1); } } catch (Exception ex) { _logger.LogError(ex); throw ex; } } ItemValueResult[] valueResults = _groupRead.Read(itemToRead); return(System.Convert.ToInt32(valueResults[0].Value)); }
private void Subscribe(NodeId[] nodeIds) { var monItems = new List <MonitoredItem>(); var newNodeIds = new List <NodeId>(); lock (_subscribedValues) { for (int i = 0; i < nodeIds.Length; i++) { if (!_subscribedValues.ContainsKey(nodeIds[i])) { var monitoredItem = CreateMonitoredItem(nodeIds[i]); monitoredItem.Notification += MonitoredItem_Notification; monItems.Add(monitoredItem); newNodeIds.Add(nodeIds[i]); _subscribedValues.Add(nodeIds[i], new VariableValue(monitoredItem) { LastRead = DateTimeOffset.UtcNow, Value = new DataValue(Variant.Null) }); } } } if (monItems.Count > 0) { // Force read of current value. InitializeNodeValues(nodeIds); _logger.LogInformation("Subscribing to {0} data values", monItems.Count); _subscription.AddItems(monItems); _subscription.ApplyChanges(); } }
/// <summary> /// Подписка на изменение конкретного значения на сервере /// </summary> public void Subscribe(string itemName) { var subscriptionState = new SubscriptionState { Name = itemName, Active = true }; try { subscription = (Opc.Da.Subscription)serverHandle.CreateSubscription(subscriptionState); } catch (Exception exception) { Console.WriteLine("Error {0}", exception.Message); return; } Opc.Da.Item[] items = new Opc.Da.Item[1]; items[0] = new Opc.Da.Item(); items[0].ItemName = itemName; items = subscription.AddItems(items); subscription.DataChanged += new Opc.Da.DataChangedEventHandler(DataChange); }
private void SubscribeToRead(ReadParameter[] readParameters) { var newParameters = readParameters.Where(p => !_itemValues.ContainsKey(p.Address)).ToArray(); if (!newParameters.Any()) { return; } var items = newParameters.Select(p => new Item { ItemName = p.Address }).ToArray(); try { _group.AddItems(items); } catch { _server.CancelSubscription(_group); _canSubscribe = false; } if (_canSubscribe) { var itemValues = _server.Read(items); foreach (var itemValue in itemValues) { _itemValues.Add(itemValue.ItemName, itemValue.Value); } } }
private void ConnectionAgent() { while (!_connectionEnd.WaitOne(0) && !Connected) { try { URL url = new URL(_OpcSection.Server.Name); _Server = new Opc.Da.Server(new OpcCom.Factory(), null); _Server.Connect(url, new ConnectData(new NetworkCredential())); _groupRead = (Subscription)_Server.CreateSubscription(_GroupReadState); _groupWrite = (Subscription)_Server.CreateSubscription(_GroupWriteState); for (int i = 0; i < _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags.Count; i++) { _Items[i] = new Opc.Da.Item(); //_Items[i].ItemName = String.Format("{0}{1}", _OpcSection.Server.Channel, _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name); _Items[i].ItemName = _OpcSection.Server.Channel + "." + _OpcSection.Server.Device + "." + _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name; //string itmNam = String.Format("{0}]{1}", _OpcSection.Server.Channel, _OpcSection.Server.TagGroup.GetElement(_TagGroup).Tags[i].Name); _logger.LogInfo(/*Mtd*/ ": recognized element " + _Items[i].ItemName); } _Items = _groupRead.AddItems(_Items); _groupRead.DataChanged += new DataChangedEventHandler(Group_DataChanged); } catch (Exception ex) { _logger.LogError(ex); } } }
public async Task PublishRequestCount() { var subscriptionList = new List <Subscription>(); var numOfNotifications = 0L; const int TestWaitTime = 10000; const int MonitoredItemsPerSubscription = 50; const int Subscriptions = 50; const int MaxServerPublishRequest = 20; for (int i = 0; i < Subscriptions; i++) { var subscription = new Subscription(m_session.DefaultSubscription) { PublishingInterval = 0, DisableMonitoredItemCache = true, PublishingEnabled = true }; subscriptionList.Add(subscription); var list = Enumerable.Range(1, MonitoredItemsPerSubscription).Select(_ => new MonitoredItem(subscription.DefaultItem) { StartNodeId = new NodeId("Scalar_Simulation_Int32", 2), SamplingInterval = 0, }).ToList(); var dict = list.ToDictionary(item => item.ClientHandle, _ => DateTime.MinValue); subscription.AddItems(list); var result = m_session.AddSubscription(subscription); Assert.True(result); await subscription.CreateAsync(); var publishInterval = (int)subscription.CurrentPublishingInterval; TestContext.Out.WriteLine($"CurrentPublishingInterval: {publishInterval}"); subscription.FastDataChangeCallback = (_, notification, __) => { notification.MonitoredItems.ForEach(item => { Interlocked.Increment(ref numOfNotifications); }); }; } var stopwatch = Stopwatch.StartNew(); await Task.Delay(1000); // verify that number of active publishrequests is never exceeded while (stopwatch.ElapsedMilliseconds < TestWaitTime) { // use the sample server default for max publish request count Assert.GreaterOrEqual(MaxServerPublishRequest, m_session.GoodPublishRequestCount); await Task.Delay(100); } foreach (var subscription in subscriptionList) { var result = await m_session.RemoveSubscriptionAsync(subscription); Assert.True(result); } }
private void Subscribe(CreateSubscription callback) { _callback = callback; _items.ForEach(i => i.Notification += OnNotification); _subscription.AddItems(_items); _session.AddSubscription(_subscription); _subscription.Create(); }
private void btReadWrite_Click(object sender, EventArgs e) { if (_server != null && _server.IsConnected) { _subscriptionWrite.RemoveItems(_subscriptionWrite.Items); _subscriptionWrite.AddItems(new[] { new Item { ItemName = txtVariableWrite.Text }, }); var items = (ItemValueResult[])_subscriptionWrite.Read(_subscriptionWrite.Items); var item = items.FirstOrDefault(x => x.ItemName == txtVariableWrite.Text); RtbDataChangedWrite = item == null ? @"Variable NOT Found." : $"Variable:{item.ItemName}\n\nValue:{item.Value}\nQuality:{item.Quality.QualityBits.ToString()}\nTimeStamp:{item.Timestamp}"; } }
private void CreateSubscriptionsFromXml(List <XmlOpcUaSubscription> xmlSubscriptions) { _subscriptions = new List <Subscription>(); foreach (XmlOpcUaSubscription xmlSub in xmlSubscriptions) { try { int pubInt = Convert.ToInt32(xmlSub.XmlPublishingInterval); // A list of monitored items is created, which are later recorded by the client. var monitoredItems = new List <MonitoredItem>(); // For this purpose, the list of Opc variables from the XML configuration is transferred. foreach (XmlOpcUaVariable opcvariable in xmlSub.XmlOpcUaVariables) { // A monitored item is created for each C_OpcUaVariable object. MonitoredItem monitoredItem = CreateMonitoredItemFromXml(opcvariable); // The created monitored item is added to the list. monitoredItems.Add(monitoredItem); } // Subscription is created. Subscription sub = CreateSubscription(pubInt); // MonitoredItems are added. if (monitoredItems != null) { sub.AddItems(monitoredItems); } // Subscription is added to the internal list. _subscriptions.Add(sub); } catch (Exception ex) { throw new Exception(" The subscription with the interval " + xmlSub.XmlPublishingInterval + " from the server " + _xmlConfig.XmlOpcUaServer.XmlOpcUrl + " could not be created ", ex); } foreach (Subscription sub in _subscriptions) { try { AddSubscriptionToSession(sub); } catch (Exception ex) { throw new Exception(" The subscription with the Interval " + sub.PublishingInterval + " could not to the server " + _xmlConfig.XmlOpcUaServer.XmlOpcUrl + " added ", ex); } } } }
private void txtVariableRead_TextChanged(object sender, EventArgs e) { if (_server != null && _server.IsConnected) { _subscription.RemoveItems(_subscription.Items); _subscription.AddItems(new[] { new Item { ItemName = txtVariableRead.Text }, }); RtbDataChangedRead = @"Variable NOT Found;"; RtbRead = string.Empty; } }
public static void browse() { Console.WriteLine("Step 3 - Browse the server namespace."); ReferenceDescriptionCollection refs; Byte[] cp; session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs); Console.WriteLine("DisplayName: BrowseName, NodeClass, NodeID"); foreach (var rd in refs) { string space = " "; Console.WriteLine("{0}: {1}, {2}, {3}", rd.DisplayName, rd.BrowseName, rd.NodeClass, rd.NodeId); obhod(session, rd, space); } var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 10 }; Data.list.Add(new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258" }); foreach (string name in Data.tags.Keys) { Data.list.Add(new MonitoredItem(subscription.DefaultItem) { DisplayName = Data.tags[name].DisplayName, StartNodeId = Data.tags[name].NodeId }); } Data.list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(Data.list); session.AddSubscription(subscription); subscription.Create(); }
/// <summary> /// Подписка на изменение значения на сервере /// </summary> public void SubscribeAll() { var subscriptionState = new SubscriptionState { Name = "All", Active = true }; subscription = (Opc.Da.Subscription)serverHandle.CreateSubscription(subscriptionState); Opc.Da.Item[] items = tagList.ToArray(); items = subscription.AddItems(items); subscription.DataChanged += new Opc.Da.DataChangedEventHandler(DataChange); }
public void SubscribedMonitoredItems(ICollection <MonitoredItem> items) { if (_subscription == null || !_subscription.Created) { return; } if (items == null || !items.Any()) { return; } if (_callback != null) { foreach (var monitoredItem in items) { monitoredItem.Notification += _callback.Invoke; } } try { _subscription.AddItems(items); _subscription.ApplyChanges(); } catch (ServiceResultException ex) { if (ex.StatusCode == StatusCodes.BadRequestTimeout) { SysLog.Warn("BadRequestTimeout error message reported from server."); } else { SysLog.Warn("Error reported from server. Message: ", ex); OnCheckConnectionTimerOnElapsed(this, new EventArgs() as ElapsedEventArgs); } } catch (Exception ex) { SysLog.Error("Unexpected error.", ex); OnCheckConnectionTimerOnElapsed(this, new EventArgs() as ElapsedEventArgs); } finally { SetCurrentListMonitoredItemsSubscribed(items); } }
private void CreateSubscription() { if (IsAvailable) { if (ClientSubscription == null) { // initialize subscription. ClientSubscription = new Subscription(ClientSession.DefaultSubscription) { PublishingInterval = 100 }; //ClientSubscription.MaxNotificationsPerPublish = 0; //ClientSubscription.Priority = 0; //ClientSubscription.PublishingEnabled = true; } List <MonitoredItem> MonitoredItem_List = new List <MonitoredItem>(); foreach (var item in TagSubscriptionDictionary) { OPCTag MyTag = item.Value as OPCTag; MonitoredItem MyMonitoredItem = new MonitoredItem(ClientSubscription.DefaultItem) { DisplayName = MyTag.Name, StartNodeId = MyTag.Address }; MyMonitoredItem.Notification += MyTag.OnSubscriptionNotification; MonitoredItem_List.Add(MyMonitoredItem); } ClientSubscription.AddItems(MonitoredItem_List); if (!IsSubscriptionActive) { ClientSession.AddSubscription(ClientSubscription); ClientSubscription.Create(); IsSubscriptionActive = true; } else { ClientSubscription.Modify(); } } else { Logger?.LogWarning($"OPC - Tag Subscription - Client current state is not available. Subscription will be created on next connection."); } }
private void ConnectToOpcServer() { // 1st: Create a server object and connect to the RSLinx OPC Server try { server = new Opc.Da.Server(fact, null); server.Url = new Opc.URL("opcda://localhost/RSLinx OPC Server"); //2nd: Connect to the created server server.Connect(); //Read group subscription groupState = new Opc.Da.SubscriptionState(); groupState.Name = "myReadGroup"; groupState.UpdateRate = 200; groupState.Active = true; //Read group creation groupRead = (Opc.Da.Subscription)server.CreateSubscription(groupState); groupRead.DataChanged += new Opc.Da.DataChangedEventHandler(groupRead_DataChanged); Item item = new Item(); item.ItemName = "[MYPLC]N7:0"; itemsList.Add(item); item = new Item(); item.ItemName = "[MYPLC]O:0/0"; itemsList.Add(item); item = new Item(); item.ItemName = "[MYPLC]B3:0/3"; itemsList.Add(item); groupRead.AddItems(itemsList.ToArray()); groupStateWrite = new Opc.Da.SubscriptionState(); groupStateWrite.Name = "myWriteGroup"; groupStateWrite.Active = false; groupWrite = (Opc.Da.Subscription)server.CreateSubscription(groupStateWrite); } catch (Exception exc) { MessageBox.Show(exc.Message); } }
public Subscription Execute(List <DataItem> dataItems) { Subscription subscription = new Subscription(opcSession.DefaultSubscription) { PublishingInterval = publishingIntervalSeconds }; List <MonitoredItem> monitoredItems = CreateReadValueIdCollection(dataItems); monitoredItems.ForEach(i => i.Notification += OnNotification); subscription.AddItems(monitoredItems); opcSession.AddSubscription(subscription); subscription.Create(); return(subscription); }
public void Connect() { try { //подключаемся к серверу _opcServer.Connect(new Opc.ConnectData(new NetworkCredential())); } catch (Exception ex) { throw new Exception("Ошибка подключения к серверу " + string.Format("opcda://{0}/{1}", _hostName, _opcServerVendor)); } //если подключен успешно if (_opcServer.IsConnected) { //создаем подписку _subscriptionState = new Opc.Da.SubscriptionState() { Active = true, UpdateRate = _updateRate, Deadband = 0, Name = "PLCMonitor_to_" + _plc.Topic }; _scadaSubscription = (Opc.Da.Subscription)_opcServer.CreateSubscription(_subscriptionState); //добавляем теги в подписку Opc.Da.ItemResult[] result = _scadaSubscription.AddItems(_scadaItems.ToArray()); for (int i = 0; i < result.Length; i++) { _scadaItems[i].ServerHandle = result[i].ServerHandle; } _scadaSubscription.State.Active = true; //запрашиваем данные пока не подана команда _stop _readThread = new Thread(new ThreadStart(ReadData)); _readThread.Start(); } else { throw new Exception("Ошибка подключения к серверу " + string.Format("opcda://{0}/{1}", _hostName, _opcServerVendor)); } }
/// <summary> /// Hier werden aus der XML-Konfiguration OpcUa Subscriptions erstellt. /// </summary> /// <param name="xmlSubscriptions"></param> /// <returns></returns> private async Task CreateSubscriptionsFromXmlAsync(List <XmlOpcUaSubscription> xmlSubscriptions) { m_Subscriptions = new List <Subscription>(); foreach (XmlOpcUaSubscription xmlSub in xmlSubscriptions) { try { int pubInt = Convert.ToInt32(xmlSub.XmlPublishingInterval); // Eine Liste aus Monitored Items wird erstellt, die Später vom Client aufgezeichnet werden. var monitoredItems = new List <MonitoredItem>(); // Dazu wird die übergeben Liste der Opc Variablen aus der XML Konfiguration übergeben. foreach (XmlOpcUaVariable opcvariable in xmlSub.XmlOpcUaVariablen) { // Für jedes C_OpcUaVariable Objekt wir eine Monitored Item erstellt. MonitoredItem monitoredItem = await CreateMonitoredItemFromXmlAsync(opcvariable); // Das erstellte monitored Item wird zu der Liste hinzugefügt. monitoredItems.Add(monitoredItem); } // Subscription wird erstellt. Subscription sub = CreateSubscription(pubInt); // MonitoredItems werden hinzugefügt. if (monitoredItems != null) { sub.AddItems(monitoredItems); } //Subscription wird zur internen Liste hinzugefügt. m_Subscriptions.Add(sub); } catch (Exception ex) { throw new Exception("Die Subscription mit dem Interval " + xmlSub.XmlPublishingInterval + " vom Server " + ServerLabel + " konnte nicht erstellt werden", ex); } } }
public void SubscribeToNodeChanges(IEnumerable <string> nodeIds, int updateDelay) { var subscription = new Subscription(Session.DefaultSubscription) { PublishingInterval = updateDelay }; var items = nodeIds.Select(x => new MonitoredItem { StartNodeId = x }).ToList(); foreach (var item in items) { item.Notification += OnChange; } subscription.AddItems(items); Session.AddSubscription(subscription); subscription.Create(); }
public async Task InvokeAsync(HttpContext context) { Session session = SessionConfig.GetOpcSessionAsync(_configuration.GetSection("EndpointUrl").Value).Result; Subscription subscription = new Subscription(session.DefaultSubscription); IEnumerable <MonitoredItem> items = _options.OpcPoints .Select(setting => { MonitoredItem item = new MonitoredItem { DisplayName = setting.ItemId, StartNodeId = "ns=2;s=" + setting.ItemId }; item.Notification += (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) => { if (e.NotificationValue is MonitoredItemNotification notification) { var value = notification.Value; OpcItem opcItem = new OpcItem { ItemId = monitoredItem.DisplayName.Substring(30), Value = value.Value, Quality = value.StatusCode.ToString(), TimeStamp = value.SourceTimestamp.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), HighAlarm = setting.HighAlarm, LowAlarm = setting.LowAlarm }; _hubContext.Clients.All.OpcDataUpdate(opcItem); } }; return(item); } ); subscription.AddItems(items); session.AddSubscription(subscription); subscription.Create(); await _next(context); }
/// <summary> /// Create subscription /// </summary> /// <param name="monitoredItems"></param> /// <param name="publishingInterval"></param> /// <param name="prioritize"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ServiceResultException"></exception> public Subscription CreateOpcUaSubscription(IEnumerable <MonitoredItem> monitoredItems, int publishingInterval, bool prioritize = false) { if (monitoredItems == null) { throw new ArgumentNullException(nameof(monitoredItems)); } if (publishingInterval == 0) { throw new ArgumentException(nameof(publishingInterval)); } this.VerifySessionCreated(); if (monitoredItems.Count() == 0) { return(null); } // create subscription var subscription = new Subscription(template: this.Session.DefaultSubscription) { PublishingInterval = publishingInterval, DisplayName = Guid.NewGuid().ToString(), Priority = prioritize ? Convert.ToByte(255) : Convert.ToByte(0) }; // add monitored items subscription.AddItems(monitoredItems: monitoredItems); // add subscription to session _ = this.Session.AddSubscription(subscription: subscription); subscription.Create(); return(subscription); }
static void Main(string[] args) { Console.WriteLine("Step 1 - Create a config."); var config = new ApplicationConfiguration() { ApplicationName = "MyHomework", ApplicationType = ApplicationType.Client, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = @"Windows", StorePath = @"CurrentUser\My", SubjectName = Utils.Format(@"CN={0}, DC={1}", "MyHomework", System.Net.Dns.GetHostName()) }, TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Windows", StorePath = @"CurrentUser\TrustedPeople", }, NonceLength = 32, AutoAcceptUntrustedCertificates = true }, TransportConfigurations = new TransportConfigurationCollection(), TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } }; config.Validate(ApplicationType.Client); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); }; } Console.WriteLine("Step 2 - Create a session with your server."); using (var session = Session.Create(config, new ConfiguredEndpoint(null, new EndpointDescription("opc.tcp://" + Dns.GetHostName() + ":62541")), true, "", 60000, null, null)) //EndpointDescription need to be changed according to your OPC server { Console.WriteLine("Step 3 - Browse the server namespace."); ReferenceDescriptionCollection refs; byte[] cp; session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs); //var node = session.ReadValue(new NodeId("ns=2;s=Moxa.AZOT_WAREHOUSE.N2Scaled"), typeof(float)); //to simply read a TAG Console.WriteLine("DisplayName: BrowseName, NodeClass"); foreach (var rd in refs) { Console.WriteLine("{0}: {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass); ReferenceDescriptionCollection nextRefs; byte[] nextCp; session.Browse(null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out nextCp, out nextRefs); foreach (var nextRd in nextRefs) { Console.WriteLine("+ {0}: {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass); } } Console.WriteLine("Step 4 - Create a subscription. Set a faster publishing interval if you wish."); var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("Step 5 - Add a list of items you wish to monitor to the subscription."); var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258" } }; list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(list); Console.WriteLine("Step 6 - Add the subscription to the session."); session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("Press any key to remove subscription..."); Console.ReadKey(true); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(true); }
private async Task <Session> ConsoleSampleClient() { Console.WriteLine("1 - Create an Application Configuration."); ExitCode = ExitCode.ErrorCreateApplication; ApplicationInstance application = new ApplicationInstance { ApplicationName = "UA Core Complex Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.ComplexClient" }; // load the application configuration. ApplicationConfiguration config = await application.LoadApplicationConfiguration(false).ConfigureAwait(false); // check the application certificate. bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0).ConfigureAwait(false); if (!haveAppCertificate) { throw new Exception("Application instance certificate invalid!"); } ReverseConnectManager reverseConnectManager = null; if (ReverseConnectUri != null) { // start the reverse connection manager reverseConnectManager = new ReverseConnectManager(); reverseConnectManager.AddEndpoint(ReverseConnectUri); reverseConnectManager.StartService(config); } if (haveAppCertificate) { config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { m_autoAccept = true; } config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } else { Console.WriteLine(" WARN: missing application certificate, using unsecure connection."); } Console.WriteLine("2 - Discover endpoints of {0}.", m_endpointURL); ExitCode = ExitCode.ErrorDiscoverEndpoints; EndpointDescription selectedEndpoint; if (reverseConnectManager == null) { selectedEndpoint = CoreClientUtils.SelectEndpoint(m_endpointURL, haveAppCertificate, 15000); } else { Console.WriteLine(" Waiting for reverse connection."); ITransportWaitingConnection connection = await reverseConnectManager.WaitForConnection( new Uri(m_endpointURL), null, new CancellationTokenSource(60000).Token); if (connection == null) { throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out."); } selectedEndpoint = CoreClientUtils.SelectEndpoint(config, connection, haveAppCertificate, 15000); } Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); ExitCode = ExitCode.ErrorCreateSession; // create the user identity UserIdentity userIdentity; if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password)) { userIdentity = new UserIdentity(new AnonymousIdentityToken()); } else { userIdentity = new UserIdentity(Username, Password); } // create worker session if (reverseConnectManager == null) { m_session = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); } else { Console.WriteLine(" Waiting for reverse connection."); ITransportWaitingConnection connection = await reverseConnectManager.WaitForConnection( new Uri(m_endpointURL), null, new CancellationTokenSource(60000).Token); if (connection == null) { throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out."); } m_session = await CreateSession(config, connection, selectedEndpoint, userIdentity).ConfigureAwait(false); } // register keep alive handler m_session.KeepAlive += Client_KeepAlive; Console.WriteLine("4 - Browse for all custom type variables."); ExitCode = ExitCode.ErrorReadComplexTypes; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var allVariableNodes = BrowseAdddressSpace ? BrowseAllVariables() : new List <INode>(); var allCustomTypeVariables = allVariableNodes.Where(n => ((VariableNode)n).DataType.NamespaceIndex != 0).ToList(); stopWatch.Stop(); Console.WriteLine($" -- Browse all nodes took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($" -- Browsed {allVariableNodes.Count} nodes, from which {allCustomTypeVariables.Count} are custom type variables."); stopWatch.Reset(); // for testing clear the nodecache m_session.NodeCache.Clear(); stopWatch.Start(); if (LoadTypeSystem) { Console.WriteLine("5 - Load the server type dictionary."); ExitCode = ExitCode.ErrorLoadTypeDictionary; stopWatch.Reset(); stopWatch.Start(); var complexTypeSystem = new ComplexTypeSystem(m_session); await complexTypeSystem.Load().ConfigureAwait(false); stopWatch.Stop(); Console.WriteLine($"Load type system took {stopWatch.ElapsedMilliseconds}ms."); Console.WriteLine($"Custom types defined for this session:"); foreach (var type in complexTypeSystem.GetDefinedTypes()) { Console.WriteLine($"{type.Namespace}.{type.Name}"); } Console.WriteLine($"Loaded {m_session.DataTypeSystem.Count} dictionaries:"); foreach (var dictionary in m_session.DataTypeSystem) { Console.WriteLine($" + {dictionary.Value.Name}"); foreach (var type in dictionary.Value.DataTypes) { Console.WriteLine($" -- {type.Key}:{type.Value}"); } } } else { Console.WriteLine("4 - Not loading the server type dictionary."); } foreach (VariableNode variableNode in allCustomTypeVariables) { try { var value = m_session.ReadValue(variableNode.NodeId); CastInt32ToEnum(variableNode, value); Console.WriteLine($" -- {variableNode}:{value}"); if (value.Value is ExtensionObject extensionObject) { if (extensionObject.Body is BaseComplexType complexType) { foreach (var item in complexType.GetPropertyEnumerator()) { if (Verbose) { Console.WriteLine($" -- -- {item.Name}:{complexType[item.Name]}"); } if (WriteComplexInt && item.PropertyType == typeof(Int32)) { var data = complexType[item.Name]; if (data != null) { complexType[item.Name] = (Int32)data + 1; } Console.WriteLine($" -- -- Increment: {item.Name}, {complexType[item.Name]}"); WriteValue(m_session, variableNode.NodeId, value); } } } } if (PrintAsJson) { PrintValueAsJson(variableNode.BrowseName.Name, value); } } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($" -- {variableNode}: Access denied!"); } } } Console.WriteLine("6 - Create test sessions which load only single types as needed."); if (LoadTypeSystem) { foreach (VariableNode variableNode in allCustomTypeVariables) { Session testSession = null; try { Console.WriteLine($"Open session for {variableNode}:"); testSession = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); var complexTypeSystem = new ComplexTypeSystem(testSession); NodeId dataType = variableNode.DataType; Type nullType = testSession.Factory.GetSystemType(dataType); var valueBefore = testSession.ReadValue(variableNode.NodeId); Console.WriteLine($" -- {valueBefore}"); Type systemType = await complexTypeSystem.LoadType(dataType).ConfigureAwait(false); var valueAfter = testSession.ReadValue(variableNode.NodeId); Console.WriteLine($" -- {variableNode}: {systemType} {dataType}"); Console.WriteLine($" -- {valueAfter}"); Console.WriteLine($"Custom types defined for {variableNode}:"); foreach (var type in complexTypeSystem.GetDefinedTypes()) { Console.WriteLine($" -- {type.Namespace}.{type.Name}"); } } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($" -- {variableNode}: Access denied!"); } } finally { testSession?.Close(); } } } else { Console.WriteLine("6 - Not testing to load individual types."); } Console.WriteLine("7 - Create a subscription with publishing interval of 1 second."); ExitCode = ExitCode.ErrorCreateSubscription; var subscription = new Subscription(m_session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("8 - Add all custom values and the server time to the subscription."); ExitCode = ExitCode.ErrorMonitoredItem; var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime.ToString() } }; list.ForEach(i => i.Notification += OnNotification); foreach (var customVariable in allCustomTypeVariables) { var newItem = new MonitoredItem(subscription.DefaultItem) { DisplayName = customVariable.DisplayName.Text, StartNodeId = ExpandedNodeId.ToNodeId(customVariable.NodeId, m_session.NamespaceUris) }; newItem.Notification += OnComplexTypeNotification; list.Add(newItem); } subscription.AddItems(list); Console.WriteLine("9 - Add the subscription to the session."); ExitCode = ExitCode.ErrorAddSubscription; m_session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("10 - Running...Press Ctrl-C to exit..."); ExitCode = ExitCode.ErrorRunning; return(m_session); }
private void ConnectToOpcServer()//метод выполняется один раз. Вызывается через конструктор { // 1st: Create a server object and connect to the RSLinx OPC Server try { server = new Opc.Da.Server(fact, null); server.Url = new Opc.URL("opcda://localhost/Kepware.KEPServerEX.V6"); //2nd: Connect to the created server server.Connect(); //Read group subscription groupState = new Opc.Da.SubscriptionState(); groupState.Name = "myReadGroup"; groupState.UpdateRate = 200; groupState.Active = true; //Read group creation groupRead = (Opc.Da.Subscription)server.CreateSubscription(groupState); groupRead.DataChanged += new Opc.Da.DataChangedEventHandler(groupRead_DataChanged); Item item = new Item(); item.ItemName = "Simulation Examples.Functions.Sine1"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Sine2"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Sine3"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Random1"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Random2"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Random3"; itemsList.Add(item); item = new Item(); item.ItemName = "Simulation Examples.Functions.Random4"; itemsList.Add(item); groupRead.AddItems(itemsList.ToArray()); // groupStateWrite = new Opc.Da.SubscriptionState(); // groupStateWrite.Name = "myWriteGroup"; // groupStateWrite.Active = false; // groupWrite = (Opc.Da.Subscription)server.CreateSubscription(groupStateWrite); } catch (Exception exc) { MessageBox.Show(exc.Message); } }
private async Task ConsoleClient() { Log(conn_name + " - " + "Create an Application Configuration..."); exitCode = ExitCode.ErrorCreateApplication; ApplicationInstance application = new ApplicationInstance { ApplicationName = "JSON-SCADA OPC-UA Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "", }; bool haveAppCertificate = false; ApplicationConfiguration config = null; try { // load the application configuration. Log(conn_name + " - " + "Load config from " + OPCUA_conn.configFileName); config = await application.LoadApplicationConfiguration(OPCUA_conn.configFileName, false); // config.SecurityConfiguration.AutoAcceptUntrustedCertificates = true; // check the application certificate. haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0); if (!haveAppCertificate) { Log(conn_name + " - " + "FATAL: Application instance certificate invalid!", LogLevelNoLog); Environment.Exit(1); } if (haveAppCertificate) { config.ApplicationUri = X509Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { autoAccept = true; } config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } else { Log(conn_name + " - " + "WARN: missing application certificate, using unsecure connection."); } } catch (Exception e) { Log(conn_name + " - WARN: " + e.Message); } if (config == null) { Log(conn_name + " - " + "FATAL: error in XML config file!", LogLevelNoLog); Environment.Exit(1); } try { Log(conn_name + " - " + "Discover endpoints of " + OPCUA_conn.endpointURLs[0]); exitCode = ExitCode.ErrorDiscoverEndpoints; var selectedEndpoint = CoreClientUtils.SelectEndpoint(OPCUA_conn.endpointURLs[0], haveAppCertificate && OPCUA_conn.useSecurity, 15000); Log(conn_name + " - " + "Selected endpoint uses: " + selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Log(conn_name + " - " + "Create a session with OPC UA server."); exitCode = ExitCode.ErrorCreateSession; var endpointConfiguration = EndpointConfiguration.Create(config); var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration); await Task.Delay(50); session = await Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null); // Log("" + session.KeepAliveInterval); // default is 5000 session.KeepAliveInterval = System.Convert.ToInt32(OPCUA_conn.timeoutMs); // register keep alive handler session.KeepAlive += Client_KeepAlive; } catch (Exception e) { Log(conn_name + " - WARN: " + e.Message); } if (session == null) { Log(conn_name + " - " + "FATAL: error creating session!", LogLevelNoLog); Environment.Exit(1); } Log(conn_name + " - " + "Browsing the OPC UA server namespace."); exitCode = ExitCode.ErrorBrowseNamespace; await FindObjects(session, ObjectIds.ObjectsFolder); await Task.Delay(50); Log(conn_name + " - " + "Add a list of items (server current time and status) to the subscription."); exitCode = ExitCode.ErrorMonitoredItem; ListMon.ForEach(i => i.Notification += OnNotification); //ListMon.ForEach(i => i.SamplingInterval = System.Convert.ToInt32(System.Convert.ToDouble(OPCUA_conn.autoCreateTagSamplingInterval) * 1000); // ListMon.ForEach(i => Log(conn_name + " - " + i.DisplayName)); Log(conn_name + " - " + ListMon.Count + " Objects found"); Log(conn_name + " - " + "Create a subscription with publishing interval of " + System.Convert.ToDouble(OPCUA_conn.autoCreateTagPublishingInterval) + "seconds"); exitCode = ExitCode.ErrorCreateSubscription; var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = System.Convert.ToInt32(System.Convert.ToDouble(OPCUA_conn.autoCreateTagPublishingInterval) * 1000), PublishingEnabled = true }; await Task.Delay(50); subscription.AddItems(ListMon); await Task.Delay(50); Log(conn_name + " - " + "Add the subscription to the session."); Log(conn_name + " - " + subscription.MonitoredItemCount + " Monitored items"); exitCode = ExitCode.ErrorAddSubscription; session.AddSubscription(subscription); subscription.Create(); subscription.ApplyChanges(); Log(conn_name + " - " + "Running..."); exitCode = ExitCode.ErrorRunning; }
public async Task InitializeClient(string endpointURL, IEnumerable <string> tagInfos) { m_NumberOfCommunicationErrors = 0; m_PreviousState = ServerState.Unknown; m_FailedKeepAliveEvents = 0; m_EndpointURL = endpointURL; m_TagInfos = tagInfos; var config = await CreateApplicationConfiguration(); m_connecting = true; int numberOfTries = 0; while (m_connecting) { try { numberOfTries++; bool haveAppCertificate = ValidateCertificate(config); m_Session = await CreateSession(config, endpointURL, haveAppCertificate); m_connecting = !m_Session.Connected; if (m_Session.Connected) { m_Session.KeepAlive += OnSessionKeepAlive; } } catch (Exception ex) { m_Log.Error($"Failed to connect to OPC Server {endpointURL}", ex); await Task.Delay(1000); } } Console.WriteLine("4 - Create a subscription with publishing interval of 1 second."); m_Subscription = new Subscription(m_Session.DefaultSubscription) { PublishingInterval = 1000 }; foreach (var tagInfo in m_TagInfos) { if (string.IsNullOrEmpty(tagInfo)) { continue; } var monitoredItem = new MonitoredItem(m_Subscription.DefaultItem) { DisplayName = tagInfo, StartNodeId = new NodeId(tagInfo, 6), Handle = tagInfo }; m_MonitoredItems.Add(monitoredItem); } m_MonitoredItems.ForEach(i => i.Notification += OnNotification); m_Subscription.AddItems(m_MonitoredItems); Console.WriteLine("6 - Add the subscription to the session."); m_Session.AddSubscription(m_Subscription); m_Subscription.Create(); }
public static async Task ConsoleSampleClient(string endpointURL) { Console.WriteLine("1 - Create an Application Configuration."); var config = new ApplicationConfiguration() { ApplicationName = "UA Core Sample Client", ApplicationType = ApplicationType.Client, ApplicationUri = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient", SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = "X509Store", StorePath = "CurrentUser\\UA_MachineDefault", SubjectName = "UA Core Sample Client" }, TrustedPeerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/UA Applications", }, TrustedIssuerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities", }, RejectedCertificateStore = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/RejectedCertificates", }, NonceLength = 32, AutoAcceptUntrustedCertificates = true }, TransportConfigurations = new TransportConfigurationCollection(), TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } }; await config.Validate(ApplicationType.Client); bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null; if (!haveAppCertificate) { Console.WriteLine(" INFO: Creating new application certificate: {0}", config.ApplicationName); X509Certificate2 certificate = CertificateFactory.CreateCertificate( config.SecurityConfiguration.ApplicationCertificate.StoreType, config.SecurityConfiguration.ApplicationCertificate.StorePath, config.ApplicationUri, config.ApplicationName, config.SecurityConfiguration.ApplicationCertificate.SubjectName ); config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate; } haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null; if (haveAppCertificate) { config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } } else { Console.WriteLine(" WARN: missing application certificate, using unsecure connection."); } Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL); Uri endpointURI = new Uri(endpointURL); var endpointCollection = DiscoverEndpoints(config, endpointURI, 10); var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate); Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); var endpointConfiguration = EndpointConfiguration.Create(config); var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration); endpoint.Update(selectedEndpoint); var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null); Console.WriteLine("4 - Browse the OPC UA server namespace."); ReferenceDescriptionCollection references; Byte[] continuationPoint; references = session.FetchReferences(ObjectIds.ObjectsFolder); session.Browse( null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out continuationPoint, out references); Console.WriteLine(" DisplayName, BrowseName, NodeClass"); foreach (var rd in references) { Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass); ReferenceDescriptionCollection nextRefs; byte[] nextCp; session.Browse( null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out nextCp, out nextRefs); foreach (var nextRd in nextRefs) { Console.WriteLine(" + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass); } } Console.WriteLine("5 - Create a subscription with publishing interval of 1 second."); var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription."); var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258" } }; list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(list); Console.WriteLine("7 - Add the subscription to the session."); session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("8 - Running...Press any key to exit..."); Console.ReadKey(true); }
public async Task AddSubscriptionAsync() { var subscription = new Subscription(); // check keepAlive int keepAlive = 0; m_session.KeepAlive += (Session sender, KeepAliveEventArgs e) => { keepAlive++; }; // add current time var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = VariableIds.Server_ServerStatus_CurrentTime } }; list.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => { foreach (var value in item.DequeueValues()) { TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); } }); subscription = new Subscription(m_session.DefaultSubscription); TestContext.Out.WriteLine("MaxMessageCount: {0}", subscription.MaxMessageCount); TestContext.Out.WriteLine("MaxNotificationsPerPublish: {0}", subscription.MaxNotificationsPerPublish); TestContext.Out.WriteLine("MinLifetimeInterval: {0}", subscription.MinLifetimeInterval); subscription.AddItem(list.First()); Assert.AreEqual(1, subscription.MonitoredItemCount); Assert.True(subscription.ChangesPending); bool result = await m_session.RemoveSubscriptionAsync(subscription); Assert.False(result); result = await m_session.RemoveSubscriptionsAsync(new List <Subscription>() { subscription }); Assert.False(result); result = m_session.AddSubscription(subscription); Assert.True(result); result = m_session.AddSubscription(subscription); Assert.False(result); result = await m_session.RemoveSubscriptionsAsync(new List <Subscription>() { subscription }); Assert.True(result); result = await m_session.RemoveSubscriptionAsync(subscription); Assert.False(result); result = m_session.AddSubscription(subscription); Assert.True(result); await subscription.CreateAsync().ConfigureAwait(false); // add state var list2 = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusState", StartNodeId = VariableIds.Server_ServerStatus_State } }; list2.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => { foreach (var value in item.DequeueValues()) { TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); } }); subscription.AddItems(list); await subscription.ApplyChangesAsync().ConfigureAwait(false); await subscription.SetPublishingModeAsync(false).ConfigureAwait(false); Assert.False(subscription.PublishingEnabled); await subscription.SetPublishingModeAsync(true).ConfigureAwait(false); Assert.True(subscription.PublishingEnabled); Assert.False(subscription.PublishingStopped); subscription.Priority = 200; await subscription.ModifyAsync().ConfigureAwait(false); // save m_session.Save(SubscriptionTestXml); await Task.Delay(5000).ConfigureAwait(false); TestContext.Out.WriteLine("CurrentKeepAliveCount : {0}", subscription.CurrentKeepAliveCount); TestContext.Out.WriteLine("CurrentPublishingEnabled: {0}", subscription.CurrentPublishingEnabled); TestContext.Out.WriteLine("CurrentPriority : {0}", subscription.CurrentPriority); TestContext.Out.WriteLine("PublishTime : {0}", subscription.PublishTime); TestContext.Out.WriteLine("LastNotificationTime : {0}", subscription.LastNotificationTime); TestContext.Out.WriteLine("SequenceNumber : {0}", subscription.SequenceNumber); TestContext.Out.WriteLine("NotificationCount : {0}", subscription.NotificationCount); TestContext.Out.WriteLine("LastNotification : {0}", subscription.LastNotification); TestContext.Out.WriteLine("Notifications : {0}", subscription.Notifications.Count()); TestContext.Out.WriteLine("OutstandingMessageWorker: {0}", subscription.OutstandingMessageWorkers); await subscription.ConditionRefreshAsync().ConfigureAwait(false); var sre = Assert.Throws <ServiceResultException>(() => subscription.Republish(subscription.SequenceNumber)); Assert.AreEqual(StatusCodes.BadMessageNotAvailable, sre.StatusCode); subscription.RemoveItems(list); await subscription.ApplyChangesAsync().ConfigureAwait(false); subscription.RemoveItem(list2.First()); result = await m_session.RemoveSubscriptionAsync(subscription).ConfigureAwait(false); Assert.True(result); }
//This test doesn't deterministically prove sequential publishing, but rather relies on a subscription not being able to handle the message load. //This test should be re-implemented with a Session that deterministically provides the wrong order of messages to Subscription. public void SequentialPublishingSubscription(bool enabled) { var subscriptionList = new List <Subscription>(); var sequenceBroken = new AutoResetEvent(false); var numOfNotifications = 0L; const int TestWaitTime = 10000; const int MonitoredItemsPerSubscription = 500; const int Subscriptions = 10; for (int i = 0; i < Subscriptions; i++) { var subscription = new Subscription(m_session.DefaultSubscription) { SequentialPublishing = enabled, PublishingInterval = 0, DisableMonitoredItemCache = true, //Not needed PublishingEnabled = false }; subscriptionList.Add(subscription); //Create many monitored items on the server status current time, and track the last reported source timestamp var list = Enumerable.Range(1, MonitoredItemsPerSubscription).Select(_ => new MonitoredItem(subscription.DefaultItem) { StartNodeId = new NodeId("Scalar_Simulation_Int32", 2), SamplingInterval = 0, }).ToList(); var dict = list.ToDictionary(item => item.ClientHandle, _ => DateTime.MinValue); subscription.AddItems(list); var result = m_session.AddSubscription(subscription); Assert.True(result); subscription.Create(); var publishInterval = (int)subscription.CurrentPublishingInterval; TestContext.Out.WriteLine($"CurrentPublishingInterval: {publishInterval}"); //Need to realize test failed, assert needs to be brought to this thread subscription.FastDataChangeCallback = (_, notification, __) => { notification.MonitoredItems.ForEach(item => { Interlocked.Increment(ref numOfNotifications); if (dict[item.ClientHandle] > item.Value.SourceTimestamp) { sequenceBroken.Set(); //Out of order encountered } dict[item.ClientHandle] = item.Value.SourceTimestamp; }); }; } UInt32Collection subscriptionIds = new UInt32Collection(); foreach (var subscription in subscriptionList) { subscriptionIds.Add(subscription.Id); } var stopwatch = Stopwatch.StartNew(); // start m_session.SetPublishingMode(null, true, subscriptionIds, out var results, out var diagnosticInfos); // Wait for out-of-order to occur var failed = sequenceBroken.WaitOne(TestWaitTime); // stop m_session.SetPublishingMode(null, false, subscriptionIds, out results, out diagnosticInfos); //Log information var elapsed = stopwatch.Elapsed.TotalMilliseconds / 1000.0; TestContext.Out.WriteLine($"Ran for: {elapsed:N} seconds"); long totalNotifications = Interlocked.Read(ref numOfNotifications); double notificationRate = totalNotifications / elapsed; foreach (var subscription in subscriptionList) { int outstandingMessageWorkers = subscription.OutstandingMessageWorkers; TestContext.Out.WriteLine($"Id: {subscription.Id} Outstanding workers: {outstandingMessageWorkers}"); } TestContext.Out.WriteLine($"Number of notifications: {totalNotifications:N0}"); TestContext.Out.WriteLine($"Notifications rate: {notificationRate:N} per second"); //How fast it processed notifications. Assert.NotZero(totalNotifications); //No notifications means nothing worked if (enabled) { //catch if Out-of-sequence occurred Assert.False(failed); } var notificationsPerSecond = Subscriptions * MonitoredItemsPerSubscription; Assert.AreEqual(notificationsPerSecond * (elapsed + 0.5), totalNotifications, notificationsPerSecond); foreach (var subscription in subscriptionList) { var result = m_session.RemoveSubscription(subscription); Assert.True(result); } }
public static async Task ConsoleSampleClient(string endpointURL) { Console.WriteLine("1 - Create an Application Configuration."); var config = new ApplicationConfiguration() { ApplicationName = "UA Core Sample Client", ApplicationType = ApplicationType.Client, ApplicationUri = "urn:"+Utils.GetHostName()+":OPCFoundation:CoreSampleClient", SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/MachineDefault", SubjectName = "UA Core Sample Client" }, TrustedPeerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/UA Applications", }, TrustedIssuerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities", }, RejectedCertificateStore = new CertificateTrustList { StoreType = "Directory", StorePath = "OPC Foundation/CertificateStores/RejectedCertificates", }, NonceLength = 32, AutoAcceptUntrustedCertificates = true }, TransportConfigurations = new TransportConfigurationCollection(), TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } }; await config.Validate(ApplicationType.Client); bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null; if (!haveAppCertificate) { Console.WriteLine(" INFO: Creating new application certificate: {0}", config.ApplicationName); X509Certificate2 certificate = CertificateFactory.CreateCertificate( config.SecurityConfiguration.ApplicationCertificate.StoreType, config.SecurityConfiguration.ApplicationCertificate.StorePath, config.ApplicationUri, config.ApplicationName ); config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate; } haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null; if (haveAppCertificate) { config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } } else { Console.WriteLine(" WARN: missing application certificate, using unsecure connection."); } Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL); Uri endpointURI = new Uri(endpointURL); var endpointCollection = DiscoverEndpoints(config, endpointURI, 10); var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate); Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); var endpointConfiguration = EndpointConfiguration.Create(config); var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration); endpoint.Update(selectedEndpoint); var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null, null); Console.WriteLine("4 - Browse the OPC UA server namespace."); ReferenceDescriptionCollection references; Byte[] continuationPoint; references = session.FetchReferences(ObjectIds.ObjectsFolder); session.Browse( null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out continuationPoint, out references); Console.WriteLine(" DisplayName, BrowseName, NodeClass"); foreach (var rd in references) { Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass); ReferenceDescriptionCollection nextRefs; byte[] nextCp; session.Browse( null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out nextCp, out nextRefs); foreach (var nextRd in nextRefs) { Console.WriteLine(" + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass); } } Console.WriteLine("5 - Create a subscription with publishing interval of 1 second."); var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription."); var list = new List<MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258" } }; list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(list); Console.WriteLine("7 - Add the subscription to the session."); session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("8 - Running...Press any key to exit..."); Console.ReadKey(true); }