/// <summary>
        /// Raised when a publish response arrives from the server.
        /// </summary>
        /// <param name="session">The target of the event.</param>
        /// <param name="e">The <see cref="Opc.Ua.Client.NotifacationEventArgs"/>Instance containing the event data.</param>
        private void Session_Notification(Session session, NotificationEventArgs e)
        {
            NotificationMessage message = e.NotificationMessage;

            // Check for keep alive.
            if (message.NotificationData.Count == 0)
            {
                return;
            }

            // Get the data changes (oldest to newest).
            foreach (MonitoredItemNotification datachange in message.GetDataChanges(false))
            {
                // Lookup the monitored item.
                MonitoredItem monitoredItem = e.Subscription.FindItemByClientHandle(datachange.ClientHandle);

                if (monitoredItem == null)
                {
                    continue;
                }

                ClientMonitoredItemData clientData = monitoredItem.Handle as ClientMonitoredItemData;

                clientData.callback(clientData.clientHandle, datachange.Value);
            }
        }
예제 #2
0
        /// <summary>
        /// Raised when a publish response arrives from the server.
        /// </summary>
        /// <param name="session">The target of the event.</param>
        /// <param name="e">The <see cref="Opc.Ua.Client.NotifacationEventArgs"/>Instance containing the event data.</param>
        private void DataChangedNotification(Session session, NotificationEventArgs e)
        {
            NotificationMessage message = e.NotificationMessage;

            // Check for keep alive.
            if (message.NotificationData.Count == 0)
            {
                return;
            }
            List <object>    clientHandleList = new List <object>();
            List <DataValue> ValueList        = new List <DataValue>();

            // Get the data changes (oldest to newest).
            foreach (MonitoredItemNotification datachange in message.GetDataChanges(false))
            {
                // Lookup the monitored item.
                MonitoredItem monitoredItem = e.Subscription.FindItemByClientHandle(datachange.ClientHandle);

                if (monitoredItem == null)
                {
                    continue;
                }

                ClientMonitoredItemData clientData = monitoredItem.Handle as ClientMonitoredItemData;
                clientHandleList.Add(clientData.clientHandle);
                ValueList.Add(datachange.Value);
            }
            DataChangedEvent(clientHandleList, ValueList);
        }
예제 #3
0
        /// <summary>
        /// Processes new data.
        /// </summary>
        private void ProcessDataChanges(SubscriptionTag subscriptionTag, NotificationMessage notificationMessage)
        {
            foreach (MonitoredItemNotification change in notificationMessage.GetDataChanges(false))
            {
                if (subscriptionTag.Subscription.FindItemByClientHandle(change.ClientHandle) is
                    MonitoredItem monitoredItem)
                {
                    if (subscriptionTag.ItemsByNodeID.TryGetValue(monitoredItem.StartNodeId.ToString(),
                                                                  out ItemTag itemTag))
                    {
                        Log.WriteLine("{0} {1} = {2} ({3})", CommPhrases.ReceiveNotation,
                                      monitoredItem.DisplayName, change.Value, change.Value.StatusCode);

                        int tagIndex  = itemTag.DeviceTag.Index;
                        int tagStatus = StatusCode.IsGood(change.Value.StatusCode) ?
                                        CnlStatusID.Defined : CnlStatusID.Undefined;

                        if (itemTag.ItemConfig.IsArray && change.Value.Value is Array arrVal)
                        {
                            int       arrLen    = Math.Min(itemTag.ItemConfig.DataLength, arrVal.Length);
                            double[]  arr       = new double[arrLen];
                            TagFormat tagFormat = TagFormat.FloatNumber;

                            for (int i = 0; i < arrLen; i++)
                            {
                                arr[i] = ConvertArrayElem(arrVal.GetValue(i), out TagFormat format);
                                if (i == 0)
                                {
                                    tagFormat = format;
                                }
                            }

                            DeviceData.SetDoubleArray(tagIndex, arr, tagStatus);
                            DeviceTags[tagIndex].Format = tagFormat;
                        }
                        else
                        {
                            SetTagData(tagIndex, change.Value.Value, tagStatus);
                        }
                    }
                    else
                    {
                        Log.WriteLine(Locale.IsRussian ?
                                      "Ошибка: тег \"{0}\" не найден" :
                                      "Error: tag \"{0}\" not found", monitoredItem.StartNodeId);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Processes new data.
        /// </summary>
        private void ProcessDataChanges(SubscriptionTag subscriptionTag, NotificationMessage notificationMessage)
        {
            foreach (MonitoredItemNotification change in notificationMessage.GetDataChanges(false))
            {
                MonitoredItem monitoredItem = subscriptionTag.Subscription.FindItemByClientHandle(change.ClientHandle);

                if (monitoredItem != null)
                {
                    if (subscriptionTag.ItemsByNodeID.TryGetValue(monitoredItem.StartNodeId.ToString(),
                                                                  out ItemTag itemTag))
                    {
                        WriteToLog((Localization.UseRussian ? "Приём " : "Receive ") +
                                   monitoredItem.DisplayName + " = " + change.Value + " (" + change.Value.StatusCode + ")");

                        int tagIndex  = itemTag.KPTag.Index;
                        int tagStatus = StatusCode.IsGood(change.Value.StatusCode) ?
                                        BaseValues.CnlStatuses.Defined :
                                        BaseValues.CnlStatuses.Undefined;

                        if (itemTag.ItemConfig.IsArray)
                        {
                            int      arrayLen = itemTag.ItemConfig.ArrayLen;
                            double[] vals     = DecodeArray(change.Value.Value, arrayLen, out TagType tagType);

                            for (int i = 0; i < arrayLen; i++)
                            {
                                SetCurData(tagIndex, vals[i], tagStatus);
                                KPTags[tagIndex].Aux = tagType;
                                tagIndex++;
                            }
                        }
                        else
                        {
                            SetCurData(tagIndex, DecodeItemVal(change.Value.Value, out TagType tagType), tagStatus);
                            itemTag.KPTag.Aux = tagType;
                        }
                    }
                    else
                    {
                        WriteToLog(string.Format(Localization.UseRussian ?
                                                 "Ошибка: тег \"{0}\" не найден" :
                                                 "Error: tag \"{0}\" not found", monitoredItem.StartNodeId));
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Raised when a publish response arrives from the server.
        /// </summary>
        static void Session_Notification(Session session, NotificationEventArgs e)
        {
            NotificationMessage message = e.NotificationMessage;

            // check for keep alive.
            if (message.NotificationData.Count == 0)
            {
                Console.WriteLine(
                    "===>>> Subscription KeepAlive: SubscriptionId={0} MessageId={1} Time={2:HH:mm:ss.fff}",
                    e.Subscription.Id,
                    message.SequenceNumber,
                    message.PublishTime.ToLocalTime());

                return;
            }

            DataChangeNotification dcn = (DataChangeNotification)ExtensionObject.ToEncodeable(message.NotificationData[0]);
            // Console.WriteLine("{0:mm:ss.fff} - SeqNo={1}, Items={2}", message.PublishTime, message.SequenceNumber, dcn.MonitoredItems.Count);

            int count = 0;

            // get the data changes (oldest to newest).
            foreach (MonitoredItemNotification datachange in message.GetDataChanges(false))
            {
                // lookup the monitored item.
                MonitoredItem monitoredItem = e.Subscription.FindItemByClientHandle(datachange.ClientHandle);

                if (monitoredItem == null)
                {
                    Console.WriteLine("MonitoredItem ClientHandle not known: {0}", datachange.ClientHandle);
                    continue;
                }

                // this is called on another thread so we need to synchronize before accessing the node.
                lock (m_lock)
                {
                    NodeOfInterest node = monitoredItem.Handle as NodeOfInterest;

                    //Console.WriteLine(
                    //    "Update for {0}: {1} Status={2} Timestamp={3:HH:mm:ss.fff}",
                    //    node.DisplayName,
                    //    datachange.Value.WrappedValue,
                    //    datachange.Value.StatusCode,
                    //    datachange.Value.SourceTimestamp.ToLocalTime());

                    node.Value = datachange.Value;
                    Save(datachange.ClientHandle, node.Value);
                    count++;
                }
            }

            if (count > NotificationsPerPublish)
            {
                Console.WriteLine("Too many notifications in Publish: {0}/{1}", count, NotificationsPerPublish);
            }

            lock (m_publishes)
            {
                m_notifications++;

                if (m_lastDump.AddSeconds(1) > DateTime.UtcNow)
                {
                    return;
                }

                int sampleCount = 0;
                int itemCount   = 0;

                DateTime timestamp = DateTime.MinValue;

                while (m_publishes.Count > 0)
                {
                    DataValue value1 = m_publishes.Dequeue();

                    if (timestamp < value1.SourceTimestamp)
                    {
                        if (timestamp != DateTime.MinValue)
                        {
                            //Console.WriteLine(
                            //    "Items = {1}, Timestamp = {0:mm:ss.fff}",
                            //    timestamp,
                            //    itemCount);
                        }

                        timestamp = value1.SourceTimestamp;
                        itemCount = 0;
                    }

                    sampleCount++;
                    itemCount++;
                }

                //Console.WriteLine(
                //    "Items = {1}, Timestamp = {0:mm:ss.fff}",
                //    timestamp,
                //    itemCount);

                uint expectedSamples       = 10000; // (uint)((1000.0/SamplingInterval)*ItemsToMonitor);
                uint expectedNotifications = 50;

                Console.WriteLine(
                    "{0:mm:ss.fff}-{1:mm:ss.fff}, Messages = {2}/{3}, Samples = {4}/{5}, MissedSamples = {6}",
                    m_lastDump,
                    m_lastDump.AddSeconds(1),
                    m_notifications,
                    expectedNotifications,
                    sampleCount,
                    expectedSamples,
                    (int)m_expectedSamples - (int)m_actualSamples);

                m_lastDump    = m_lastDump.AddSeconds(1);
                m_lastMessage = message.SequenceNumber;
                m_dumpCount++;
                m_notifications = 0;

                m_actualSamples   += (uint)sampleCount;
                m_expectedSamples += expectedSamples;

                if (m_dumpCount == 10)
                {
                    m_actualSamples   = 0;
                    m_expectedSamples = 0;
                }
            }
        }