Opc.Ua.Server.CoreNodeManager.CreateMonitoredItems C# (CSharp) Method

CreateMonitoredItems() public method

Creates a set of monitored items.
public CreateMonitoredItems ( OperationContext context, uint subscriptionId, double publishingInterval, TimestampsToReturn timestampsToReturn, IList itemsToCreate, IList errors, IList filterErrors, IList monitoredItems, long &globalIdCounter ) : void
context OperationContext
subscriptionId uint
publishingInterval double
timestampsToReturn TimestampsToReturn
itemsToCreate IList
errors IList
filterErrors IList
monitoredItems IList
globalIdCounter long
return void
        public void CreateMonitoredItems(
            OperationContext                  context,
            uint                              subscriptionId,
            double                            publishingInterval,
            TimestampsToReturn                timestampsToReturn,
            IList<MonitoredItemCreateRequest> itemsToCreate,
            IList<ServiceResult>              errors,
            IList<MonitoringFilterResult>     filterErrors,
            IList<IMonitoredItem>             monitoredItems,
            ref long                          globalIdCounter)
        {
            if (context == null)         throw new ArgumentNullException("context");
            if (itemsToCreate == null)   throw new ArgumentNullException("itemsToCreate");
            if (errors == null)          throw new ArgumentNullException("errors");
            if (monitoredItems == null)  throw new ArgumentNullException("monitoredItems");

            try
            {
                m_lock.Enter();

                for (int ii = 0; ii < errors.Count; ii++)
                {
                    MonitoredItemCreateRequest itemToCreate = itemsToCreate[ii];

                    // skip items that have already been processed.
                    if (itemToCreate.Processed)
                    {
                        continue;
                    }
                    
                    // look up the node.
                    ILocalNode node = this.GetLocalNode(itemToCreate.ItemToMonitor.NodeId) as ILocalNode;

                    if (node == null)
                    {
                        continue;
                    }

                    // owned by this node manager.
                    itemToCreate.Processed = true;

                    if (!node.SupportsAttribute(itemToCreate.ItemToMonitor.AttributeId))
                    {
                        errors[ii] = StatusCodes.BadAttributeIdInvalid;
                        continue;
                    }

                    // fetch the metadata for the node.
                    NodeMetadata metadata = GetNodeMetadata(context, node, BrowseResultMask.All);

                    if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
                    {
                        if ((metadata.AccessLevel & AccessLevels.CurrentRead) == 0)
                        {
                            errors[ii] = StatusCodes.BadNotReadable;
                            continue;
                        }
                    }

                    // check value rank against index range.
                    if (itemToCreate.ItemToMonitor.ParsedIndexRange != NumericRange.Empty)
                    {
                        int valueRank = metadata.ValueRank;
                        
                        if (itemToCreate.ItemToMonitor.AttributeId != Attributes.Value)
                        {
                            valueRank = Attributes.GetValueRank(itemToCreate.ItemToMonitor.AttributeId);
                        }

                        if (valueRank == ValueRanks.Scalar)
                        {
                            errors[ii] = StatusCodes.BadIndexRangeInvalid;
                            continue;
                        }
                    }

                    bool rangeRequired = false;
                                        
                    // validate the filter against the node/attribute being monitored.
                    errors[ii] = ValidateFilter(
                        metadata,
                        itemToCreate.ItemToMonitor.AttributeId,
                        itemToCreate.RequestedParameters.Filter,
                        out rangeRequired);

                    if (ServiceResult.IsBad(errors[ii]))
                    {
                         continue;
                    }

                    // lookup EU range if required.
                    Range range = null;

                    if (rangeRequired)
                    {
                        errors[ii] = ReadEURange(context, node, out range);
                                                
                        if (ServiceResult.IsBad(errors[ii]))
                        {
                             continue;
                        }
                    }
                    
                    // create a globally unique identifier.
                    uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

                    // limit the sampling rate for non-value attributes.
                    double minimumSamplingInterval = m_defaultMinimumSamplingInterval;

                    if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
                    {
                        // use the MinimumSamplingInterval attribute to limit the sampling rate for value attributes.
                        IVariable variableNode = node as IVariable;
 
                        if (variableNode != null)
                        {
                            minimumSamplingInterval = variableNode.MinimumSamplingInterval;

                            // use the default if the node does not specify one.
                            if (minimumSamplingInterval < 0)
                            {
                                minimumSamplingInterval = m_defaultMinimumSamplingInterval;
                            }
                        }
                    }
                    
                    // create monitored item.
                    MonitoredItem monitoredItem = m_samplingGroupManager.CreateMonitoredItem(
                        context,
                        subscriptionId,
                        publishingInterval,
                        timestampsToReturn,
                        monitoredItemId,
                        node,
                        itemToCreate,
                        range,
                        minimumSamplingInterval);
                    
                    // save monitored item.
                    m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                    // update monitored item list.
                    monitoredItems[ii] = monitoredItem;
                    
                    #if LEGACY_CORENODEMANAGER
                    // subscribe to the variable
                    if (minimumSamplingInterval == 0)
                    { 
                        VariableSource variable = node as VariableSource;
                    
                        if (variable != null)
                        {
                            variable.Subscribe(monitoredItem);
                        }
                    }
                    #endif

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

                    initialValue.ServerTimestamp = DateTime.UtcNow;
                    initialValue.StatusCode      = StatusCodes.BadWaitingForInitialData;
                    
                    ServiceResult error = node.Read(context, itemToCreate.ItemToMonitor.AttributeId, initialValue);

                    if (ServiceResult.IsBad(error))
                    {
                        initialValue.Value = null;
                        initialValue.StatusCode = error.StatusCode;
                    }
                        
                    monitoredItem.QueueValue(initialValue, error);

                    // errors updating the monitoring groups will be reported in notifications.
                    errors[ii] = StatusCodes.Good;
                }
            }
            finally
            {
                m_lock.Exit();
            } 

            // update all groups with any new items.
            m_samplingGroupManager.ApplyChanges();
        }