Example #1
1
        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); }
        }
Example #2
0
        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());
        }
Example #3
0
        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));
        }
Example #4
0
        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();
            }
        }
Example #5
0
        /// <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);
        }
Example #6
0
        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);
                }
            }
        }
Example #7
0
        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); }
            }
        }
Example #8
0
        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);
            }
        }
Example #9
0
 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}";
            }
        }
Example #11
0
        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;
            }
        }
Example #13
0
        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();
        }
Example #14
0
        /// <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);
        }
Example #15
0
        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);
            }
        }
Example #16
0
        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.");
            }
        }
Example #17
0
        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);
        }
Example #19
0
        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));
            }
        }
Example #20
0
        /// <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);
                }
            }
        }
Example #21
0
        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();
        }
Example #22
0
        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);
        }
Example #24
0
        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);
        }
Example #25
0
        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);
        }
Example #26
0
        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);
            }
        }
Example #27
0
            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;
            }
Example #28
0
        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();
        }
Example #29
0
        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);
        }