Ejemplo n.º 1
0
        /// <summary>
        /// Returns the AbsoluteDeadband if the filter specifies one. Zero otherwize.
        /// </summary>
        public static double GetAbsoluteDeadband(MonitoringFilter filter)
        {
            DataChangeFilter datachangeFilter = filter as DataChangeFilter;

            if (datachangeFilter == null)
            {
                return 0.0;
            }

            if (datachangeFilter.DeadbandType != (uint)Opc.Ua.DeadbandType.Absolute)
            {
                return 0.0;
            }

            return datachangeFilter.DeadbandValue;
        }
		/// <summary>
		/// Initializes the object with its node type.
		/// </summary>
        public MemoryBufferMonitoredItem(
            IServerInternal     server,
            INodeManager        nodeManager,
            object              mangerHandle,
            uint                offset,
            uint                subscriptionId,
            uint                id,
            Session             session,
            ReadValueId         itemToMonitor,
            DiagnosticsMasks    diagnosticsMasks,
            TimestampsToReturn  timestampsToReturn,
            MonitoringMode      monitoringMode,
            uint                clientHandle,
            MonitoringFilter    originalFilter,
            MonitoringFilter    filterToUse,
            Range               range,
            double              samplingInterval,
            uint                queueSize,
            bool                discardOldest,
            double              minimumSamplingInterval)
        :
            base(
                server,
                nodeManager,
                mangerHandle,
                subscriptionId,
                id,
                session,
                itemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                originalFilter,
                filterToUse,
                range,
                samplingInterval,
                queueSize,
                discardOldest,
                minimumSamplingInterval)
		{
            m_offset = offset;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates a new monitored item.
 /// </summary>
 /// <param name="server">The server.</param>
 /// <param name="nodeManager">The node manager.</param>
 /// <param name="managerHandle">The manager handle.</param>
 /// <param name="subscriptionId">The subscription id.</param>
 /// <param name="id">The id.</param>
 /// <param name="session">The session.</param>
 /// <param name="itemToMonitor">The item to monitor.</param>
 /// <param name="diagnosticsMasks">The diagnostics masks.</param>
 /// <param name="timestampsToReturn">The timestamps to return.</param>
 /// <param name="monitoringMode">The monitoring mode.</param>
 /// <param name="clientHandle">The client handle.</param>
 /// <param name="originalFilter">The original filter.</param>
 /// <param name="filterToUse">The filter to use.</param>
 /// <param name="range">The range.</param>
 /// <param name="samplingInterval">The sampling interval.</param>
 /// <param name="queueSize">Size of the queue.</param>
 /// <param name="discardOldest">if set to <c>true</c> [discard oldest].</param>
 /// <param name="minimumSamplingInterval">The minimum sampling interval.</param>
 /// <returns>The monitored item.</returns>
 protected virtual MonitoredItem CreateMonitoredItem(
     IServerInternal server,
     INodeManager nodeManager,
     object managerHandle,
     uint subscriptionId,
     uint id,
     Session session,
     ReadValueId itemToMonitor,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     MonitoringFilter originalFilter,
     MonitoringFilter filterToUse,
     Range range,
     double samplingInterval,
     uint queueSize,
     bool discardOldest,
     double minimumSamplingInterval)
 {
     return(new MonitoredItem(
                server,
                nodeManager,
                managerHandle,
                subscriptionId,
                id,
                session,
                itemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                originalFilter,
                filterToUse,
                range,
                samplingInterval,
                queueSize,
                discardOldest,
                minimumSamplingInterval));
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Initializes the object with its node type.
 /// </summary>
 public ComMonitoredItem(
     IServerInternal server,
     INodeManager nodeManager,
     object mangerHandle,
     uint subscriptionId,
     uint id,
     Session session,
     ReadValueId itemToMonitor,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     MonitoringFilter originalFilter,
     MonitoringFilter filterToUse,
     Range range,
     double samplingInterval,
     uint queueSize,
     bool discardOldest,
     double sourceSamplingInterval)
     : base(server,
            nodeManager,
            mangerHandle,
            subscriptionId,
            id,
            session,
            itemToMonitor,
            diagnosticsMasks,
            timestampsToReturn,
            monitoringMode,
            clientHandle,
            originalFilter,
            filterToUse,
            range,
            samplingInterval,
            queueSize,
            discardOldest,
            sourceSamplingInterval)
 {
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Throws an exception if the flter cannot be used with the node class.
        /// </summary>
        private void ValidateFilter(NodeClass nodeClass, MonitoringFilter filter)
        {
            if (filter == null)
            {
                return;
            }

            switch (nodeClass)
            {
            case NodeClass.Variable:
            case NodeClass.VariableType:
            {
                if (!typeof(DataChangeFilter).IsInstanceOfType(filter))
                {
                    m_nodeClass = NodeClass.Variable;
                }

                break;
            }

            case NodeClass.Object:
            case NodeClass.View:
            {
                if (!typeof(EventFilter).IsInstanceOfType(filter))
                {
                    m_nodeClass = NodeClass.Object;
                }

                break;
            }

            default:
            {
                throw ServiceResultException.Create(StatusCodes.BadFilterNotAllowed, "Filters may not be specified for nodes of class '{0}'.", nodeClass);
            }
            }
        }
        /// <summary>
        /// Throws an exception if the flter cannot be used with the node class.
        /// </summary>
        private void ValidateFilter(NodeClass nodeClass, MonitoringFilter filter)
        {
            if (filter == null)
            {
                return;
            }

            switch (nodeClass)
            {
                case NodeClass.Variable:
                case NodeClass.VariableType:
                {
                    if (!typeof(DataChangeFilter).IsInstanceOfType(filter))
                    {
                        m_nodeClass = NodeClass.Variable;
                    }

                    break;
                }

                case NodeClass.Object:
                case NodeClass.View:
                {
                    if (!typeof(EventFilter).IsInstanceOfType(filter))
                    {                        
                        m_nodeClass = NodeClass.Object;
                    }

                    break;
                }

                default:
                {
                    throw ServiceResultException.Create(StatusCodes.BadFilterNotAllowed, "Filters may not be specified for nodes of class '{0}'.", nodeClass);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        protected override ServiceResult CreateMonitoredItem(ServerSystemContext context, NodeHandle handle, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterResult, out IMonitoredItem monitoredItem)
        {
            filterResult  = null;
            monitoredItem = null;

            // validate parameters.
            MonitoringParameters parameters = itemToCreate.RequestedParameters;

            // validate attribute.
            if (!Attributes.IsValid(handle.Node.NodeClass, itemToCreate.ItemToMonitor.AttributeId))
            {
                return(StatusCodes.BadAttributeIdInvalid);
            }

            NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node);

            // check if the node is already being monitored.
            MonitoredNode2 monitoredNode = null;

            if (!MonitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode))
            {
                MonitoredNodes[handle.Node.NodeId] = monitoredNode = new MonitoredNode2(this, cachedNode);
            }

            handle.Node          = monitoredNode.Node;
            handle.MonitoredNode = monitoredNode;

            // create a globally unique identifier.
            uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

            // determine the sampling interval.
            double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // ensure minimum sampling interval is not exceeded.
            if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = handle.Node as BaseVariableState;

                if (variable != null && samplingInterval < variable.MinimumSamplingInterval)
                {
                    samplingInterval = variable.MinimumSamplingInterval;
                }
            }

            // put a large upper limit on sampling.
            if (samplingInterval == Double.MaxValue)
            {
                samplingInterval = 365 * 24 * 3600 * 1000.0;
            }

            // put an upper limit on queue size.
            uint queueSize = itemToCreate.RequestedParameters.QueueSize;

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

            // validate the monitoring filter.
            Range            euRange     = null;
            MonitoringFilter filterToUse = null;

            ServiceResult error = ValidateMonitoringFilter(
                context,
                handle,
                itemToCreate.ItemToMonitor.AttributeId,
                samplingInterval,
                queueSize,
                parameters.Filter,
                out filterToUse,
                out euRange,
                out filterResult);

            if (ServiceResult.IsBad(error))
            {
                return(error);
            }

            // create the item.
            MonitoredItem datachangeItem = new ComMonitoredItem(
                Server,
                this,
                handle,
                subscriptionId,
                monitoredItemId,
                context.OperationContext.Session,
                itemToCreate.ItemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                filterToUse,
                filterToUse,
                euRange,
                samplingInterval,
                queueSize,
                itemToCreate.RequestedParameters.DiscardOldest,
                0);

            // report the initial value.
            ReadInitialValue(context, handle, datachangeItem);

            // update monitored item list.
            monitoredItem = datachangeItem;

            // save the monitored item.
            MonitoredItems.Add(monitoredItemId, datachangeItem);
            monitoredNode.Add(datachangeItem);

            // report change.
            OnMonitoredItemCreated(context, handle, datachangeItem);

            return(error);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Reports a modified monitored item.
        /// </summary>
        public static void ReportModifyMonitoredItem(
            NodeId nodeId,
            uint serverHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            MonitoringFilter filter,
            MonitoringMode monitoringMode)
        {
            if (!m_eventsEnabled)
            {
                return;
            }

            lock (m_events)
            {
                Event e = new Event();
                e.EventType = EventType.ModifyItem;
                e.NodeId = nodeId;
                e.ServerHandle = serverHandle;
                e.Timestamp = HiResClock.UtcNow;
                e.Value = null;
                e.Parameters = new MonitoringParameters();
                e.Parameters.SamplingInterval = samplingInterval;
                e.Parameters.QueueSize = queueSize;
                e.Parameters.DiscardOldest = discardOldest;
                e.Parameters.Filter = new ExtensionObject(filter);
                e.MonitoringMode = monitoringMode;
                m_events.Enqueue(e);
            }
        }
		/// <summary>
		/// Initializes the object with its node type.
		/// </summary>
        public MonitoredItem(
            IServerInternal     server,
            INodeManager        nodeManager,
            object              mangerHandle,
            uint                subscriptionId,
            uint                id,
            Session             session,
            ReadValueId         itemToMonitor,
            DiagnosticsMasks    diagnosticsMasks,
            TimestampsToReturn  timestampsToReturn,
            MonitoringMode      monitoringMode,
            uint                clientHandle,
            MonitoringFilter    originalFilter,
            MonitoringFilter    filterToUse,
            Range               range,
            double              samplingInterval,
            uint                queueSize,
            bool                discardOldest,
            double              sourceSamplingInterval)
		{
            if (itemToMonitor == null) throw new ArgumentNullException("itemToMonitor");
            
			Initialize();
            
            m_server                  = server;
            m_nodeManager             = nodeManager;
            m_managerHandle           = mangerHandle;
            m_subscriptionId          = subscriptionId;
            m_id                      = id;
            m_session                 = session;
            m_nodeId                  = itemToMonitor.NodeId;
            m_attributeId             = itemToMonitor.AttributeId;
            m_indexRange              = itemToMonitor.IndexRange;
            m_parsedIndexRange        = itemToMonitor.ParsedIndexRange;
            m_encoding                = itemToMonitor.DataEncoding;
            m_diagnosticsMasks        = diagnosticsMasks;
            m_timestampsToReturn      = timestampsToReturn;
            m_monitoringMode          = monitoringMode;
            m_clientHandle            = clientHandle;
            m_originalFilter          = originalFilter;
            m_filterToUse             = filterToUse;
            m_range                   = 0;
            m_samplingInterval        = samplingInterval;
            m_queueSize               = queueSize;
            m_discardOldest           = discardOldest;
            m_sourceSamplingInterval  = (int)sourceSamplingInterval;
            m_calculator              = null;
            m_nextSamplingTime        = DateTime.UtcNow.Ticks;
            m_alwaysReportUpdates     = false;
            
            m_typeMask = MonitoredItemTypeMask.DataChange;

            if (originalFilter is EventFilter)
            {
                m_typeMask = MonitoredItemTypeMask.Events;

                if (itemToMonitor.NodeId == Objects.Server)
                {
                    m_typeMask |= MonitoredItemTypeMask.AllEvents;
                }
            }

            // create aggregate calculator.
            ServerAggregateFilter aggregateFilter = filterToUse as ServerAggregateFilter;

            if (filterToUse is ServerAggregateFilter)
            {
                m_calculator = m_server.AggregateManager.CreateCalculator(
                    aggregateFilter.AggregateType,
                    aggregateFilter.StartTime,
                    DateTime.MaxValue,
                    aggregateFilter.ProcessingInterval,
                    aggregateFilter.Stepped,
                    aggregateFilter.AggregateConfiguration);
            }

            if (range != null)
            {
                m_range = range.High - range.Low;
            }

            // report change to item state.
            ServerUtils.ReportCreateMonitoredItem(
                m_nodeId,
                m_id,
                m_samplingInterval,
                m_queueSize,
                m_discardOldest,
                m_filterToUse,
                m_monitoringMode);

            InitializeQueue();
		}
Ejemplo n.º 10
0
 public UaItemCollection(UaSubscription subscription, MonitoringMode monitoringMode, MonitoringFilter monitoringFilter, bool useQueue)
 {
     _subscription     = subscription;
     _monitoringMode   = monitoringMode;
     _monitoringFilter = monitoringFilter;
     _useQueue         = useQueue;
 }
Ejemplo n.º 11
0
 public EventQueueMonitoredItem(ISubscription target, PropertyInfo property, NodeId nodeId, uint attributeId = 12, string indexRange = null, MonitoringMode monitoringMode = MonitoringMode.Reporting, int samplingInterval = -1, MonitoringFilter filter = null, uint queueSize = 0, bool discardOldest = true)
     : base(target, property, nodeId, attributeId, indexRange, monitoringMode, samplingInterval, filter, queueSize, discardOldest)
 {
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MonitoredItemBase"/> class.
        /// </summary>
        /// <param name="target">the target model to store the published value.</param>
        /// <param name="property">the property of the model to store the published value.</param>
        /// <param name="nodeId">the NodeId to monitor.</param>
        /// <param name="attributeId">the attribute to monitor.</param>
        /// <param name="indexRange">the range of array indexes to monitor.</param>
        /// <param name="monitoringMode">the monitoring mode.</param>
        /// <param name="samplingInterval">the sampling interval.</param>
        /// <param name="filter">the properties that trigger a notification.</param>
        /// <param name="queueSize">the length of the queue used by the server to buffer values.</param>
        /// <param name="discardOldest">a value indicating whether to discard the oldest entries in the queue when it is full.</param>
        public MonitoredItemBase(ISubscription target, PropertyInfo property, NodeId nodeId, uint attributeId = AttributeIds.Value, string indexRange = null, MonitoringMode monitoringMode = MonitoringMode.Reporting, int samplingInterval = -1, MonitoringFilter filter = null, uint queueSize = 0, bool discardOldest = true)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            if (nodeId == null)
            {
                throw new ArgumentNullException(nameof(nodeId));
            }

            this.Target           = target;
            this.Property         = property;
            this.NodeId           = nodeId;
            this.AttributeId      = attributeId;
            this.IndexRange       = indexRange;
            this.MonitoringMode   = monitoringMode;
            this.SamplingInterval = samplingInterval;
            this.Filter           = filter;
            this.QueueSize        = queueSize;
            this.DiscardOldest    = discardOldest;
            this.ClientId         = (uint)Interlocked.Increment(ref lastClientId);
        }
Ejemplo n.º 13
0
 public DataValueQueueMonitoredItem(PropertyInfo property, NodeId nodeId, uint attributeId = 13, string indexRange = null, MonitoringMode monitoringMode = MonitoringMode.Reporting, int samplingInterval = -1, MonitoringFilter filter = null, uint queueSize = 0, bool discardOldest = true)
     : base(property, nodeId, attributeId, indexRange, monitoringMode, samplingInterval, filter, queueSize, discardOldest)
 {
 }
Ejemplo n.º 14
0
        public EventQueueMonitoredItem(object target, PropertyInfo property, NodeId nodeId, uint attributeId = 12, string indexRange = null, MonitoringMode monitoringMode = MonitoringMode.Reporting, int samplingInterval = -1, MonitoringFilter filter = null, uint queueSize = 0, bool discardOldest = true)
            : base(property.Name, nodeId, attributeId, indexRange, monitoringMode, samplingInterval, filter, queueSize, discardOldest)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            this.Target   = target;
            this.Property = property;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MonitoredItemBase"/> class.
        /// </summary>
        /// <param name="name">the key.</param>
        /// <param name="nodeId">the NodeId to monitor.</param>
        /// <param name="attributeId">the attribute to monitor.</param>
        /// <param name="indexRange">the range of array indexes to monitor.</param>
        /// <param name="monitoringMode">the monitoring mode.</param>
        /// <param name="samplingInterval">the sampling interval.</param>
        /// <param name="filter">the properties that trigger a notification.</param>
        /// <param name="queueSize">the length of the queue used by the server to buffer values.</param>
        /// <param name="discardOldest">a value indicating whether to discard the oldest entries in the queue when it is full.</param>
        public MonitoredItemBase(string name, NodeId nodeId, uint attributeId = AttributeIds.Value, string indexRange = null, MonitoringMode monitoringMode = MonitoringMode.Reporting, int samplingInterval = -1, MonitoringFilter filter = null, uint queueSize = 0, bool discardOldest = true)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (nodeId == null)
            {
                throw new ArgumentNullException(nameof(nodeId));
            }

            this.Name             = name;
            this.NodeId           = nodeId;
            this.AttributeId      = attributeId;
            this.IndexRange       = indexRange;
            this.MonitoringMode   = monitoringMode;
            this.SamplingInterval = samplingInterval;
            this.Filter           = filter;
            this.QueueSize        = queueSize;
            this.DiscardOldest    = discardOldest;
            this.ClientId         = (uint)Interlocked.Increment(ref lastClientId);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Converts a monitoring filter to text for display.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns>The deadback formatted as a string.</returns>
        private string DeadbandFilterToText(MonitoringFilter filter)
        {
            DataChangeFilter datachangeFilter = filter as DataChangeFilter;

            if (datachangeFilter != null)
            {
                if (datachangeFilter.DeadbandType == (uint)DeadbandType.Absolute)
                {
                    return Utils.Format("{0:##.##}", datachangeFilter.DeadbandValue);
                }

                if (datachangeFilter.DeadbandType == (uint)DeadbandType.Percent)
                {
                    return Utils.Format("{0:##.##}%", datachangeFilter.DeadbandValue);
                }
            }

            return "None";
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Validates the monitoring filter specified by the client.
        /// </summary>
        protected virtual StatusCode ValidateMonitoringFilter(
            ServerSystemContext context,
            NodeHandle handle, 
            uint attributeId,
            double samplingInterval,
            uint queueSize,
            ExtensionObject filter,
            out MonitoringFilter filterToUse,
            out Range range,
            out MonitoringFilterResult result)
        {
            range = null;
            filterToUse = null;
            result = null;

            // nothing to do if the filter is not specified.
            if (ExtensionObject.IsNull(filter))
            {
                return StatusCodes.Good;
            }

            // extension objects wrap any data structure. must check that the client provided the correct structure.
            DataChangeFilter deadbandFilter = ExtensionObject.ToEncodeable(filter) as DataChangeFilter;

            if (deadbandFilter == null)
            {
                AggregateFilter aggregateFilter = ExtensionObject.ToEncodeable(filter) as AggregateFilter;

                if (aggregateFilter == null || attributeId != Attributes.Value)
                {
                    return StatusCodes.BadFilterNotAllowed;
                }

                if (!Server.AggregateManager.IsSupported(aggregateFilter.AggregateType))
                {
                    return StatusCodes.BadAggregateNotSupported;
                }

                ServerAggregateFilter revisedFilter = new ServerAggregateFilter();
                revisedFilter.AggregateType = aggregateFilter.AggregateType;
                revisedFilter.StartTime = aggregateFilter.StartTime;
                revisedFilter.ProcessingInterval = aggregateFilter.ProcessingInterval;
                revisedFilter.AggregateConfiguration = aggregateFilter.AggregateConfiguration;
                revisedFilter.Stepped = false;

                StatusCode error = ReviseAggregateFilter(context, handle, samplingInterval, queueSize, revisedFilter);

                if (StatusCode.IsBad(error))
                {
                    return error;
                }

                AggregateFilterResult aggregateFilterResult = new AggregateFilterResult();
                aggregateFilterResult.RevisedProcessingInterval = aggregateFilter.ProcessingInterval;
                aggregateFilterResult.RevisedStartTime = aggregateFilter.StartTime;
                aggregateFilterResult.RevisedAggregateConfiguration = aggregateFilter.AggregateConfiguration;

                filterToUse = revisedFilter;
                result = aggregateFilterResult;
                return StatusCodes.Good;
            }

            // deadband filters only allowed for variable values.
            if (attributeId != Attributes.Value)
            {
                return StatusCodes.BadFilterNotAllowed;
            }

            BaseVariableState variable = handle.Node as BaseVariableState;

            if (variable == null)
            {
                return StatusCodes.BadFilterNotAllowed;
            }

            // check for status filter.
            if (deadbandFilter.DeadbandType == (uint)DeadbandType.None)
            {
                filterToUse = deadbandFilter;
                return StatusCodes.Good;
            }

            // deadband filters can only be used for numeric values.
            if (!Server.TypeTree.IsTypeOf(variable.DataType, DataTypeIds.Number))
            {
                return StatusCodes.BadFilterNotAllowed;
            }
            
            // nothing more to do for absolute filters.
            if (deadbandFilter.DeadbandType == (uint)DeadbandType.Absolute)
            {
                filterToUse = deadbandFilter;
                return StatusCodes.Good;
            }

            // need to look up the EU range if a percent filter is requested.
            if (deadbandFilter.DeadbandType == (uint)DeadbandType.Percent)
            {
                PropertyState property = handle.Node.FindChild(context, Opc.Ua.BrowseNames.EURange) as PropertyState;

                if (property == null)
                {
                    return StatusCodes.BadFilterNotAllowed;
                }
                
                range = property.Value as Range;
                
                if (range == null)
                {
                    return StatusCodes.BadFilterNotAllowed;
                }

                filterToUse = deadbandFilter;

                return StatusCodes.Good;
            }

            // no other type of filter supported.
            return StatusCodes.BadFilterNotAllowed;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        protected override ServiceResult CreateMonitoredItem(
            ISystemContext context,
            NodeState source,
            uint subscriptionId,
            double publishingInterval,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest itemToCreate,
            ref long globalIdCounter,
            out MonitoringFilterResult filterError,
            out IMonitoredItem monitoredItem)
        {
            filterError   = null;
            monitoredItem = null;

            MemoryTagState tag = source as MemoryTagState;

            // use default behavoir for non-tag sources.
            if (tag == null)
            {
                return(base.CreateMonitoredItem(
                           context,
                           source,
                           subscriptionId,
                           publishingInterval,
                           diagnosticsMasks,
                           timestampsToReturn,
                           itemToCreate,
                           ref globalIdCounter,
                           out filterError,
                           out monitoredItem));
            }

            // validate parameters.
            MonitoringParameters parameters = itemToCreate.RequestedParameters;

            // no filters supported at this time.
            MonitoringFilter filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter);

            if (filter != null)
            {
                return(StatusCodes.BadFilterNotAllowed);
            }

            // index range not supported.
            if (itemToCreate.ItemToMonitor.ParsedIndexRange != NumericRange.Empty)
            {
                return(StatusCodes.BadIndexRangeInvalid);
            }

            // data encoding not supported.
            if (!QualifiedName.IsNull(itemToCreate.ItemToMonitor.DataEncoding))
            {
                return(StatusCodes.BadDataEncodingInvalid);
            }

            // read initial value.
            DataValue initialValue = new DataValue();

            initialValue.Value           = null;
            initialValue.ServerTimestamp = DateTime.UtcNow;
            initialValue.SourceTimestamp = DateTime.MinValue;
            initialValue.StatusCode      = StatusCodes.Good;

            ServiceResult error = source.ReadAttribute(
                context,
                itemToCreate.ItemToMonitor.AttributeId,
                itemToCreate.ItemToMonitor.ParsedIndexRange,
                itemToCreate.ItemToMonitor.DataEncoding,
                initialValue);

            if (ServiceResult.IsBad(error))
            {
                return(error);
            }

            // get the monitored node for the containing buffer.
            MemoryBufferState buffer = tag.Parent as MemoryBufferState;

            if (buffer == null)
            {
                return(StatusCodes.BadInternalError);
            }

            // create a globally unique identifier.
            uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

            // determine the sampling interval.
            double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // create the item.
            MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem(
                context as ServerSystemContext,
                tag,
                subscriptionId,
                monitoredItemId,
                itemToCreate.ItemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                samplingInterval);

            /*
             * // create the item.
             * MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem(
             *  context,
             *  tag,
             *  monitoredItemId,
             *  itemToCreate.ItemToMonitor.AttributeId,
             *  diagnosticsMasks,
             *  timestampsToReturn,
             *  itemToCreate.MonitoringMode,
             *  itemToCreate.RequestedParameters.ClientHandle,
             *  samplingInterval);
             */

            // report the initial value.
            datachangeItem.QueueValue(initialValue, null);

            // update monitored item list.
            monitoredItem = datachangeItem;

            return(ServiceResult.Good);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MonitoredItemCollection"/> class.
        /// Attributes found in the given subscription are added to the collection.
        /// </summary>
        /// <param name="subscription">the instance that will be inspected for [MonitoredItem] attributes.</param>
        public MonitoredItemCollection(ISubscription subscription)
        {
            var typeInfo = subscription.GetType().GetTypeInfo();

            foreach (var propertyInfo in typeInfo.DeclaredProperties)
            {
                var itemAttribute = propertyInfo.GetCustomAttribute <MonitoredItemAttribute>();
                if (itemAttribute == null || string.IsNullOrEmpty(itemAttribute.NodeId))
                {
                    continue;
                }

                MonitoringFilter filter = null;
                if (itemAttribute.AttributeId == AttributeIds.Value && (itemAttribute.DataChangeTrigger != DataChangeTrigger.StatusValue || itemAttribute.DeadbandType != DeadbandType.None))
                {
                    filter = new DataChangeFilter()
                    {
                        Trigger = itemAttribute.DataChangeTrigger, DeadbandType = (uint)itemAttribute.DeadbandType, DeadbandValue = itemAttribute.DeadbandValue
                    };
                }

                var propType = propertyInfo.PropertyType;
                if (propType == typeof(DataValue))
                {
                    this.Add(new DataValueMonitoredItem(
                                 target: subscription,
                                 property: propertyInfo,
                                 nodeId: NodeId.Parse(itemAttribute.NodeId),
                                 indexRange: itemAttribute.IndexRange,
                                 attributeId: itemAttribute.AttributeId,
                                 samplingInterval: itemAttribute.SamplingInterval,
                                 filter: filter,
                                 queueSize: itemAttribute.QueueSize,
                                 discardOldest: itemAttribute.DiscardOldest));
                    continue;
                }

                if (propType == typeof(ObservableQueue <DataValue>))
                {
                    this.Add(new DataValueQueueMonitoredItem(
                                 target: subscription,
                                 property: propertyInfo,
                                 nodeId: NodeId.Parse(itemAttribute.NodeId),
                                 indexRange: itemAttribute.IndexRange,
                                 attributeId: itemAttribute.AttributeId,
                                 samplingInterval: itemAttribute.SamplingInterval,
                                 filter: filter,
                                 queueSize: itemAttribute.QueueSize,
                                 discardOldest: itemAttribute.DiscardOldest));
                    continue;
                }

                if (propType == typeof(BaseEvent) || propType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                {
                    this.Add(new EventMonitoredItem(
                                 target: subscription,
                                 property: propertyInfo,
                                 nodeId: NodeId.Parse(itemAttribute.NodeId),
                                 indexRange: itemAttribute.IndexRange,
                                 attributeId: itemAttribute.AttributeId,
                                 samplingInterval: itemAttribute.SamplingInterval,
                                 filter: new EventFilter()
                    {
                        SelectClauses = EventHelper.GetSelectClauses(propType)
                    },
                                 queueSize: itemAttribute.QueueSize,
                                 discardOldest: itemAttribute.DiscardOldest));
                    continue;
                }

                if (propType.IsConstructedGenericType && propType.GetGenericTypeDefinition() == typeof(ObservableQueue <>))
                {
                    var elemType = propType.GenericTypeArguments[0];
                    if (elemType == typeof(BaseEvent) || elemType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                    {
                        this.Add((MonitoredItemBase)Activator.CreateInstance(
                                     typeof(EventQueueMonitoredItem <>).MakeGenericType(elemType),
                                     subscription,
                                     propertyInfo,
                                     NodeId.Parse(itemAttribute.NodeId),
                                     itemAttribute.AttributeId,
                                     itemAttribute.IndexRange,
                                     MonitoringMode.Reporting,
                                     itemAttribute.SamplingInterval,
                                     new EventFilter()
                        {
                            SelectClauses = EventHelper.GetSelectClauses(elemType)
                        },
                                     itemAttribute.QueueSize,
                                     itemAttribute.DiscardOldest));
                        continue;
                    }
                }

                this.Add(new ValueMonitoredItem(
                             target: subscription,
                             property: propertyInfo,
                             nodeId: NodeId.Parse(itemAttribute.NodeId),
                             indexRange: itemAttribute.IndexRange,
                             attributeId: itemAttribute.AttributeId,
                             samplingInterval: itemAttribute.SamplingInterval,
                             filter: filter,
                             queueSize: itemAttribute.QueueSize,
                             discardOldest: itemAttribute.DiscardOldest));
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Creates a new monitored item and calls StartMonitoring().
        /// </summary>
        public virtual MonitoredItem CreateMonitoredItem(
            OperationContext context,
            uint subscriptionId,
            double publishingInterval,
            TimestampsToReturn timestampsToReturn,
            uint monitoredItemId,
            object managerHandle,
            MonitoredItemCreateRequest itemToCreate,
            Range range,
            double minimumSamplingInterval)
        {
            // use publishing interval as sampling interval.
            double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // limit the sampling interval.
            if (minimumSamplingInterval > 0 && samplingInterval < minimumSamplingInterval)
            {
                samplingInterval = minimumSamplingInterval;
            }

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

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

            // get filter.
            MonitoringFilter filter = null;

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

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

                samplingInterval = 0;
            }

            // check if the queue size was not specified.
            if (queueSize == 0)
            {
                queueSize = 1;
            }

            // create monitored item.
            MonitoredItem monitoredItem = CreateMonitoredItem(
                m_server,
                m_nodeManager,
                managerHandle,
                subscriptionId,
                monitoredItemId,
                context.Session,
                itemToCreate.ItemToMonitor,
                context.DiagnosticsMask,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                filter,
                filter,
                range,
                samplingInterval,
                queueSize,
                itemToCreate.RequestedParameters.DiscardOldest,
                samplingInterval);

            // start sampling.
            StartMonitoring(context, monitoredItem);

            // return item.
            return(monitoredItem);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SubscriptionBase"/> class.
        /// </summary>
        public SubscriptionBase()
        {
            this.application = UaApplication.Current;
            this.application?.Completion.ContinueWith(t => this.stateMachineCts?.Cancel());
            this.logger           = this.application?.LoggerFactory?.CreateLogger(this.GetType());
            this.errors           = new ErrorsContainer <string>(p => this.ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(p)));
            this.progress         = new Progress <CommunicationState>(s => this.State = s);
            this.propertyChanged += this.OnPropertyChanged;
            this.whenSubscribed   = new TaskCompletionSource <bool>();
            this.whenUnsubscribed = new TaskCompletionSource <bool>();
            this.whenUnsubscribed.TrySetResult(true);

            // register the action to be run on the ui thread, if there is one.
            if (SynchronizationContext.Current != null)
            {
                this.actionBlock = new ActionBlock <PublishResponse>(pr => this.OnPublishResponse(pr), new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true, TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
                });
            }
            else
            {
                this.actionBlock = new ActionBlock <PublishResponse>(pr => this.OnPublishResponse(pr), new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true
                });
            }

            // read [Subscription] attribute.
            var typeInfo = this.GetType().GetTypeInfo();
            var sa       = typeInfo.GetCustomAttribute <SubscriptionAttribute>();

            if (sa != null)
            {
                this.endpointUrl        = sa.EndpointUrl;
                this.publishingInterval = sa.PublishingInterval;
                this.keepAliveCount     = sa.KeepAliveCount;
                this.lifetimeCount      = sa.LifetimeCount;
            }

            // read [MonitoredItem] attributes.
            foreach (var propertyInfo in typeInfo.DeclaredProperties)
            {
                var mia = propertyInfo.GetCustomAttribute <MonitoredItemAttribute>();
                if (mia == null || string.IsNullOrEmpty(mia.NodeId))
                {
                    continue;
                }

                MonitoringFilter filter = null;
                if (mia.AttributeId == AttributeIds.Value && (mia.DataChangeTrigger != DataChangeTrigger.StatusValue || mia.DeadbandType != DeadbandType.None))
                {
                    filter = new DataChangeFilter()
                    {
                        Trigger = mia.DataChangeTrigger, DeadbandType = (uint)mia.DeadbandType, DeadbandValue = mia.DeadbandValue
                    };
                }

                var propType = propertyInfo.PropertyType;
                if (propType == typeof(DataValue))
                {
                    this.monitoredItems.Add(new DataValueMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: NodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: filter,
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType == typeof(BaseEvent) || propType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                {
                    this.monitoredItems.Add(new EventMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: NodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: new EventFilter()
                    {
                        SelectClauses = EventHelper.GetSelectClauses(propType)
                    },
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType == typeof(ObservableQueue <DataValue>))
                {
                    this.monitoredItems.Add(new DataValueQueueMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: NodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: filter,
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType.IsConstructedGenericType && propType.GetGenericTypeDefinition() == typeof(ObservableQueue <>))
                {
                    var elemType = propType.GenericTypeArguments[0];
                    if (elemType == typeof(BaseEvent) || elemType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                    {
                        this.monitoredItems.Add((MonitoredItemBase)Activator.CreateInstance(
                                                    typeof(EventQueueMonitoredItem <>).MakeGenericType(elemType),
                                                    this,
                                                    propertyInfo,
                                                    NodeId.Parse(mia.NodeId),
                                                    mia.AttributeId,
                                                    mia.IndexRange,
                                                    MonitoringMode.Reporting,
                                                    mia.SamplingInterval,
                                                    new EventFilter()
                        {
                            SelectClauses = EventHelper.GetSelectClauses(elemType)
                        },
                                                    mia.QueueSize,
                                                    mia.DiscardOldest));
                        continue;
                    }
                }

                this.monitoredItems.Add(new ValueMonitoredItem(
                                            target: this,
                                            property: propertyInfo,
                                            nodeId: NodeId.Parse(mia.NodeId),
                                            indexRange: mia.IndexRange,
                                            attributeId: mia.AttributeId,
                                            samplingInterval: mia.SamplingInterval,
                                            filter: filter,
                                            queueSize: mia.QueueSize,
                                            discardOldest: mia.DiscardOldest));
            }

            this.stateMachineCts  = new CancellationTokenSource();
            this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token));
        }
Ejemplo n.º 22
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);
        }
		/// <summary>
		/// Modifies the attributes for monitored item.
		/// </summary>
		public ServiceResult ModifyAttributes(
            DiagnosticsMasks   diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            uint               clientHandle,
            MonitoringFilter   originalFilter,
            MonitoringFilter   filterToUse,
            Range              range,
            double             samplingInterval,
            uint               queueSize,
            bool               discardOldest)
        {
            lock (m_lock)
			{
                m_diagnosticsMasks   = diagnosticsMasks;
                m_timestampsToReturn = timestampsToReturn;
                m_clientHandle       = clientHandle;
                m_discardOldest      = discardOldest;

                m_originalFilter = originalFilter;
                m_filterToUse    = filterToUse;
                                    
                if (range != null)
                {
                    m_range = range.High - range.Low;
                }

                SetSamplingInterval(samplingInterval);
                m_queueSize = queueSize;

                // check if aggregate filter has been updated.
                ServerAggregateFilter aggregateFilter = filterToUse as ServerAggregateFilter;

                if (filterToUse is ServerAggregateFilter)
                {
                    ServerAggregateFilter existingFilter = filterToUse as ServerAggregateFilter;

                    bool match = existingFilter != null;

                    if (match) if (existingFilter.AggregateType != aggregateFilter.AggregateType) match = false;
                    if (match) if (existingFilter.ProcessingInterval != aggregateFilter.ProcessingInterval) match = false;
                    if (match) if (existingFilter.StartTime != aggregateFilter.StartTime) match = false;
                    if (match) if (!existingFilter.AggregateConfiguration.IsEqual(aggregateFilter.AggregateConfiguration)) match = false;

                    if (!match)
                    {
                        m_calculator = m_server.AggregateManager.CreateCalculator(
                            aggregateFilter.AggregateType,
                            aggregateFilter.StartTime,
                            DateTime.MaxValue,
                            aggregateFilter.ProcessingInterval,
                            aggregateFilter.Stepped,
                            aggregateFilter.AggregateConfiguration);
                    }
                }

                // report change to item state.
                ServerUtils.ReportModifyMonitoredItem(
                    m_nodeId,
                    m_id,
                    m_samplingInterval,
                    m_queueSize,
                    m_discardOldest,
                    m_filterToUse,
                    m_monitoringMode);

                InitializeQueue();

                return null;
            }
        }
Ejemplo n.º 24
0
        public MonitoredItem CreateMonitoredItem(string displayName, string nodeId, int samplingInterval, MonitoringFilter filterValue = null, int queueSize = 1, MonitoringMode mode = MonitoringMode.Reporting)
        {
            var monitoredItem = new MonitoredItem
            {
                DisplayName      = displayName,
                StartNodeId      = new NodeId(nodeId),
                AttributeId      = Attributes.Value,
                MonitoringMode   = mode,
                SamplingInterval = samplingInterval,
                QueueSize        = (uint)queueSize,
                CacheQueueSize   = queueSize,
                DiscardOldest    = true
            };

            if (filterValue == null)
            {
                return(monitoredItem);
            }

            monitoredItem.Filter = filterValue;
            return(monitoredItem);
        }