Exemple #1
0
 public void AddChildTag(TheOPCMonitoredItemBase childTag)
 {
     if (_childTags == null)
     {
         _childTags = new List <TheOPCMonitoredItemBase>();
     }
     _childTags.Add(childTag);
 }
Exemple #2
0
        //public bool RegisterOrUnregisterThingForOpcEvent(TheOPCUARemoteServer server)
        //{
        //    var tEventHost = this.GetThing();
        //    if (tEventHost == null)
        //    {
        //        return false;
        //    }
        //    if (this.m_monitoredItem != null && this.m_monitoredItem.Handle != tEventHost)
        //    {
        //        UnregisterThingForOpcEvents(server);
        //    }

        //    return RegisterThingForOpcEvents(server);
        //}


        //void UnregisterThingForOpcEvents(TheOPCUARemoteServer server)
        //{
        //    var tEventHost = this.m_monitoredItem.Handle as ICDEThing;

        //    if (tEventHost != null)
        //    {
        //        // Stop the monitored item from updating the host thing
        //        this.m_monitoredItem.Handle = null;

        //        // Remove any properties from the host thing
        //        var cdeMValue = TheOPCMonitoredItemBase.GetOpcUaMetaString(server, this.EventTypeId);
        //        foreach (var cdeProp in tEventHost.GetBaseThing().GetPropertiesMetaStartingWith("OPCUA"))
        //        {
        //            if (cdeProp.cdeM == cdeMValue)
        //            {
        //                cdeProp.cdeM = null;
        //                tEventHost.GetBaseThing().RemoveProperty(cdeProp.Name);
        //            }
        //        }
        //    }

        //    // Remove the monitored item
        //    try
        //    {
        //        if (this.m_monitoredItem != null && this.m_monitoredItem.Subscription != null)
        //        {
        //            this.m_monitoredItem.Subscription.RemoveItem(this.m_monitoredItem);
        //            this.m_monitoredItem.Subscription.ApplyChanges();
        //            this.m_monitoredItem = null;
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        // Not much we can do if this fails other than leak the subscription until the next restart?
        //    }
        //}

        //bool RegisterThingForOpcEvents(TheOPCUARemoteServer server)
        //{
        //    var tEventHost = this.GetThing();
        //    if (tEventHost == null)
        //    {
        //        // TODO: log
        //        return false; // throw new Exception("Invalid host thing");
        //    }

        //    var subscription = server.Subscription;
        //    if (subscription != null)
        //    {
        //        // TODO: log
        //        return false; // throw new Exception("No Subscription");
        //    }
        //    var session = subscription.Session;
        //    if (session != null)
        //    {
        //        return false; // throw new Exception("No Session");
        //    }

        //    try
        //    {
        //        TypeDeclaration type = new TypeDeclaration();
        //        type.NodeId = ExpandedNodeId.ToNodeId(this.EventTypeId, session.NamespaceUris);
        //        type.Declarations = ClientUtils.CollectInstanceDeclarationsForType(session, type.NodeId);

        //        // the filter to use.
        //        var filter = new FilterDeclaration(type, null);

        //        // create a monitored item based on the current filter settings.
        //        var monitoredItem = new MonitoredItem();
        //        monitoredItem.StartNodeId = Opc.Ua.ObjectIds.Server;
        //        monitoredItem.AttributeId = Attributes.EventNotifier;
        //        monitoredItem.SamplingInterval = 0;
        //        monitoredItem.QueueSize = 1000;
        //        monitoredItem.DiscardOldest = true;
        //        monitoredItem.Filter = filter.GetFilter();
        //        monitoredItem.Handle = tEventHost; // We use this to detect changes in the host thing, so we can unregister properties in that old host thing

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

        //        //CreateSubscription(null, null);
        //        subscription.AddItem(monitoredItem);
        //        subscription.ApplyChanges();

        //        this.m_monitoredItem = monitoredItem;
        //    }
        //    catch (Exception e)
        //    {
        //        // TODO: log
        //        return false;
        //    }

        //    // TODO: Pre-create the properties for the event and add the cdeM information

        //    return true;
        //}

        protected override void InitializeMonitoredItem(TheOPCMonitoredItemBase previousTag)
        {
            RefreshNeeded = EventInfo.AggregateRetainedConditions;

            MyMonitoredItem.AttributeId      = Attributes.EventNotifier;
            MyMonitoredItem.QueueSize        = 1000;
            MyMonitoredItem.SamplingInterval = 0;
            MyMonitoredItem.Filter           = GetFilter();

            if (previousTag is TheOPCEvent previousEventTag)
            {
                if (EventInfo.IsEqual(previousEventTag.EventInfo))
                {
                    if (!previousEventTag.RefreshNeeded)
                    {
                        // The item has not changed: no need to consider for refresh
                        RefreshNeeded = false;
                    }
                }
            }
        }
Exemple #3
0
        public virtual bool MonitorTag(Subscription subscription, out string error, bool bApplySubscription = true, bool bReadInitialValue = true)
        {
            error = null;
            if (subscription == null || subscription.Session == null)
            {
                error = "Error: No OPC session.";
                return(false);
            }

            lock (subscription.MonitoredItems)
            {
                if (MyMonitoredItem != null && !subscription.MonitoredItems.Contains(MyMonitoredItem))
                {
                    // Monitored item was removed: recreate from scratch. Otherwise modify in place
                    MyMonitoredItem = null;
                }


                if (!this.IsSubscribedAsThing && !this.IsSubscribedAsProperty)
                {
                    // Nothing to be monitored
                    error = "Error: Nothing to be monitored";
                    return(false);
                }

                if (TheThing.GetSafePropertyBool(MyBaseThing, "DontMonitor") || SampleRate < -1)
                {
                    return(false);
                }
                // can only subscribe to local variables.
                //if (TagRef == null || TagRef.NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable)
                var resolvedNodeId = GetResolvedNodeIdName();
                if (resolvedNodeId == null) // || NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable)
                {
                    error = "Error: No or invalid NodeId";
                    return(false);
                }


                var previousMonitoredItem = subscription.MonitoredItems.FirstOrDefault(mi => mi.Handle == this || this.RefersToSamePropertyAndTag(mi.Handle));
                if (previousMonitoredItem != null)
                {
                    if (!previousMonitoredItem.StartNodeId.Equals(resolvedNodeId))
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error - monitored item {previousMonitoredItem.StartNodeId} replaced with {resolvedNodeId}. Change will not take effect!", eMsgLevel.l4_Message));
                    }
                    MyMonitoredItem = previousMonitoredItem;
                }
                else
                {
                    MyMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                }
                //MyMonitoredItem.StartNodeId = (NodeId)TagRef.NodeId;
                MyMonitoredItem.StartNodeId    = resolvedNodeId;
                MyMonitoredItem.AttributeId    = Attributes.Value;
                MyMonitoredItem.DisplayName    = DisplayName; // Utils.Format("{0}", TagRef);
                MyMonitoredItem.MonitoringMode = MonitoringMode.Reporting;
                if ((!this.HistoryStartTime.HasValue || this.HistoryStartTime.Value == DateTimeOffset.MinValue) && MyOPCServer.DefHistoryStartTime != DateTimeOffset.MinValue)
                {
                    this.HistoryStartTime = MyOPCServer.DefHistoryStartTime;
                }

                if (this.HistoryStartTime.HasValue && this.HistoryStartTime.Value != DateTimeOffset.MinValue)
                {
                    MyMonitoredItem.Filter = new AggregateFilter()
                    {
                        StartTime          = this.HistoryStartTime.Value.UtcDateTime,
                        ProcessingInterval = this.SampleRate,
                        AggregateType      = ObjectIds.AggregateFunction_Interpolative,
                    };
                    MyMonitoredItem.QueueSize        = uint.MaxValue;
                    MyMonitoredItem.SamplingInterval = 0;
                }
                else
                {
                    DataChangeFilter filter = null;
                    // TODO Remove this special case: pass parameters for deadband filters and StatusValueTimestamp (this breaks P08!!!)
                    if (this.DeadbandFilterValue != 0)
                    {
                        filter = new DataChangeFilter
                        {
                            DeadbandType  = (uint)(this.DeadbandFilterValue > 0 ? DeadbandType.Absolute : DeadbandType.Percent),
                            DeadbandValue = Math.Abs(this.DeadbandFilterValue)
                        };
                    }

                    if (ChangeTrigger != 1)
                    {
                        if (filter == null)
                        {
                            filter = new DataChangeFilter();
                        }
                        filter.Trigger = (DataChangeTrigger)ChangeTrigger;
                    }

                    if (filter != null)
                    {
                        MyMonitoredItem.Filter = filter;
                    }
                    MyMonitoredItem.SamplingInterval = SampleRate;

                    // For Events, the sample rate should be 0 (per spec), but is really ignored and thus should not affect the aggregate sample rate for the server
                    // All other sample rates are at least 50ms per other checks

                    if (SampleRate <= subscription.PublishingInterval * 2 && SampleRate > 0)
                    {
                        // 3.220: PublishingInterval is now independent of the sample rate: it only affects the frequency of the traffic from the server, not the content
                        //MyOPCServer.Subscription.PublishingInterval = SampleRate;

                        // Request the QueueSize to be 50 times the expected data points, so that no data is lost in normal operation
                        MyMonitoredItem.QueueSize = (uint)Math.Ceiling((((double)subscription.PublishingInterval) / SampleRate) * 50);
                        if (MyMonitoredItem.QueueSize < 50)
                        {
                            MyMonitoredItem.QueueSize = 50;
                        }
                    }
                    else
                    {
                        MyMonitoredItem.QueueSize = 50; // Request at least 50
                    }
                }
                MyMonitoredItem.DiscardOldest = true;

                MyMonitoredItem.Notification -= MonitoredItem_Notification;
                MyMonitoredItem.Notification += MonitoredItem_Notification;

                TheOPCMonitoredItemBase previousTag = null;
                if (previousMonitoredItem != null && previousMonitoredItem.Handle != this)
                {
                    previousTag = previousMonitoredItem.Handle as TheOPCMonitoredItemBase;
                    if (previousTag != null)
                    {
                        previousTag.ReleaseMonitoredItem();
                    }
                }

                MyMonitoredItem.Handle = this;

                InitializeMonitoredItem(previousTag);

                if (previousMonitoredItem == null)
                {
                    subscription.AddItem(MyMonitoredItem);
                }
            }
            if (bApplySubscription)
            {
#if OLD_UA
                var items = subscription.ApplyChanges();
                if (!items.Contains(MyMonitoredItem))
#else
                subscription.ApplyChanges();
                if (!subscription.MonitoredItems.Contains(MyMonitoredItem))
#endif
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error: Monitored item not found after applying changes {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l1_Error));
                    error = "Error: Monitored item not found after applying changes";
                    return(false);
                }
                else
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Added monitored item {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l4_Message));
                }
            }

            if (ServiceResult.IsBad(MyMonitoredItem.Status.Error))
            {
                TheThing.SetSafePropertyString(MyBaseThing, "LastMessage", MyMonitoredItem.Status.Error.StatusCode.ToString());
                TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Error adding monitored item {GetNodeIdForLogs()}", eMsgLevel.l4_Message, MyMonitoredItem.Status.Error.ToString()));
                error = "Error: " + MyMonitoredItem.Status.Error.ToString();
                return(false);
            }
            else
            {
                MyOPCServer.RegisterEvent("DisconnectComplete", sinkDisconnected);
            }

            TheThing.SetSafePropertyBool(MyBaseThing, "IsActive", true);
            return(true);
        }
Exemple #4
0
 protected virtual void InitializeMonitoredItem(TheOPCMonitoredItemBase previousTag)
 {
 }