Пример #1
0
        /// <summary>
        /// Processes a Publish repsonse from the server.
        /// </summary>
        void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(m_MonitoredItemNotification, monitoredItem, e);
                return;
            }
            else if (!IsHandleCreated)
            {
                return;
            }

            try
            {
                // ignore notifications for other monitored items.
                if (!Object.ReferenceEquals(m_monitoredItem, monitoredItem))
                {
                    return;
                }

                // notify controls of the change.
                EventsCTRL.NotificationReceived(e);
                DataChangesCTRL.NotificationReceived(e);
                if (e != null)
                {
                    MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                    LatestValueCTRL.ShowValue(notification, true);
                }
                // update item status.
                UpdateStatus();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Пример #2
0
        private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            if (InvokeRequired)
            {
                Invoke(new Action <string, MonitoredItem, MonitoredItemNotificationEventArgs>(SubCallback), key,
                       monitoredItem, args);
                return;
            }

            if (key == "A")
            {
                // 如果有多个的订阅值都关联了当前的方法,可以通过key和monitoredItem来区分
                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
                if (notification != null)
                {
                    textBox3.Text = notification.Value.WrappedValue.Value.ToString();
                }
            }
            else if (key == "B")
            {
                // 需要区分出来每个不同的节点信息
                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
                if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[0])
                {
                    textBox5.Text = notification.Value.WrappedValue.Value.ToString();
                }
                else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[1])
                {
                    textBox9.Text = notification.Value.WrappedValue.Value.ToString();
                }
                else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[2])
                {
                    textBox10.Text = notification.Value.WrappedValue.Value.ToString();
                }
            }
        }
Пример #3
0
 private void MonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
 {
     try
     {
         if (!(e.NotificationValue is MonitoredItemNotification monitoredItemNotification))
         {
             return;
         }
         for (int index = 0; index < monitoredVariablePanel.Controls.Count; index++)
         {
             if (monitoredVariablePanel.Controls[index].Name != monitoredItem.ResolvedNodeId.ToString())
             {
                 continue;
             }
             ArgumentUserControl argumentUserControl =
                 (ArgumentUserControl)monitoredVariablePanel.Controls[index];
             argumentUserControl.ValueInput = monitoredItemNotification.Value.WrappedValue.ToString();
         }
     }
     catch (Exception ex)
     {
         InformationDisplay($"Monitored Item Notification exception: {ex.StackTrace}");
     }
 }
Пример #4
0
        public void addConnection(BaseVariableState collectorNode, ReferenceDescription clientNode)
        {
            // test if clientNode is Variable
            if (clientNode.NodeClass == NodeClass.Variable)//&& collectorNode.GetType()==typeof(VariableNode))
            {
                MonitoredItem monitoredItem = new MonitoredItem();
                monitoredItem.StartNodeId   = ExpandedNodeId.ToNodeId(clientNode.NodeId, session.NamespaceUris);
                monitoredItem.AttributeId   = Attributes.Value;
                monitoredItem.Notification += new MonitoredItemNotificationEventHandler(connectVariable);
                Debug.Print("Client.cs: not fully implemented new session, just easily created");
                Subscription sub = new Subscription();
                sub.PublishingEnabled          = true;
                sub.PublishingInterval         = 1000;
                sub.Priority                   = 1;
                sub.KeepAliveCount             = 10;
                sub.LifetimeCount              = 20;
                sub.MaxNotificationsPerPublish = 1000;

                sub.AddItem(monitoredItem);
                session.AddSubscription(sub);
                sub.Create();
                connectedVariables.Add(monitoredItem, collectorNode);
            }
        }
Пример #5
0
        private void OnFastDataChange(Subscription subscription, DataChangeNotification notification, IList <string> stringTable)
        {
            OpcUaDeviceOutParamEntity opcUaDeviceOutParamEntity = new OpcUaDeviceOutParamEntity();

            opcUaDeviceOutParamEntity.StatusCode            = (uint)DeviceStatusCode.SubscriptionOK;
            opcUaDeviceOutParamEntity.SubScriptionValueList = new List <Tuple <string, object> >();

            foreach (MonitoredItemNotification itemNotification in notification.MonitoredItems)
            {
                MonitoredItem item = subscription.FindItemByClientHandle(itemNotification.ClientHandle);
                if (item == null)
                {
                    continue;
                }
                foreach (var value in item.DequeueValues())
                {
                    opcUaDeviceOutParamEntity.SubScriptionValueList.Add(Tuple.Create(item.ResolvedNodeId.ToString(), value.Value));
                }
            }

            DeviceEventArgs <DeviceParamEntityBase> args = new DeviceEventArgs <DeviceParamEntityBase>(opcUaDeviceOutParamEntity);

            Notification.Invoke(this, args);
        }
Пример #6
0
        /// <summary>
        /// Removes the monitored item from the collection.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        private HdaSubscribeAttributeRequest Remove(NodeState source, MonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                m_monitoredItems.Remove(monitoredItem.Id);

                // get the HDA item id.
                string itemId = GetItemId(source);

                // delete the subscribe request for the HDA item.
                if (itemId != null)
                {
                    HdaSubscribeAttributeRequest request = FindAttributeRequest(itemId, false);

                    if (request != null)
                    {
                        request.Remove(m_context, monitoredItem);
                        return(request);
                    }
                }

                return(null);
            }
        }
Пример #7
0
        /// <summary>
        /// Adds the monitored item to the collection.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        private HdaSubscribeAttributeRequest Add(NodeState source, MonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                // get the HDA item id.
                string itemId = GetItemId(source);

                // create/update the subscribe request for the HDA item.
                if (itemId != null)
                {
                    HdaSubscribeAttributeRequest request = FindAttributeRequest(itemId, true);

                    if (request != null)
                    {
                        request.Add(m_context, monitoredItem);
                        return(request);
                    }
                }

                return(null);
            }
        }
Пример #8
0
        /// <summary>
        /// Updates the filter.
        /// </summary>
        private void UpdateFilter()
        {
            if (m_subscription != null)
            {
                // changing the filter changes the fields requested. this makes it
                // impossible to process notifications sent before the change.
                // to avoid this problem we create a new item and remove the old one.
                MonitoredItem monitoredItem = m_filter.CreateMonitoredItem(m_session);

                // set up callback for notifications.
                monitoredItem.Notification += m_MonitoredItem_Notification;

                m_subscription.AddItem(monitoredItem);
                m_subscription.RemoveItem(m_monitoredItem);
                m_subscription.ApplyChanges();

                // replace monitored item.
                m_monitoredItem.Notification -= m_MonitoredItem_Notification;
                m_monitoredItem = monitoredItem;

                // send a refresh since previously filtered conditions may be now available.
                Conditions_RefreshMI_Click(this, null);
            }
        }
Пример #9
0
        /// <summary>
        /// Changes the area monitored by the control.
        /// </summary>
        public void ChangeArea(NodeId areaId, bool fetchRecent)
        {
            m_areaId = areaId;
            EventsLV.Items.Clear();

            if (fetchRecent)
            {
                ReadRecentHistory();
            }

            if (m_subscription != null)
            {
                MonitoredItem monitoredItem = new MonitoredItem(m_monitoredItem);
                monitoredItem.StartNodeId = areaId;

                m_subscription.AddItem(monitoredItem);
                m_subscription.RemoveItem(m_monitoredItem);
                m_monitoredItem = monitoredItem;

                monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification);

                m_subscription.ApplyChanges();
            }
        }
Пример #10
0
        /// <summary>
        /// Callback method for updating values of subscibed nodes
        /// </summary>
        /// <param name="monitoredItem"></param>
        /// <param name="e"></param>
        private void Notification_MonitoredItem(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            if (!(e.NotificationValue is MonitoredItemNotification notification))
            {
                return;
            }

            var value = notification.Value;

            var variable = ArchiveVariables.FirstOrDefault(x =>
                                                           x.Name == monitoredItem.StartNodeId && monitoredItem.DisplayName == $"{x.Name} [{ArchiveInterval.None}]");

            if (variable == null)
            {
                return;
            }

            _unitOfWork.Records.Add(new RecordEntity()
            {
                ArchiveTime = value.SourceTimestamp,
                VariableId  = variable.Id,
                Value       = value.Value.ToString()
            });
        }
Пример #11
0
        void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e);
                return;
            }

            try
            {
                MonitoredItemNotification datachange = e.NotificationValue as MonitoredItemNotification;

                if (datachange == null)
                {
                    return;
                }

                CurrentStateTB.Text = datachange.Value.WrappedValue.ToString();
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #12
0
        /// <summary>
        /// Updates the request after adding/removing items.
        /// </summary>
        private void UpdateSamplingInterval()
        {
            double samplingInterval = Double.MaxValue;

            for (int ii = 0; ii < MonitoredItems.Count; ii++)
            {
                MonitoredItem monitoredItem = MonitoredItems[ii];

                // find the handle associated with the item.
                NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle;

                if (handle == null)
                {
                    continue;
                }

                // ignore disabled items.
                if (monitoredItem.MonitoringMode == MonitoringMode.Disabled)
                {
                    continue;
                }

                // find the fastest sampling interval.
                if (samplingInterval > monitoredItem.SamplingInterval)
                {
                    samplingInterval = monitoredItem.SamplingInterval;
                }
            }

            // update values.
            if (samplingInterval != m_samplingInterval)
            {
                m_samplingInterval = (int)samplingInterval;
                m_nextUpdateTime   = DateTime.UtcNow;
            }
        }
Пример #13
0
        void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e);
                return;
            }

            try
            {
                MonitoredItemNotification datachange = e.NotificationValue as MonitoredItemNotification;

                if (datachange == null)
                {
                    return;
                }

                CurrentStateTB.Text = datachange.Value.WrappedValue.ToString();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #14
0
            /// <summary>
            /// Monitored item notification handler
            /// </summary>
            /// <param name="monitoredItem"></param>
            /// <param name="e"></param>
            private void OnMonitoredItemChanged(MonitoredItem monitoredItem,
                                                MonitoredItemNotificationEventArgs e)
            {
                try {
                    if (OnMonitoredItemChange == null)
                    {
                        return;
                    }
                    if (e?.NotificationValue == null || monitoredItem?.Subscription?.Session == null)
                    {
                        return;
                    }
                    if (!(e.NotificationValue is MonitoredItemNotification notification))
                    {
                        return;
                    }
                    if (!(notification.Value is DataValue value))
                    {
                        return;
                    }

                    var message = new SubscriptionNotificationModel {
                        ServiceMessageContext = monitoredItem.Subscription.Session.MessageContext,
                        ApplicationUri        = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri,
                        EndpointUrl           = monitoredItem.Subscription.Session.Endpoint.EndpointUrl,
                        SubscriptionId        = Id,
                        Notifications         = new List <MonitoredItemNotificationModel> {
                            notification.ToMonitoredItemNotification(monitoredItem)
                        }
                    };
                    OnMonitoredItemChange(this, message);
                }
                catch (Exception ex) {
                    _logger.Debug(ex, "Exception processing monitored item notification");
                }
            }
Пример #15
0
        private void ViewValueMI_Click(object sender, EventArgs e)
        {
            try {
                MonitoredItem monitoredItem = null;
                DataValue     value         = null;

                foreach (DataGridViewRow row in ResultsDV.SelectedRows)
                {
                    DataRowView source = row.DataBoundItem as DataRowView;
                    monitoredItem = (MonitoredItem)source.Row[0];
                    value         = (DataValue)source.Row[11];
                    break;
                }

                if (monitoredItem == null)
                {
                    return;
                }

                m_EditComplexValueDlg     = new EditComplexValueDlg();
                m_EditComplexValueDlg.Tag = monitoredItem;

                m_EditComplexValueDlg.ShowDialog(
                    m_session,
                    monitoredItem.ResolvedNodeId,
                    monitoredItem.AttributeId,
                    null,
                    value.Value,
                    true,
                    "View Data Change");

                m_EditComplexValueDlg = null;
            } catch (Exception exception) {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #16
0
        private void OnMonitorNotification(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs e)
        {
            VariableNode varNode = (VariableNode)monitoreditem.Subscription.Session.ReadNode(monitoreditem.StartNodeId);

            foreach (var value in monitoreditem.DequeueValues())
            {
                Console.WriteLine("Got a value");
                var     typeManager = new DataTypeManager(monitoreditem.Subscription.Session);
                UaValue opcvalue    = typeManager.GetUaValue(varNode, value, false);

                dynamic monitorInfoPair;

                lock (_monitorPublishInfo)
                {
                    monitorInfoPair = _monitorPublishInfo
                                      .SelectMany(pair => pair.Value, (parent, child) => new { ServerUrl = parent.Key, Info = child })
                                      .First(couple => couple.Info.Subscription == monitoreditem.Subscription);
                }

                var message = $"[TOPIC: {monitorInfoPair.Info.Topic}]  \t ({monitoreditem.DisplayName}): {opcvalue.Value}";
                monitorInfoPair.Info.Forward(message);
                Console.WriteLine(message);
            }
        }
Пример #17
0
        /// <summary>
        /// Handles a set monitoring mode request.
        /// </summary>
        public void SetMonitoringMode(List <MonitoringRequest> requests)
        {
            lock (m_lock)
            {
                if (m_session == null)
                {
                    throw new ServiceResultException(StatusCodes.BadCommunicationError);
                }

                for (int ii = 0; ii < requests.Count; ii++)
                {
                    MonitoredItem monitoredItem = null;

                    if (!m_monitoredItems.TryGetValue(requests[ii].MonitoredItem.Id, out monitoredItem))
                    {
                        continue;
                    }

                    monitoredItem.MonitoringMode = requests[ii].MonitoredItem.MonitoringMode;
                }

                m_subscription.ApplyChanges();
            }
        }
Пример #18
0
        private void DeleteMI_Click(object sender, EventArgs e)
        {
            try
            {
                if (m_state != DisplayState.EditItems)
                {
                    return;
                }

                foreach (DataGridViewRow row in ItemsDV.SelectedRows)
                {
                    DataRowView   source        = row.DataBoundItem as DataRowView;
                    MonitoredItem monitoredItem = (MonitoredItem)source.Row[0];
                    m_subscription.RemoveItem(monitoredItem);
                    source.Row.Delete();
                }

                m_dataset.AcceptChanges();
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
        private void NewMI_Click(object sender, EventArgs e)
        {
            try
            {
                MonitoredItem monitoredItem = null;

                foreach (DataGridViewRow row in ResultsDV.SelectedRows)
                {
                    DataRowView source = row.DataBoundItem as DataRowView;
                    monitoredItem = (MonitoredItem)source.Row[0];
                    break;
                }

                if (monitoredItem == null)
                {
                    monitoredItem = new MonitoredItem(m_subscription.DefaultItem);
                }
                else
                {
                    monitoredItem = new MonitoredItem(monitoredItem);
                }

                if (new EditMonitoredItemDlg().ShowDialog(m_session, monitoredItem, false))
                {
                    m_subscription.AddItem(monitoredItem);
                    DataRow row = m_dataset.Tables[0].NewRow();
                    monitoredItem.Handle = row;
                    UpdateRow(row, monitoredItem);
                    m_dataset.Tables[0].Rows.Add(row);
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #20
0
        /// <summary>
        /// Constructs an event object from a notification.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="monitoredItem">The monitored item that produced the notification.</param>
        /// <param name="notification">The notification.</param>
        /// <param name="knownEventTypes">The known event types.</param>
        /// <param name="eventTypeMappings">Mapping between event types and known event types.</param>
        /// <returns>
        /// The event object. Null if the notification is not a valid event type.
        /// </returns>
        public static BaseEventState ConstructEvent(
            Session session,
            MonitoredItem monitoredItem,
            EventFieldList notification,
            Dictionary <NodeId, Type> knownEventTypes,
            Dictionary <NodeId, NodeId> eventTypeMappings)
        {
            // find the event type.
            NodeId eventTypeId = FindEventType(monitoredItem, notification);

            if (eventTypeId == null)
            {
                return(null);
            }

            // look up the known event type.
            Type   knownType   = null;
            NodeId knownTypeId = null;

            if (eventTypeMappings.TryGetValue(eventTypeId, out knownTypeId))
            {
                knownType = knownEventTypes[knownTypeId];
            }

            // try again.
            if (knownType == null)
            {
                if (knownEventTypes.TryGetValue(eventTypeId, out knownType))
                {
                    knownTypeId = eventTypeId;
                    eventTypeMappings.Add(eventTypeId, eventTypeId);
                }
            }

            // try mapping it to a known type.
            if (knownType == null)
            {
                // browse for the supertypes of the event type.
                ReferenceDescriptionCollection supertypes = ClientUtils.BrowseSuperTypes(session, eventTypeId, false);

                // can't do anything with unknown types.
                if (supertypes == null)
                {
                    return(null);
                }

                // find the first supertype that matches a known event type.
                for (int ii = 0; ii < supertypes.Count; ii++)
                {
                    NodeId superTypeId = (NodeId)supertypes[ii].NodeId;

                    if (knownEventTypes.TryGetValue(superTypeId, out knownType))
                    {
                        knownTypeId = superTypeId;
                        eventTypeMappings.Add(eventTypeId, superTypeId);
                    }

                    if (knownTypeId != null)
                    {
                        break;
                    }
                }

                // can't do anything with unknown types.
                if (knownTypeId == null)
                {
                    return(null);
                }
            }

            // construct the event based on the known event type.
            BaseEventState e = (BaseEventState)Activator.CreateInstance(knownType, new object[] { (NodeState)null });

            // get the filter which defines the contents of the notification.
            EventFilter filter = monitoredItem.Status.Filter as EventFilter;

            // initialize the event with the values in the notification.
            e.Update(session.SystemContext, filter.SelectClauses, notification);

            // save the orginal notification.
            e.Handle = notification;

            return(e);
        }
Пример #21
0
        private void BoilerCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (m_session == null)
                {
                    return;
                }

                if (m_subscription != null)
                {
                    m_session.RemoveSubscription(m_subscription);
                    m_subscription = null;
                }

                ReferenceDescription boiler = (ReferenceDescription)BoilerCB.SelectedItem;

                if (boiler == null)
                {
                    return;
                }

                m_subscription = new Subscription();

                m_subscription.PublishingEnabled          = true;
                m_subscription.PublishingInterval         = 1000;
                m_subscription.Priority                   = 1;
                m_subscription.KeepAliveCount             = 10;
                m_subscription.LifetimeCount              = 20;
                m_subscription.MaxNotificationsPerPublish = 1000;

                m_session.AddSubscription(m_subscription);
                m_subscription.Create();

                NamespaceTable wellKnownNamespaceUris = new NamespaceTable();
                wellKnownNamespaceUris.Append(Namespaces.Boiler);

                string[] browsePaths = new string[]
                {
                    "1:PipeX001/1:FTX001/1:Output",
                    "1:DrumX001/1:LIX001/1:Output",
                    "1:PipeX002/1:FTX002/1:Output",
                    "1:LCX001/1:SetPoint",
                };

                List <NodeId> nodes = ClientUtils.TranslateBrowsePaths(
                    m_session,
                    (NodeId)boiler.NodeId,
                    wellKnownNamespaceUris,
                    browsePaths);

                Control[] controls = new Control[]
                {
                    InputPipeFlowTB,
                    DrumLevelTB,
                    OutputPipeFlowTB,
                    DrumLevelSetPointTB
                };

                for (int ii = 0; ii < nodes.Count; ii++)
                {
                    controls[ii].Text = "---";

                    if (nodes[ii] != null)
                    {
                        MonitoredItem monitoredItem = new MonitoredItem();
                        monitoredItem.StartNodeId   = nodes[ii];
                        monitoredItem.AttributeId   = Attributes.Value;
                        monitoredItem.Handle        = controls[ii];
                        monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification);
                        m_subscription.AddItem(monitoredItem);
                    }
                }

                m_subscription.ApplyChanges();
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #22
0
        /// <summary>
        /// Updates the display with a new value for a monitored variable.
        /// </summary>
        private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e);
                return;
            }

            try
            {
                EventFieldList notification = e.NotificationValue as EventFieldList;

                if (notification == null)
                {
                    return;
                }

                // check the type of event.
                NodeId eventTypeId = FormUtils.FindEventType(monitoredItem, notification);

                // ignore unknown events.
                if (NodeId.IsNull(eventTypeId))
                {
                    return;
                }

                // check for refresh start.
                if (eventTypeId == ObjectTypeIds.RefreshStartEventType)
                {
                    ConditionsLV.Items.Clear();
                    return;
                }

                // check for refresh end.
                if (eventTypeId == ObjectTypeIds.RefreshEndEventType)
                {
                    return;
                }

                // construct the condition object.
                ConditionState condition = FormUtils.ConstructEvent(
                    m_session,
                    monitoredItem,
                    notification,
                    m_eventTypeMappings) as ConditionState;

                if (condition == null)
                {
                    return;
                }

                // look for existing entry.
                ListViewItem item = null;

                for (int ii = 0; ii < ConditionsLV.Items.Count; ii++)
                {
                    ConditionState current = (ConditionState)ConditionsLV.Items[ii].Tag;

                    // the combination of a condition and branch id uniquely identify an item in the display.
                    if (current.NodeId == condition.NodeId && BaseVariableState.GetValue(current.BranchId) == BaseVariableState.GetValue(condition.BranchId))
                    {
                        // match found but watch out for out of order events (async processing can cause this to happen).
                        if (BaseVariableState.GetValue(current.Time) > BaseVariableState.GetValue(condition.Time))
                        {
                            return;
                        }

                        item = ConditionsLV.Items[ii];
                        break;
                    }
                }

                // create a new entry.
                if (item == null)
                {
                    item = new ListViewItem(String.Empty);

                    item.SubItems.Add(String.Empty); // Condition
                    item.SubItems.Add(String.Empty); // Branch
                    item.SubItems.Add(String.Empty); // Type
                    item.SubItems.Add(String.Empty); // Severity
                    item.SubItems.Add(String.Empty); // Time
                    item.SubItems.Add(String.Empty); // State
                    item.SubItems.Add(String.Empty); // Message
                    item.SubItems.Add(String.Empty); // Comment

                    ConditionsLV.Items.Add(item);
                }

                // look up the condition type metadata in the local cache.
                INode type = m_session.NodeCache.Find(condition.TypeDefinitionId);

                // Source
                if (condition.SourceName != null)
                {
                    item.SubItems[0].Text = Utils.Format("{0}", condition.SourceName.Value);
                }
                else
                {
                    item.SubItems[0].Text = null;
                }

                // Condition
                if (condition.ConditionName != null)
                {
                    item.SubItems[1].Text = Utils.Format("{0}", condition.ConditionName.Value);
                }
                else
                {
                    item.SubItems[1].Text = null;
                }

                // Branch
                if (condition.BranchId != null && !NodeId.IsNull(condition.BranchId.Value))
                {
                    item.SubItems[2].Text = Utils.Format("{0}", condition.BranchId.Value);
                }
                else
                {
                    item.SubItems[2].Text = null;
                }

                // Type
                if (type != null)
                {
                    item.SubItems[3].Text = Utils.Format("{0}", type);
                }
                else
                {
                    item.SubItems[3].Text = null;
                }

                // Severity
                if (condition.Severity != null)
                {
                    item.SubItems[4].Text = Utils.Format("{0}", (EventSeverity)condition.Severity.Value);
                }
                else
                {
                    item.SubItems[4].Text = null;
                }

                // Time
                if (condition.Time != null)
                {
                    item.SubItems[5].Text = Utils.Format("{0:HH:mm:ss.fff}", condition.Time.Value.ToLocalTime());
                }
                else
                {
                    item.SubItems[5].Text = null;
                }

                // State
                if (condition.EnabledState != null && condition.EnabledState.EffectiveDisplayName != null)
                {
                    item.SubItems[6].Text = Utils.Format("{0}", condition.EnabledState.EffectiveDisplayName.Value);
                }
                else
                {
                    item.SubItems[6].Text = null;
                }

                // Message
                if (condition.Message != null)
                {
                    item.SubItems[7].Text = Utils.Format("{0}", condition.Message.Value);
                }
                else
                {
                    item.SubItems[7].Text = null;
                }

                // Comment
                if (condition.Comment != null)
                {
                    item.SubItems[8].Text = Utils.Format("{0}", condition.Comment.Value);
                }
                else
                {
                    item.SubItems[8].Text = null;
                }

                item.Tag = condition;

                // set the color based on the retain bit.
                if (!BaseVariableState.GetValue(condition.Retain))
                {
                    item.ForeColor = Color.DimGray;
                }
                else
                {
                    if (NodeId.IsNull(BaseVariableState.GetValue(condition.BranchId)))
                    {
                        item.ForeColor = Color.Empty;
                    }
                    else
                    {
                        item.ForeColor = Color.DarkGray;
                    }
                }

                // adjust the width of the columns.
                for (int ii = 0; ii < ConditionsLV.Columns.Count; ii++)
                {
                    ConditionsLV.Columns[ii].Width = -2;
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #23
0
        /// <summary>
        /// Updates the application after connecting to or disconnecting from the server.
        /// </summary>
        private void Server_ConnectComplete(object sender, EventArgs e)
        {
            try
            {
                m_session = ConnectServerCTRL.Session;

                // check for disconnect.
                if (m_session == null)
                {
                    if (m_auditEventForm != null)
                    {
                        m_auditEventForm.Close();
                        m_auditEventForm = null;
                    }

                    return;
                }

                // set a suitable initial state.
                if (m_session != null && !m_connectedOnce)
                {
                    m_connectedOnce = true;
                }

                // create the default subscription.
                m_subscription = new Subscription();

                m_subscription.DisplayName                = null;
                m_subscription.PublishingInterval         = 1000;
                m_subscription.KeepAliveCount             = 10;
                m_subscription.LifetimeCount              = 100;
                m_subscription.MaxNotificationsPerPublish = 1000;
                m_subscription.PublishingEnabled          = true;
                m_subscription.TimestampsToReturn         = TimestampsToReturn.Both;

                m_session.AddSubscription(m_subscription);
                m_subscription.Create();

                // must specify the fields that the form is interested in.
                m_filter.SelectClauses = m_filter.ConstructSelectClauses(
                    m_session,
                    NodeId.Parse("ns=2;s=4:2"),
                    NodeId.Parse("ns=2;s=4:1"),
                    ObjectTypeIds.DialogConditionType,
                    ObjectTypeIds.ExclusiveLimitAlarmType,
                    ObjectTypeIds.NonExclusiveLimitAlarmType);

                // create a monitored item based on the current filter settings.
                m_monitoredItem = m_filter.CreateMonitoredItem(m_session);

                // set up callback for notifications.
                m_monitoredItem.Notification += m_MonitoredItem_Notification;

                m_subscription.AddItem(m_monitoredItem);
                m_subscription.ApplyChanges();

                // send an initial refresh.
                Conditions_RefreshMI_Click(sender, e);

                ConditionsMI.Enabled = true;
                ViewMI.Enabled       = true;
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Пример #24
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);
        }
Пример #25
0
        /// <summary>
        /// Validates the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="requests">The requests.</param>
        /// <returns>The items. May contain null is validation failed.</returns>
        public ComDaGroupItem[] ValidateItems(ComDaGroup group, ComDaCreateItemRequest[] requests)
        {
            TraceState("ValidateItems", group.Name);

            // get the session to use for the operation.
            Session session = m_session;

            if (session == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            // validate items.
            ComDaGroupItem[] items = new ComDaGroupItem[requests.Length];

            for (int ii = 0; ii < requests.Length; ii += 10000)
            {
                ValidateItems(session, group, requests, items, ii, 10000);
            }

            // process results.
            for (int ii = 0; ii < requests.Length; ii++)
            {
                // check for the results.
                ComDaCreateItemRequest request = requests[ii];

                if (request.Error < 0)
                {
                    items[ii] = null;
                    continue;
                }

                // check access path.
                if (!String.IsNullOrEmpty(request.AccessPath))
                {
                    items[ii]     = null;
                    request.Error = ResultIds.E_UNKNOWNPATH;
                    continue;
                }

                ComDaGroupItem item = items[ii];

                // validate the datatype.
                if (request.RequestedDataType != 0)
                {
                    NodeId dataTypeId = ComUtils.GetDataTypeId(request.RequestedDataType);

                    if (NodeId.IsNull(dataTypeId))
                    {
                        items[ii]     = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }

                    bool reqTypeIsArray    = (request.RequestedDataType & (short)VarEnum.VT_ARRAY) != 0;
                    bool actualTypeIsArray = (item.CanonicalDataType & (short)VarEnum.VT_ARRAY) != 0;

                    if (reqTypeIsArray != actualTypeIsArray)
                    {
                        items[ii]     = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }
                }

                // create a new monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.StartNodeId      = item.NodeId;
                monitoredItem.RelativePath     = null;
                monitoredItem.AttributeId      = Attributes.Value;
                monitoredItem.MonitoringMode   = (request.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled;
                monitoredItem.SamplingInterval = group.UpdateRate / 2;
                monitoredItem.QueueSize        = 0;
                monitoredItem.DiscardOldest    = true;
                monitoredItem.Filter           = null;

                // update item.
                item.ServerHandle  = (int)monitoredItem.ClientHandle;
                item.MonitoredItem = monitoredItem;

                // link the monitored item back to the group item.
                monitoredItem.Handle = item;

                // update return parameters.
                request.ServerHandle      = item.ServerHandle;
                request.CanonicalDataType = item.CanonicalDataType;
                request.AccessRights      = item.AccessRights;
                request.Error             = ResultIds.S_OK;
            }

            return(items);
        }
Пример #26
0
        /// <summary>
        // Handles the sampling interval procedure started from the menu bar.
        /// <summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void SamplingInterval_Click(object sender, EventArgs e)
        {
            try
            {
                // Check if operation is currently allowed.
                if (monitoredItemsControl.Subscription.Session == null ||
                    monitoredItemsControl.Subscription.innerSubscription == null ||
                    monitoredItemsControl.MonitoredItemsList.SelectedItems.Count == 0)
                {
                    return;
                }

                // Determine the sampling interval being requested.
                double samplingInterval = 0;

                if (sender == toolStripMenuItem_SamplingInterval_100)
                {
                    samplingInterval = 100;
                }
                else if (sender == toolStripMenuItem_SamplingInterval_500)
                {
                    samplingInterval = 500;
                }
                else if (sender == toolStripMenuItem_SamplingInterval_1000)
                {
                    samplingInterval = 1000;
                }

                // Update the monitoring mode.
                List <MonitoredItem> itemsToChange = new List <MonitoredItem>();

                for (int ii = 0; ii < monitoredItemsControl.MonitoredItemsList.SelectedItems.Count; ii++)
                {
                    MonitoredItem monitoredItem = monitoredItemsControl.MonitoredItemsList.SelectedItems[ii].Tag as MonitoredItem;

                    if (monitoredItem != null)
                    {
                        // Set the current interval.
                        monitoredItem.SamplingInterval = (int)samplingInterval;
                        itemsToChange.Add(monitoredItem);

                        // Apply the changes to the server.
                        monitoredItemsControl.Subscription.ModifyMonitoredItem(monitoredItem);

                        // Update the display.
                        // Sampling column.
                        monitoredItemsControl.MonitoredItemsList.SelectedItems[ii].SubItems[1].Text = samplingInterval.ToString();

                        // Error column.
                        monitoredItemsControl.MonitoredItemsList.SelectedItems[ii].SubItems[5].Text = String.Empty;

                        if (ServiceResult.IsBad(itemsToChange[ii].Status.Error))
                        {
                            monitoredItemsControl.MonitoredItemsList.SelectedItems[ii].SubItems[5].Text = itemsToChange[ii].Status.Error.StatusCode.ToString();
                        }
                    }
                }

                // Update status label.
                toolStripStatusLabel.Text = "Setting sampling interval succeeded.";
            }
            catch (Exception exception)
            {
                // Update status label.
                toolStripStatusLabel.Text  = "An exception occured while setting sampling interval: " + exception.Message;
                toolStripStatusLabel.Image = global::Siemens.OpcUA.Client.Properties.Resources.error;
            }
        }
        /// <summary>
        /// Shows a value in control.
        /// </summary>
        private async Task ShowValue(int index, bool overwrite, object value)
        {
            if (value == null)
            {
                return;
            }

            // show monitored items.
            MonitoredItem monitoredItem = value as MonitoredItem;

            if (monitoredItem != null)
            {
                m_monitoredItem = monitoredItem;
                ShowValue(ref index, ref overwrite, monitoredItem.LastValue.ToString());
                return;
            }

            // show data changes
            MonitoredItemNotification datachange = value as MonitoredItemNotification;

            if (datachange != null)
            {
                ShowValue(ref index, ref overwrite, datachange.Value.ToString());
                return;
            }

            // show events
            EventFieldList eventFields = value as EventFieldList;

            if (eventFields != null)
            {
                for (int ii = 0; ii < eventFields.EventFields.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, eventFields, ii);
                }

                return;
            }

            // show extension bodies.
            ExtensionObject extension = value as ExtensionObject;

            if (extension != null)
            {
                ShowValue(ref index, ref overwrite, extension.Body.ToString());
                return;
            }

            // show encodeables.
            IEncodeable encodeable = value as IEncodeable;

            if (encodeable != null)
            {
                PropertyInfo[] properties = encodeable.GetType().GetProperties();

                foreach (PropertyInfo property in properties)
                {
                    ShowValue(ref index, ref overwrite, encodeable, property);
                }

                return;
            }

            // show bytes.
            byte[] bytes = value as byte[];

            if (bytes != null)
            {
                bool result = await PromptOnLongList(bytes.Length / 16);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < bytes.Length; ii += 16)
                {
                    ShowValue(ref index, ref overwrite, bytes, ii);
                }

                return;
            }

            // show arrays
            Array array = value as Array;

            if (array != null)
            {
                bool result = await PromptOnLongList(array.Length);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < array.Length; ii++)
                {
                    ShowValue(ref index, ref overwrite, array, ii);
                }

                return;
            }

            // show lists
            IList list = value as IList;

            if (list != null)
            {
                bool result = await PromptOnLongList(list.Count);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < list.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, list, ii);
                }

                return;
            }

            // show xml elements
            XmlElement xml = value as XmlElement;

            if (xml != null)
            {
                bool result = await PromptOnLongList(xml.ChildNodes.Count);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < xml.ChildNodes.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, xml, ii);
                }

                return;
            }

            // show data value.
            DataValue datavalue = value as DataValue;

            if (datavalue != null)
            {
                ShowValue(ref index, ref overwrite, datavalue, 0);
                ShowValue(ref index, ref overwrite, datavalue, 1);
                ShowValue(ref index, ref overwrite, datavalue, 2);
                ShowValue(ref index, ref overwrite, datavalue, 3);
                return;
            }

            // show node id value.
            NodeId nodeId = value as NodeId;

            if (nodeId != null)
            {
                ShowValue(ref index, ref overwrite, nodeId, 0);
                ShowValue(ref index, ref overwrite, nodeId, 1);
                ShowValue(ref index, ref overwrite, nodeId, 2);
                return;
            }

            // show expanded node id value.
            ExpandedNodeId expandedNodeId = value as ExpandedNodeId;

            if (expandedNodeId != null)
            {
                ShowValue(ref index, ref overwrite, expandedNodeId, 0);
                ShowValue(ref index, ref overwrite, expandedNodeId, 1);
                ShowValue(ref index, ref overwrite, expandedNodeId, 2);
                ShowValue(ref index, ref overwrite, expandedNodeId, 3);
                return;
            }

            // show qualified name value.
            QualifiedName qualifiedName = value as QualifiedName;

            if (qualifiedName != null)
            {
                ShowValue(ref index, ref overwrite, qualifiedName, 0);
                ShowValue(ref index, ref overwrite, qualifiedName, 1);
                return;
            }

            // show qualified name value.
            LocalizedText localizedText = value as LocalizedText;

            if (localizedText != null)
            {
                ShowValue(ref index, ref overwrite, localizedText, 0);
                ShowValue(ref index, ref overwrite, localizedText, 1);
                return;
            }

            // show variant.
            Variant?variant = value as Variant?;

            if (variant != null)
            {
                ShowValue(ref index, ref overwrite, variant.Value.Value.ToString());
                return;
            }

            // show unknown types as strings.
            ShowValue(ref index, ref overwrite, String.Format("{0}", value));
        }
Пример #28
0
 private static string PrepareArgs(MonitoredItem monitoredItem)
 {
     return("-u " + monitoredItem.Url + " -e " + monitoredItem.ElementName + " -f " + monitoredItem.Frequency.ToString() + " -i " + monitoredItem.MonitItemId.ToString());
 }
Пример #29
0
 public void AddMonitoredItem(MonitoredItem monitoredItem)
 {
     _monitors.Add(monitoredItem);
 }
        /// <summary>
        /// The notification that the data for a monitored item has changed on an OPC UA server.
        /// </summary>
        public void MonitoredItemNotificationEventHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                if (e == null || e.NotificationValue == null || monitoredItem == null || monitoredItem.Subscription == null || monitoredItem.Subscription.Session == null)
                {
                    return;
                }

                if (!(e.NotificationValue is MonitoredItemNotification notification))
                {
                    return;
                }

                if (!(notification.Value is DataValue value))
                {
                    return;
                }

                MessageData messageData = new MessageData();
                if (IotCentralMode)
                {
                    // for IoTCentral we use the DisplayName as the key in the telemetry and the Value as the value.
                    if (monitoredItem.DisplayName != null)
                    {
                        // use the DisplayName as reported in the MonitoredItem
                        messageData.DisplayName = monitoredItem.DisplayName;
                    }
                    if (value.Value != null)
                    {
                        // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder
                        JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                        value.ServerTimestamp = DateTime.MinValue;
                        value.SourceTimestamp = DateTime.MinValue;
                        value.StatusCode      = StatusCodes.Good;
                        encoder.WriteDataValue("Value", value);
                        string valueString = encoder.CloseAndReturnText();
                        // we only want the value string, search for everything till the real value starts
                        // and get it
                        string marker      = "{\"Value\":{\"Value\":";
                        int    markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture);
                        messageData.PreserveValueQuotes = true;
                        if (markerStart >= 0)
                        {
                            // we either have a value in quotes or just a value
                            int valueLength;
                            int valueStart = marker.Length;
                            if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0)
                            {
                                // value is in quotes and two closing curly brackets at the end
                                valueStart++;
                                valueLength = valueString.Length - valueStart - 3;
                            }
                            else
                            {
                                // value is without quotes with two curly brackets at the end
                                valueLength = valueString.Length - marker.Length - 2;
                                messageData.PreserveValueQuotes = false;
                            }
                            messageData.Value = valueString.Substring(valueStart, valueLength);
                        }
                        Logger.Debug($"   IoTCentral key: {messageData.DisplayName}");
                        Logger.Debug($"   IoTCentral values: {messageData.Value}");
                    }
                }
                else
                {
                    // update the required message data to pass only the required data to HubCommunication
                    EndpointTelemetryConfiguration telemetryConfiguration = GetEndpointTelemetryConfiguration(EndpointUrl);

                    // the endpoint URL is required to allow HubCommunication lookup the telemetry configuration
                    messageData.EndpointUrl = EndpointUrl;
                    if (telemetryConfiguration.NodeId.Publish == true)
                    {
                        messageData.NodeId = OriginalId;
                    }
                    if (telemetryConfiguration.MonitoredItem.ApplicationUri.Publish == true)
                    {
                        messageData.ApplicationUri = (monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri + (string.IsNullOrEmpty(OpcSession.PublisherSite) ? "" : $":{OpcSession.PublisherSite}"));
                    }
                    if (telemetryConfiguration.MonitoredItem.DisplayName.Publish == true && monitoredItem.DisplayName != null)
                    {
                        // use the DisplayName as reported in the MonitoredItem
                        messageData.DisplayName = monitoredItem.DisplayName;
                    }
                    if (telemetryConfiguration.Value.SourceTimestamp.Publish == true && value.SourceTimestamp != null)
                    {
                        // use the SourceTimestamp as reported in the notification event argument in ISO8601 format
                        messageData.SourceTimestamp = value.SourceTimestamp.ToString("o", CultureInfo.InvariantCulture);
                    }
                    if (telemetryConfiguration.Value.StatusCode.Publish == true && value.StatusCode != null)
                    {
                        // use the StatusCode as reported in the notification event argument
                        messageData.StatusCode = value.StatusCode.Code;
                    }
                    if (telemetryConfiguration.Value.Status.Publish == true && value.StatusCode != null)
                    {
                        // use the StatusCode as reported in the notification event argument to lookup the symbolic name
                        messageData.Status = StatusCode.LookupSymbolicId(value.StatusCode.Code);
                    }
                    if (telemetryConfiguration.Value.Value.Publish == true && value.Value != null)
                    {
                        // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder
                        JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false);
                        value.ServerTimestamp = DateTime.MinValue;
                        value.SourceTimestamp = DateTime.MinValue;
                        value.StatusCode      = StatusCodes.Good;
                        encoder.WriteDataValue("Value", value);
                        string valueString = encoder.CloseAndReturnText();
                        // we only want the value string, search for everything till the real value starts
                        // and get it
                        string marker      = "{\"Value\":{\"Value\":";
                        int    markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture);
                        messageData.PreserveValueQuotes = true;
                        if (markerStart >= 0)
                        {
                            // we either have a value in quotes or just a value
                            int valueLength;
                            int valueStart = marker.Length;
                            if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0)
                            {
                                // value is in quotes and two closing curly brackets at the end
                                valueStart++;
                                valueLength = valueString.Length - valueStart - 3;
                            }
                            else
                            {
                                // value is without quotes with two curly brackets at the end
                                valueLength = valueString.Length - marker.Length - 2;
                                messageData.PreserveValueQuotes = false;
                            }
                            messageData.Value = valueString.Substring(valueStart, valueLength);
                        }
                    }

                    // currently the pattern processing is done here, which adds runtime to the notification processing.
                    // In case of perf issues it can be also done in CreateJsonMessageAsync of IoTHubMessaging.cs.

                    // apply patterns
                    messageData.ApplyPatterns(telemetryConfiguration);

                    Logger.Debug($"   ApplicationUri: {messageData.ApplicationUri}");
                    Logger.Debug($"   EndpointUrl: {messageData.EndpointUrl}");
                    Logger.Debug($"   DisplayName: {messageData.DisplayName}");
                    Logger.Debug($"   Value: {messageData.Value}");
                }

                // add message to fifo send queue
                if (monitoredItem.Subscription == null)
                {
                    Logger.Debug($"Subscription already removed. No more details available.");
                }
                else
                {
                    Logger.Debug($"Enqueue a new message from subscription {(monitoredItem.Subscription == null ? "removed" : monitoredItem.Subscription.Id.ToString(CultureInfo.InvariantCulture))}");
                    Logger.Debug($" with publishing interval: {monitoredItem.Subscription.PublishingInterval} and sampling interval: {monitoredItem.SamplingInterval}):");
                }
                HubCommunication.Enqueue(messageData);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error processing monitored item notification");
            }
        }
Пример #31
0
        /// <summary>
        /// Starts monitoring the value of the currently selected item.
        /// </summary>
        public void CreateMonitoredItem(ReferenceDescription node)
        {
            ListOfMonitoredItemCreateRequest itemsToCreate = new ListOfMonitoredItemCreateRequest();

            MonitoredItemCreateRequest itemToCreate = new MonitoredItemCreateRequest();

            itemToCreate.ItemToMonitor = new ReadValueId();
            itemToCreate.ItemToMonitor.NodeId = new NodeId(node.NodeId);
            itemToCreate.ItemToMonitor.AttributeId = Attributes.Value;
            itemToCreate.MonitoringMode = MonitoringMode.Reporting_2;
            itemToCreate.RequestedParameters = new MonitoringParameters();
            itemToCreate.RequestedParameters.ClientHandle = ++m_monitoredItemCount;
            itemToCreate.RequestedParameters.SamplingInterval = 1000;
            itemToCreate.RequestedParameters.QueueSize = 0;
            itemToCreate.RequestedParameters.DiscardOldest = true;
            itemToCreate.RequestedParameters.Filter = new ExtensionObject();

            itemsToCreate.Add(itemToCreate);

            ListOfMonitoredItemCreateResult results;
            ListOfDiagnosticInfo diagnosticInfos;

            m_client.CreateMonitoredItems(
                m_client.CreateRequestHeader(),
                m_subscriptionId,
                TimestampsToReturn.Both_2,
                itemsToCreate,
                out results,
                out diagnosticInfos);

            if (results != null)
            {
                // update the list view.
                MonitoredItemCreateResult result = results[0];

                ListViewItem item = new ListViewItem(itemToCreate.RequestedParameters.ClientHandle.ToString());

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[1].Text = node.DisplayName.Text;

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[2].Text = "<Unknown>";

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[3].Text = String.Format("{0}", result.StatusCode);

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[4].Text = String.Format("{0:HH:mm:ss}", DateTime.Now);

                UpdatesLV.Items.Add(item);

                // save the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.MonitoredItemId = result.MonitoredItemId;
                monitoredItem.ItemToMonitor = itemToCreate.ItemToMonitor;
                monitoredItem.MonitoringMode = itemToCreate.MonitoringMode;
                monitoredItem.Parameters = itemToCreate.RequestedParameters;

                monitoredItem.Parameters.SamplingInterval = result.RevisedSamplingInterval;
                monitoredItem.Parameters.QueueSize = result.RevisedQueueSize;

                m_monitoredItems.Add(itemToCreate.RequestedParameters.ClientHandle, monitoredItem);

                item.Tag = monitoredItem;
            }
        }
Пример #32
0
        /// <summary>
        /// Create Subscription and MonitoredItems for DataChanges
        /// </summary>
        public void SubscribeToDataChanges()
        {
            if (m_session == null || m_session.Connected == false)
            {
                m_output.WriteLine("Session not connected!");
                return;
            }

            try
            {
                // Create a subscription for receiving data change notifications

                // Define Subscription parameters
                Subscription subscription = new Subscription(m_session.DefaultSubscription);

                subscription.DisplayName        = "Console ReferenceClient Subscription";
                subscription.PublishingEnabled  = true;
                subscription.PublishingInterval = 1000;

                m_session.AddSubscription(subscription);

                // Create the subscription on Server side
                subscription.Create();
                m_output.WriteLine("New Subscription created with SubscriptionId = {0}.", subscription.Id);

                // Create MonitoredItems for data changes (Reference Server)

                MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
                intMonitoredItem.StartNodeId      = new NodeId("ns=2;s=Scalar_Simulation_Int32");
                intMonitoredItem.AttributeId      = Attributes.Value;
                intMonitoredItem.DisplayName      = "Int32 Variable";
                intMonitoredItem.SamplingInterval = 1000;
                intMonitoredItem.Notification    += OnMonitoredItemNotification;

                subscription.AddItem(intMonitoredItem);

                MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                // Float Node - Objects\CTT\Scalar\Simulation\Float
                floatMonitoredItem.StartNodeId      = new NodeId("ns=2;s=Scalar_Simulation_Float");
                floatMonitoredItem.AttributeId      = Attributes.Value;
                floatMonitoredItem.DisplayName      = "Float Variable";
                floatMonitoredItem.SamplingInterval = 1000;
                floatMonitoredItem.Notification    += OnMonitoredItemNotification;

                subscription.AddItem(floatMonitoredItem);

                MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                // String Node - Objects\CTT\Scalar\Simulation\String
                stringMonitoredItem.StartNodeId      = new NodeId("ns=2;s=Scalar_Simulation_String");
                stringMonitoredItem.AttributeId      = Attributes.Value;
                stringMonitoredItem.DisplayName      = "String Variable";
                stringMonitoredItem.SamplingInterval = 1000;
                stringMonitoredItem.Notification    += OnMonitoredItemNotification;

                subscription.AddItem(stringMonitoredItem);

                // Create the monitored items on Server side
                subscription.ApplyChanges();
                m_output.WriteLine("MonitoredItems created for SubscriptionId = {0}.", subscription.Id);
            }
            catch (Exception ex)
            {
                m_output.WriteLine("Subscribe error: {0}", ex.Message);
            }
        }
Пример #33
0
        /// <summary>
        /// Creates a monitored item.
        /// </summary>
        public void CreateMonitoredItem(
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // initialize the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.Id = (uint)Interlocked.Increment(ref m_monitoredItemCounter);
                monitoredItem.ItemToMonitor = request.ItemToMonitor;
                monitoredItem.MonitoringMode = request.MonitoringMode;
                monitoredItem.Parameters = request.RequestedParameters;
                monitoredItem.NextScanTime = 0;

                // use the publishing interval as the default.
                if (monitoredItem.Parameters.SamplingInterval < 0)
                {
                    monitoredItem.Parameters.SamplingInterval = m_publishingInterval;
                }

                // ensure the queue is at least one.
                if (monitoredItem.Parameters.QueueSize == 0)
                {
                    monitoredItem.Parameters.QueueSize = 1;
                }

                result.MonitoredItemId = monitoredItem.Id;
                result.RevisedQueueSize = monitoredItem.Parameters.QueueSize;
                result.RevisedSamplingInterval = monitoredItem.Parameters.SamplingInterval;
                result.FilterResult = new ExtensionObject();

                m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                // start a background thread that scans the items.
                if (m_monitoredItems.Count == 1)
                {
                    ThreadPool.QueueUserWorkItem(OnScanItems);
                }
            }
        }