/// <summary>
        /// Checks if the item meets the group's criteria.
        /// </summary>
        private bool MeetsGroupCriteria(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            // can only sample variables.
            if ((monitoredItem.MonitoredItemType & MonitoredItemTypeMask.DataChange) == 0)
            {
                return(false);
            }

            // can't sample disabled items.
            if (monitoredItem.MonitoringMode == MonitoringMode.Disabled)
            {
                return(false);
            }

            // check sampling interval.
            if (AdjustSamplingInterval(monitoredItem.SamplingInterval) != m_samplingInterval)
            {
                return(false);
            }

            // compare session.
            if (context.SessionId != m_session.Id)
            {
                return(false);
            }

            // check the diagnostics marks.
            if (m_diagnosticsMask != (context.DiagnosticsMask & DiagnosticsMasks.OperationAll))
            {
                return(false);
            }

            return(true);
        }
示例#2
0
        /// <summary>
        /// Changes monitoring attributes the item.
        /// </summary>
        /// <remarks>
        /// It will call the external source to change the monitoring if an external source was provided originally.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void ModifyMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                // find existing sampling group.
                SamplingGroup samplingGroup = null;

                if (m_sampledItems.TryGetValue(monitoredItem, out samplingGroup))
                {
                    if (samplingGroup != null)
                    {
                        if (samplingGroup.ModifyMonitoring(context, monitoredItem))
                        {
                            return;
                        }
                    }

                    m_sampledItems.Remove(monitoredItem);
                }

                // assign to a new sampling group.
                StartMonitoring(context, monitoredItem);
                return;
            }
        }
示例#3
0
        /// <summary>
        /// Starts monitoring the item.
        /// </summary>
        /// <remarks>
        /// It will use the external source for monitoring if the source accepts the item.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void StartMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                // do nothing for disabled or exception based items.
                if (monitoredItem.MonitoringMode == MonitoringMode.Disabled || monitoredItem.MinimumSamplingInterval == 0)
                {
                    m_sampledItems.Add(monitoredItem, null);
                    return;
                }

                // find a suitable sampling group.
                foreach (SamplingGroup samplingGroup in m_samplingGroups)
                {
                    if (samplingGroup.StartMonitoring(context, monitoredItem))
                    {
                        m_sampledItems.Add(monitoredItem, samplingGroup);
                        return;
                    }
                }

                // create a new sampling group.
                SamplingGroup samplingGroup2 = new SamplingGroup(
                    m_server,
                    m_nodeManager,
                    m_samplingRates,
                    context,
                    monitoredItem.SamplingInterval);

                samplingGroup2.StartMonitoring(context, monitoredItem);

                m_samplingGroups.Add(samplingGroup2);
                m_sampledItems.Add(monitoredItem, samplingGroup2);
            }
        }
        /// <summary>
        /// Updates the group by apply any pending changes.
        /// </summary>
        /// <returns>
        /// Returns true if the group has no more items and can be dropped.
        /// </returns>
        public bool ApplyChanges()
        {
            lock (m_lock)
            {
                // add items.
                List <ISampledDataChangeMonitoredItem> itemsToSample = new List <ISampledDataChangeMonitoredItem>();

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

                    if (!m_items.ContainsKey(monitoredItem.Id))
                    {
                        m_items.Add(monitoredItem.Id, monitoredItem);

                        if (monitoredItem.MonitoringMode != MonitoringMode.Disabled)
                        {
                            itemsToSample.Add(monitoredItem);
                        }
                    }
                }

                m_itemsToAdd.Clear();

                // collect first sample.
                if (itemsToSample.Count > 0)
                {
                    Task.Run(() =>
                    {
                        DoSample(itemsToSample);
                    });
                }

                // remove items.
                for (int ii = 0; ii < m_itemsToRemove.Count; ii++)
                {
                    m_items.Remove(m_itemsToRemove[ii].Id);
                }

                m_itemsToRemove.Clear();

                // start the group if it is not running.
                if (m_items.Count > 0)
                {
                    Startup();
                }

                // stop the group if it is running.
                else if (m_items.Count == 0)
                {
                    Shutdown();
                }

                // can be shutdown if no items left.
                return(m_items.Count == 0);
            }
        }
示例#5
0
        /// <summary>
        /// Stops monitoring the item.
        /// </summary>
        /// <returns>
        /// Returns true if the items was marked for removal from the group.
        /// </returns>
        public bool StopMonitoring(ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock) {
                if (m_items.ContainsKey(monitoredItem.Id))
                {
                    m_itemsToRemove.Add(monitoredItem);
                    return(true);
                }

                return(false);
            }
        }
示例#6
0
        /// <summary>
        /// Checks if the monitored item can be handled by the group.
        /// </summary>
        /// <returns>
        /// True if the item was added to the group.
        /// </returns>
        /// <remarks>
        /// The ApplyChanges() method must be called to actually start sampling the item.
        /// </remarks>
        public bool StartMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock) {
                if (MeetsGroupCriteria(context, monitoredItem))
                {
                    m_itemsToAdd.Add(monitoredItem);
                    monitoredItem.SetSamplingInterval(m_samplingInterval);
                    return(true);
                }

                return(false);
            }
        }
示例#7
0
        /// <summary>
        /// Checks if the monitored item can still be handled by the group.
        /// </summary>
        /// <returns>
        /// False if the item has be marked for removal from the group.
        /// </returns>
        /// <remarks>
        /// The ApplyChanges() method must be called to actually stop sampling the item.
        /// </remarks>
        public bool ModifyMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock) {
                if (m_items.ContainsKey(monitoredItem.Id))
                {
                    if (MeetsGroupCriteria(context, monitoredItem))
                    {
                        monitoredItem.SetSamplingInterval(m_samplingInterval);
                        return(true);
                    }

                    m_itemsToRemove.Add(monitoredItem);
                }

                return(false);
            }
        }
示例#8
0
        /// <summary>
        /// Stops monitoring the item.
        /// </summary>
        /// <remarks>
        /// It will call the external source to stop the monitoring if an external source was provided originally.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void StopMonitoring(ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock) {
                // check for sampling group.
                SamplingGroup samplingGroup = null;

                if (m_sampledItems.TryGetValue(monitoredItem, out samplingGroup))
                {
                    if (samplingGroup != null)
                    {
                        samplingGroup.StopMonitoring(monitoredItem);
                    }

                    m_sampledItems.Remove(monitoredItem);
                    return;
                }
            }
        }
        /// <summary>
        /// Periodically checks if the sessions have timed out.
        /// </summary>
        private void SampleMonitoredItems(object data)
        {
            try
            {
                //Utils.Trace("Server: {0} Thread Started.", Thread.CurrentThread.Name);

                int sleepCycle = Convert.ToInt32(data, CultureInfo.InvariantCulture);
                int timeToWait = sleepCycle;

                while (m_server.IsRunning)
                {
                    DateTime start = DateTime.UtcNow;

                    // wait till next sample.
                    if (m_shutdownEvent.WaitOne(timeToWait))
                    {
                        break;
                    }

                    // get current list of items to sample.
                    List <ISampledDataChangeMonitoredItem> items = new List <ISampledDataChangeMonitoredItem>();

                    lock (m_lock)
                    {
                        uint disabledItemCount = 0;
                        Dictionary <uint, ISampledDataChangeMonitoredItem> .Enumerator enumerator = m_items.GetEnumerator();

                        while (enumerator.MoveNext())
                        {
                            ISampledDataChangeMonitoredItem monitoredItem = enumerator.Current.Value;

                            if (monitoredItem.MonitoringMode == MonitoringMode.Disabled)
                            {
                                disabledItemCount++;
                                continue;
                            }

                            // check whether the item should be sampled.
                            //if (!monitoredItem.SamplingIntervalExpired())
                            //{
                            //    continue;
                            //}

                            items.Add(monitoredItem);
                        }
                    }

                    // sample the values.
                    DoSample(items);

                    int delay = (int)(DateTime.UtcNow - start).TotalMilliseconds;
                    timeToWait = sleepCycle;

                    if (delay > sleepCycle)
                    {
                        timeToWait = 2 * sleepCycle - delay;

                        if (timeToWait < 0)
                        {
                            Utils.Trace("WARNING: SamplingGroup cannot sample fast enough. TimeToSample={0}ms, SamplingInterval={1}ms", delay, sleepCycle);
                            timeToWait = sleepCycle;
                        }
                    }
                }

                //Utils.Trace("Server: {0} Thread Exited Normally.", Thread.CurrentThread.Name);
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Server: SampleMonitoredItems Thread Exited Unexpectedly.");
            }
        }
示例#10
0
        /// <summary>
        /// Checks if the monitored item can be handled by the group.
        /// </summary>
        /// <returns>
        /// True if the item was added to the group.
        /// </returns>
        /// <remarks>
        /// The ApplyChanges() method must be called to actually start sampling the item. 
        /// </remarks>
        public bool StartMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                if (MeetsGroupCriteria(context, monitoredItem))
                {
                    m_itemsToAdd.Add(monitoredItem);
                    monitoredItem.SetSamplingInterval(m_samplingInterval);
                    return true;
                }

                return false;
            }
        }
示例#11
0
        /// <summary>
        /// Checks if the monitored item can still be handled by the group.
        /// </summary>
        /// <returns>
        /// False if the item has be marked for removal from the group.
        /// </returns>
        /// <remarks>
        /// The ApplyChanges() method must be called to actually stop sampling the item. 
        /// </remarks>
        public bool ModifyMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            lock (m_lock)
            {
                if (m_items.ContainsKey(monitoredItem.Id))
                {
                    if (MeetsGroupCriteria(context, monitoredItem))
                    {
                        monitoredItem.SetSamplingInterval(m_samplingInterval);
                        return true;
                    }
                        
                    m_itemsToRemove.Add(monitoredItem);
                }

                return false;
            }
        }
        /// <summary>
        /// Stops monitoring the item.
        /// </summary>
        /// <remarks>
        /// It will call the external source to stop the monitoring if an external source was provided originally.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void StopMonitoring(ISampledDataChangeMonitoredItem monitoredItem)
        {            
            lock (m_lock)
            {
                // check for sampling group.
                SamplingGroup samplingGroup = null;

                if (m_sampledItems.TryGetValue(monitoredItem, out samplingGroup))
                {                         
                    if (samplingGroup != null)
                    {
                        samplingGroup.StopMonitoring(monitoredItem);
                    }

                    m_sampledItems.Remove(monitoredItem);
                    return;
                }
            }
        }
        /// <summary>
        /// Changes monitoring attributes the item.
        /// </summary>
        /// <remarks>
        /// It will call the external source to change the monitoring if an external source was provided originally.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void ModifyMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {           
            lock (m_lock)
            {
                // find existing sampling group.
                SamplingGroup samplingGroup = null;

                if (m_sampledItems.TryGetValue(monitoredItem, out samplingGroup))
                {    
                    if (samplingGroup != null)
                    {
                        if (samplingGroup.ModifyMonitoring(context, monitoredItem))
                        {
                            return;
                        }
                    }

                    m_sampledItems.Remove(monitoredItem);
                }
                
                // assign to a new sampling group.
                StartMonitoring(context, monitoredItem);
                return;
            }
        }
        /// <summary>
        /// Starts monitoring the item.
        /// </summary>
        /// <remarks>
        /// It will use the external source for monitoring if the source accepts the item.
        /// The changes will not take affect until the ApplyChanges() method is called.
        /// </remarks>
        public virtual void StartMonitoring(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {             
            lock (m_lock)
            {
                // do nothing for disabled or exception based items.
                if (monitoredItem.MonitoringMode == MonitoringMode.Disabled || monitoredItem.MinimumSamplingInterval == 0)
                {
                    m_sampledItems.Add(monitoredItem, null);
                    return;
                }
                                
                // find a suitable sampling group.
                foreach (SamplingGroup samplingGroup in m_samplingGroups)
                {
                    if (samplingGroup.StartMonitoring(context, monitoredItem))
                    {
                        m_sampledItems.Add(monitoredItem, samplingGroup);
                        return;
                    }
                }
                
                // create a new sampling group.
                SamplingGroup samplingGroup2 = new SamplingGroup(
                    m_server,
                    m_nodeManager,
                    m_samplingRates,
                    context,
                    monitoredItem.SamplingInterval);

                samplingGroup2.StartMonitoring(context, monitoredItem);

                m_samplingGroups.Add(samplingGroup2);
                m_sampledItems.Add(monitoredItem, samplingGroup2);
            }
        }
        /// <summary>
        /// Modifies a monitored item and calls ModifyMonitoring().
        /// </summary>
        public virtual ServiceResult ModifyMonitoredItem(
            OperationContext           context,
            TimestampsToReturn         timestampsToReturn,
            ISampledDataChangeMonitoredItem   monitoredItem,
            MonitoredItemModifyRequest itemToModify,
            Range                      range)
        {   
            // use existing interval as sampling interval.
            double samplingInterval = itemToModify.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = monitoredItem.SamplingInterval;
            }
            
            // limit the sampling interval.
            double minimumSamplingInterval = monitoredItem.MinimumSamplingInterval;

            if (minimumSamplingInterval > 0 && samplingInterval < minimumSamplingInterval)
            {
                samplingInterval = minimumSamplingInterval;
            }
            
            // calculate queue size.
            uint queueSize = itemToModify.RequestedParameters.QueueSize;

            if (queueSize == 0)
            {
                queueSize = monitoredItem.QueueSize;
            }
        
            if (queueSize > m_maxQueueSize)
            {
                queueSize = m_maxQueueSize;
            }            

            // get filter.
            MonitoringFilter filter = null;

            if (!ExtensionObject.IsNull(itemToModify.RequestedParameters.Filter))
            {
                filter = (MonitoringFilter)itemToModify.RequestedParameters.Filter.Body;               
            }

            // update limits for event filters.
            if (filter is EventFilter)
            {
                samplingInterval = 0;
            }
            
            // modify the item attributes.
            ServiceResult error = monitoredItem.ModifyAttributes(
                context.DiagnosticsMask,
                timestampsToReturn,
                itemToModify.RequestedParameters.ClientHandle,
                filter,
                filter,
                range,
                samplingInterval,
                queueSize,
                itemToModify.RequestedParameters.DiscardOldest);

            // state of item did not change if an error returned here.
            if (ServiceResult.IsBad(error))
            {
                return error;
            }

            // update sampling.
            ModifyMonitoring(context, monitoredItem);

            // everything is ok.
            return ServiceResult.Good;
        }
示例#16
0
 /// <summary>
 /// Stops monitoring the item.
 /// </summary>
 /// <returns>
 /// Returns true if the items was marked for removal from the group.
 /// </returns>
 public bool StopMonitoring(ISampledDataChangeMonitoredItem monitoredItem)
 {
     lock (m_lock)
     {
         if (m_items.ContainsKey(monitoredItem.Id))
         {
             m_itemsToRemove.Add(monitoredItem);
             return true;
         }
             
         return false;
     }
 }
示例#17
0
        /// <summary>
        /// Modifies a monitored item and calls ModifyMonitoring().
        /// </summary>
        public virtual ServiceResult ModifyMonitoredItem(
            OperationContext context,
            TimestampsToReturn timestampsToReturn,
            ISampledDataChangeMonitoredItem monitoredItem,
            MonitoredItemModifyRequest itemToModify,
            Range range)
        {
            // use existing interval as sampling interval.
            double samplingInterval = itemToModify.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = monitoredItem.SamplingInterval;
            }

            // limit the sampling interval.
            double minimumSamplingInterval = monitoredItem.MinimumSamplingInterval;

            if (minimumSamplingInterval > 0 && samplingInterval < minimumSamplingInterval)
            {
                samplingInterval = minimumSamplingInterval;
            }

            // calculate queue size.
            uint queueSize = itemToModify.RequestedParameters.QueueSize;

            if (queueSize == 0)
            {
                queueSize = monitoredItem.QueueSize;
            }

            if (queueSize > m_maxQueueSize)
            {
                queueSize = m_maxQueueSize;
            }

            // get filter.
            MonitoringFilter filter = null;

            if (!ExtensionObject.IsNull(itemToModify.RequestedParameters.Filter))
            {
                filter = (MonitoringFilter)itemToModify.RequestedParameters.Filter.Body;
            }

            // update limits for event filters.
            if (filter is EventFilter)
            {
                samplingInterval = 0;
            }

            // modify the item attributes.
            ServiceResult error = monitoredItem.ModifyAttributes(
                context.DiagnosticsMask,
                timestampsToReturn,
                itemToModify.RequestedParameters.ClientHandle,
                filter,
                filter,
                range,
                samplingInterval,
                queueSize,
                itemToModify.RequestedParameters.DiscardOldest);

            // state of item did not change if an error returned here.
            if (ServiceResult.IsBad(error))
            {
                return(error);
            }

            // update sampling.
            ModifyMonitoring(context, monitoredItem);

            // everything is ok.
            return(ServiceResult.Good);
        }
示例#18
0
        /// <summary>
        /// Checks if the item meets the group's criteria.
        /// </summary>
        private bool MeetsGroupCriteria(OperationContext context, ISampledDataChangeMonitoredItem monitoredItem)
        {
            // can only sample variables.
            if ((monitoredItem.MonitoredItemType & MonitoredItemTypeMask.DataChange) == 0)
            {
                return false;
            }

            // can't sample disabled items.
            if (monitoredItem.MonitoringMode == MonitoringMode.Disabled)
            {
                return false;
            }

            // check sampling interval.
            if (AdjustSamplingInterval(monitoredItem.SamplingInterval) != m_samplingInterval)
            {
                return false;
            }         
            
            // compare session.
            if (context.SessionId != m_session.Id)
            {
                return false;
            }

            // check the diagnostics marks.
            if (m_diagnosticsMask != (context.DiagnosticsMask & DiagnosticsMasks.OperationAll))
            {
                return false;
            }

            return true;
        }