/// <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); } }
/// <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); }
/// <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); } } } }
/// <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)); } } } }
/// <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; } } }