/// <summary>
        /// Subscribes or unsubscribes to events produced an event source.
        /// </summary>
        public override ServiceResult SubscribeToEvents(
            OperationContext context,
            object sourceId,
            uint subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            ServerSystemContext systemContext = SystemContext.Copy(context);

            // send request to external system.
            try
            {
                MonitoredItem localItem = monitoredItem as MonitoredItem;

                if (localItem == null)
                {
                    return ServiceResult.Good;
                }

                Opc.Ua.Client.Session client = GetClientSession(systemContext);


                if (unsubscribe)
                {
                    lock (client)
                    {
                        // get the subscription.
                        Opc.Ua.Client.Subscription target = null;

                        foreach (Opc.Ua.Client.Subscription current in client.Subscriptions)
                        {
                            target = current;
                            break;
                        }

                        if (target == null)
                        {
                            return ServiceResult.Good;
                        }

                        // find matching item.
                        Opc.Ua.Client.MonitoredItem remoteItem = target.FindItemByClientHandle(monitoredItem.Id);

                        if (remoteItem == null)
                        {
                            return ServiceResult.Good;
                        }

                        // apply changes.
                        target.RemoveItem(remoteItem);
                        target.ApplyChanges();

                        if (target.MonitoredItemCount == 0)
                        {
                            target.Session.RemoveSubscription(target);
                        }
                    }

                    return ServiceResult.Good;
                }
                
                // create a request.
                Opc.Ua.Client.MonitoredItem request = new Opc.Ua.Client.MonitoredItem(localItem.Id);

                if (localItem.NodeId == ObjectIds.Server || localItem.NodeId == m_root.NodeId)
                {
                    request.StartNodeId = ObjectIds.Server;
                }
                else
                {
                    request.StartNodeId = m_mapper.ToRemoteId(localItem.NodeId);
                }

                request.AttributeId = Attributes.EventNotifier;
                request.MonitoringMode = localItem.MonitoringMode;
                request.SamplingInterval = (int)localItem.SamplingInterval;
                request.QueueSize = localItem.QueueSize;
                request.DiscardOldest = true;
                request.Filter = localItem.Filter;
                request.Handle = localItem;

                lock (client)
                {
                    // create subscription.
                    if (client.SubscriptionCount == 0)
                    {
                        Opc.Ua.Client.Subscription subscription = new Opc.Ua.Client.Subscription();

                        subscription.PublishingInterval = 250;
                        subscription.KeepAliveCount = 100;
                        subscription.LifetimeCount = 1000;
                        subscription.MaxNotificationsPerPublish = 10000;
                        subscription.Priority = 1;
                        subscription.PublishingEnabled = true;
                        subscription.TimestampsToReturn = TimestampsToReturn.Both;
                        subscription.DisableMonitoredItemCache = true;
                        subscription.FastDataChangeCallback = OnDataChangeNotification;
                        subscription.FastEventCallback = OnEventNotification;

                        client.AddSubscription(subscription);
                        subscription.Create();
                    }

                    // get the subscription.
                    Opc.Ua.Client.Subscription target = null;

                    foreach (Opc.Ua.Client.Subscription current in client.Subscriptions)
                    {
                        target = current;
                        break;
                    }

                    if (target == null)
                    {
                        return ServiceResult.Good;
                    }

                    target.AddItem(request);
                    target.ApplyChanges();

                    if (ServiceResult.IsBad(request.Status.Error))
                    {
                        Utils.Trace((int)Utils.TraceMasks.Error, "Could not create event item. {0}", request.Status.Error.ToLongString());
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Could not access external system.");
            }

            return ServiceResult.Good;
        }
            private void OnNotification(
                Opc.Ua.Client.MonitoredItem item, Opc.Ua.Client.MonitoredItemNotificationEventArgs e)
            {
                foreach (var value in item.DequeueValues())
                {
                    if (this.nodeIdToItemRef != null && this.nodeIdToItemRef.ContainsKey(item.StartNodeId))
                    {
                        // get item ref
                        var ir = this.nodeIdToItemRef[item.StartNodeId];

                        // change data (and notify ObservableCollection)
                        ir.DisplayValue = "" + value.Value;
                        ir.Value        = value.Value;
                        ir.ValueTouched = true;

                        // business logic event
                        if (this.ParentRef?.ItemChanged != null)
                        {
                            this.ParentRef.ItemChanged.Invoke(this.ParentRef, ir, ItemChangeType.Value);
                        }
                    }
                }
            }
示例#3
0
 public static Opc.Ua.Client.Subscription FindSubcriptionThatHasItem(this IEnumerable <Opc.Ua.Client.Subscription> source, string NodeId, out Opc.Ua.Client.MonitoredItem ItemToFind)
 {
     ItemToFind = null;
     foreach (Opc.Ua.Client.Subscription S in source)
     {
         ItemToFind = S.MonitoredItems.FirstOrDefault(I => I.StartNodeId.ToString() == NodeId);
         if (ItemToFind != null)
         {
             return(S);
         }
     }
     return(null);
 }
        /// <summary>
        /// Called when a batch of monitored items has been created.
        /// </summary>
        protected override void OnCreateMonitoredItemsComplete(ServerSystemContext context, IList<IMonitoredItem> monitoredItems)
        {
            List<Opc.Ua.Client.MonitoredItem> requests = new List<Opc.Ua.Client.MonitoredItem>();
            List<int> indexes = new List<int>();

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

                if (monitoredItem == null || !Object.ReferenceEquals(monitoredItem.NodeManager, this))
                {
                    continue;
                }

                lock (Lock)
                {
                    // determine if a local node.
                    if (PredefinedNodes.ContainsKey(monitoredItem.NodeId))
                    {
                        continue;
                    }

                    // create a request.
                    Opc.Ua.Client.MonitoredItem request = new Opc.Ua.Client.MonitoredItem(monitoredItem.Id);

                    request.StartNodeId = m_mapper.ToRemoteId(monitoredItem.NodeId);
                    request.MonitoringMode = monitoredItem.MonitoringMode;
                    request.SamplingInterval = (int)(monitoredItem.SamplingInterval/2);
                    request.Handle = monitoredItem;

                    requests.Add(request);
                    indexes.Add(ii);
                }
            }

            // send request to external system.
            try
            {
                Opc.Ua.Client.Session client = GetClientSession(context);

                lock (client)
                {
                    // create subscription.
                    if (client.SubscriptionCount == 0)
                    {
                        Opc.Ua.Client.Subscription subscription = new Opc.Ua.Client.Subscription();

                        subscription.PublishingInterval = 250;
                        subscription.KeepAliveCount = 100;
                        subscription.LifetimeCount = 1000;
                        subscription.MaxNotificationsPerPublish = 10000;
                        subscription.Priority = 1;
                        subscription.PublishingEnabled = true;
                        subscription.TimestampsToReturn = TimestampsToReturn.Both;
                        subscription.DisableMonitoredItemCache = true;
                        subscription.FastDataChangeCallback = OnDataChangeNotification;
                        subscription.FastEventCallback = OnEventNotification;

                        client.AddSubscription(subscription);
                        subscription.Create();
                    }

                    // add items.
                    Opc.Ua.Client.Subscription target = null;

                    foreach (Opc.Ua.Client.Subscription current in client.Subscriptions)
                    {
                        target = current;
                        break;
                    }

                    for (int ii = 0; ii < requests.Count; ii++)
                    {
                        target.AddItem(requests[ii]);
                    }

                    target.ApplyChanges();

                    // check status.
                    int index = 0;

                    foreach (Opc.Ua.Client.MonitoredItem monitoredItem in target.MonitoredItems)
                    {
                        if (ServiceResult.IsBad(monitoredItem.Status.Error))
                        {
                            ((MonitoredItem)monitoredItems[indexes[index++]]).QueueValue(null, monitoredItem.Status.Error);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // handle unexpected communication error.
                ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not access external system.");

                for (int ii = 0; ii < requests.Count; ii++)
                {
                    ((MonitoredItem)monitoredItems[indexes[ii]]).QueueValue(null, error);
                }
            }
        }
示例#5
0
 public System.Threading.Tasks.Task OPCUnmonitorAsync(Opc.Ua.Client.Subscription subscription, Opc.Ua.Client.MonitoredItem monitoredItem)
 {
     return(base.Channel.OPCUnmonitorAsync(subscription, monitoredItem));
 }
示例#6
0
 public void OPCUnmonitor(Opc.Ua.Client.Subscription subscription, Opc.Ua.Client.MonitoredItem monitoredItem)
 {
     base.Channel.OPCUnmonitor(subscription, monitoredItem);
 }