Example #1
0
 /// <summary>
 /// Does any processing after a monitored item is created.
 /// </summary>
 protected override void OnCreateMonitoredItem(
     ISystemContext systemContext,
     MonitoredItemCreateRequest itemToCreate,
     MonitoredNode monitoredNode,
     DataChangeMonitoredItem monitoredItem)
 {
     // TBD
 }
Example #2
0
        /// <summary>
        /// Creates a set of monitored items.
        /// </summary>
        public MonitoredItem CreateMonitoredItem(
            OperationContext context,
            INodeManager nodeManager,
            object handle,
            uint subscriptionId,
            uint monitoredItemId,
            TimestampsToReturn timestampsToReturn,
            double publishingInterval,
            MonitoredItemCreateRequest itemToCreate,
            EventFilter filter)
        {
            lock (m_lock)
            {
                // calculate sampling interval.
                double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

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

                // limit the queue size.
                uint queueSize = itemToCreate.RequestedParameters.QueueSize;

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

                // create the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem(
                    m_server,
                    nodeManager,
                    handle,
                    subscriptionId,
                    monitoredItemId,
                    context.Session,
                    itemToCreate.ItemToMonitor,
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToCreate.MonitoringMode,
                    itemToCreate.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    samplingInterval,
                    queueSize,
                    itemToCreate.RequestedParameters.DiscardOldest,
                    MinimumSamplingIntervals.Continuous);

                // save the monitored item.
                m_monitoredItems.Add(monitoredItemId, monitoredItem);

                return(monitoredItem);
            }
        }
Example #3
0
        /// <summary>
        /// Updates the object with the results of a create monitored item request.
        /// </summary>
        public void SetCreateResult(
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            int index,
            DiagnosticInfoCollection diagnosticInfos,
            ResponseHeader responseHeader)
        {
            ServiceResult error = null;

            if (StatusCode.IsBad(result.StatusCode))
            {
                error = ClientBase.GetResult(result.StatusCode, index, diagnosticInfos, responseHeader);
            }

            m_status.SetCreateResult(request, result, error);
            m_attributesModified = false;
        }
Example #4
0
        /// <summary>
        /// Creates a monitored item.
        /// </summary>
        public void CreateMonitoredItem(
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // initialize the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.Id             = (uint)Interlocked.Increment(ref m_monitoredItemCounter);
                monitoredItem.ItemToMonitor  = request.ItemToMonitor;
                monitoredItem.MonitoringMode = request.MonitoringMode;
                monitoredItem.Parameters     = request.RequestedParameters;
                monitoredItem.NextScanTime   = 0;

                // use the publishing interval as the default.
                if (monitoredItem.Parameters.SamplingInterval < 0)
                {
                    monitoredItem.Parameters.SamplingInterval = m_publishingInterval;
                }

                // ensure the queue is at least one.
                if (monitoredItem.Parameters.QueueSize == 0)
                {
                    monitoredItem.Parameters.QueueSize = 1;
                }

                result.MonitoredItemId         = monitoredItem.Id;
                result.RevisedQueueSize        = monitoredItem.Parameters.QueueSize;
                result.RevisedSamplingInterval = monitoredItem.Parameters.SamplingInterval;
                result.FilterResult            = new ExtensionObject();

                m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                // start a background thread that scans the items.
                if (m_monitoredItems.Count == 1)
                {
                    ThreadPool.QueueUserWorkItem(OnScanItems);
                }
            }
        }
Example #5
0
 public MonitoredItem CreateMonitoredItem(
     OperationContext context,
     INodeManager nodeManager,
     object handle,
     uint subscriptionId,
     uint monitoredItemId,
     TimestampsToReturn timestampsToReturn,
     MonitoredItemCreateRequest itemToCreate,
     EventFilter filter)
 {
     return(CreateMonitoredItem(
                context,
                nodeManager,
                handle,
                subscriptionId,
                monitoredItemId,
                timestampsToReturn,
                0,
                itemToCreate,
                filter));
 }
        /// <summary>
        /// Updates the object with the results of a create monitored item request.
        /// </summary>
        internal void SetCreateResult(
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            ServiceResult error)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            m_nodeId           = request.ItemToMonitor.NodeId;
            m_attributeId      = request.ItemToMonitor.AttributeId;
            m_indexRange       = request.ItemToMonitor.IndexRange;
            m_encoding         = request.ItemToMonitor.DataEncoding;
            m_monitoringMode   = request.MonitoringMode;
            m_clientHandle     = request.RequestedParameters.ClientHandle;
            m_samplingInterval = request.RequestedParameters.SamplingInterval;
            m_queueSize        = request.RequestedParameters.QueueSize;
            m_discardOldest    = request.RequestedParameters.DiscardOldest;
            m_filter           = null;
            m_error            = error;

            if (request.RequestedParameters.Filter != null)
            {
                m_filter = Utils.Clone(request.RequestedParameters.Filter.Body) as MonitoringFilter;
            }

            if (ServiceResult.IsGood(error))
            {
                m_id = result.MonitoredItemId;
                m_samplingInterval = result.RevisedSamplingInterval;
                m_queueSize        = result.RevisedQueueSize;
            }
        }
Example #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);
        }
        /// <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;
        }
Example #9
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>
        public override void CreateMonitoredItems(
            OperationContext context,
            uint subscriptionId,
            double publishingInterval,
            TimestampsToReturn timestampsToReturn,
            IList <MonitoredItemCreateRequest> itemsToCreate,
            IList <ServiceResult> errors,
            IList <MonitoringFilterResult> filterResults,
            IList <IMonitoredItem> monitoredItems,
            ref long globalIdCounter)
        {
            ServerSystemContext             systemContext  = _defaultSystemContext.Copy(context);
            IDictionary <NodeId, NodeState> operationCache = new NodeIdDictionary <NodeState>();
            List <NodeHandle>     nodesToValidate          = new List <NodeHandle>();
            List <IMonitoredItem> createdItems             = new List <IMonitoredItem>();

            lock (Lock)
            {
                for (int ii = 0; ii < itemsToCreate.Count; ii++)
                {
                    MonitoredItemCreateRequest monitoredItemCreateRequest = itemsToCreate[ii];

                    // skip items that have already been processed.
                    if (monitoredItemCreateRequest.Processed)
                    {
                        continue;
                    }

                    ReadValueId itemToMonitor = monitoredItemCreateRequest.ItemToMonitor;

                    // check for valid handle.
                    NodeHandle handle = GetManagerHandle(systemContext, itemToMonitor.NodeId, operationCache);

                    if (handle == null)
                    {
                        continue;
                    }

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

                    // must validate node in a seperate operation.
                    errors[ii] = StatusCodes.BadNodeIdUnknown;

                    handle.Index = ii;
                    nodesToValidate.Add(handle);
                }

                // check for nothing to do.
                if (nodesToValidate.Count == 0)
                {
                    return;
                }
            }

            // validates the nodes (reads values from the underlying data source if required).
            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                NodeHandle handle = nodesToValidate[ii];

                MonitoringFilterResult filterResult  = null;
                IMonitoredItem         monitoredItem = null;

                lock (Lock)
                {
                    // validate node.
                    NodeState source = ValidateNode(systemContext, handle, operationCache);

                    if (source == null)
                    {
                        continue;
                    }

                    MonitoredItemCreateRequest itemToCreate = itemsToCreate[handle.Index];

                    // create monitored item.
                    errors[handle.Index] = CreateMonitoredItem(
                        systemContext,
                        handle,
                        subscriptionId,
                        publishingInterval,
                        context.DiagnosticsMask,
                        timestampsToReturn,
                        itemToCreate,
                        ref globalIdCounter,
                        out filterResult,
                        out monitoredItem);
                }

                // save any filter error details.
                filterResults[handle.Index] = filterResult;

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

                // save the monitored item.
                monitoredItems[handle.Index] = monitoredItem;
                createdItems.Add(monitoredItem);
            }

            // do any post processing.
            OnCreateMonitoredItemsComplete(systemContext, createdItems);
        }
Example #10
0
        /// <summary>
        /// Updates the object with the results of a create monitored item request.
        /// </summary>
        internal void SetCreateResult(   
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult  result,
            ServiceResult              error)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (result == null)  throw new ArgumentNullException("result");
            
            m_nodeId           = request.ItemToMonitor.NodeId;
            m_attributeId      = request.ItemToMonitor.AttributeId;
            m_indexRange       = request.ItemToMonitor.IndexRange;
            m_encoding         = request.ItemToMonitor.DataEncoding;
            m_monitoringMode   = request.MonitoringMode;
            m_clientHandle     = request.RequestedParameters.ClientHandle;
            m_samplingInterval = request.RequestedParameters.SamplingInterval;
            m_queueSize        = request.RequestedParameters.QueueSize;
            m_discardOldest    = request.RequestedParameters.DiscardOldest;
            m_filter           = null;
            m_error            = error;
            
            if (request.RequestedParameters.Filter != null)
            {        
                m_filter = Utils.Clone(request.RequestedParameters.Filter.Body) as MonitoringFilter;
            }

            if (ServiceResult.IsGood(error))
            {
                m_id               = result.MonitoredItemId;
                m_samplingInterval = result.RevisedSamplingInterval;
                m_queueSize        = result.RevisedQueueSize; 
            }           
        }
 /// <summary>
 /// Does any processing after a monitored item is created.
 /// </summary>
 protected virtual void OnCreateMonitoredItem(
     ISystemContext systemContext,
     MonitoredItemCreateRequest itemToCreate,
     MonitoredNode monitoredNode, 
     DataChangeMonitoredItem monitoredItem)
 {
     // does nothing.
 }
Example #12
0
        /// <summary>
        /// The state machine manages the state of the subscription.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task StateMachineAsync(CancellationToken token = default)
        {
            while (!token.IsCancellationRequested)
            {
                await this.whenSubscribed.Task;

                this.progress.Report(CommunicationState.Opening);

                try
                {
                    if (this.endpointUrl is null)
                    {
                        throw new InvalidOperationException("The endpointUrl field must not be null. Please, use the Subscription attribute properly.");
                    }

                    // get a channel.
                    this.innerChannel = await this.application.GetChannelAsync(this.endpointUrl, token);

                    try
                    {
                        // create the subscription.
                        var subscriptionRequest = new CreateSubscriptionRequest
                        {
                            RequestedPublishingInterval = this.publishingInterval,
                            RequestedMaxKeepAliveCount  = this.keepAliveCount,
                            RequestedLifetimeCount      = Math.Max(this.lifetimeCount, 3 * this.keepAliveCount),
                            PublishingEnabled           = true
                        };
                        var subscriptionResponse = await this.innerChannel.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                        // link up the dataflow blocks
                        var id        = this.subscriptionId = subscriptionResponse.SubscriptionId;
                        var linkToken = this.innerChannel.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id);

                        try
                        {
                            // create the monitored items.
                            var items = this.monitoredItems.ToList();
                            if (items.Count > 0)
                            {
                                var requests = items.Select(m => new MonitoredItemCreateRequest {
                                    ItemToMonitor = new ReadValueId {
                                        NodeId = ExpandedNodeId.ToNodeId(m.NodeId, this.InnerChannel.NamespaceUris), AttributeId = m.AttributeId, IndexRange = m.IndexRange
                                    }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters {
                                        ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter
                                    }
                                }).ToArray();

                                //split requests array to MaxMonitoredItemsPerCall chunks
                                int maxmonitoreditemspercall = 100;
                                MonitoredItemCreateRequest[] requests_chunk;
                                int chunk_size;
                                for (int i_chunk = 0; i_chunk < requests.Length; i_chunk += maxmonitoreditemspercall)
                                {
                                    chunk_size     = Math.Min(maxmonitoreditemspercall, requests.Length - i_chunk);
                                    requests_chunk = new MonitoredItemCreateRequest[chunk_size];
                                    Array.Copy(requests, i_chunk, requests_chunk, 0, chunk_size);

                                    var itemsRequest = new CreateMonitoredItemsRequest
                                    {
                                        SubscriptionId = id,
                                        ItemsToCreate  = requests_chunk,
                                    };
                                    var itemsResponse = await this.innerChannel.CreateMonitoredItemsAsync(itemsRequest);

                                    if (itemsResponse.Results is { } results)
                                    {
                                        for (int i = 0; i < results.Length; i++)
                                        {
                                            var item   = items[i];
                                            var result = results[i];

                                            if (result is null)
                                            {
                                                this.logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. The result is null.");
                                                continue;
                                            }

                                            item.OnCreateResult(result);
                                            if (StatusCode.IsBad(result.StatusCode))
                                            {
                                                this.logger?.LogError($"Error creating MonitoredItem for {item.NodeId}. {StatusCodes.GetDefaultMessage(result.StatusCode)}");
                                            }
                                        }
                                    }
                                }
                            }

                            this.progress.Report(CommunicationState.Opened);

                            // wait here until channel is closing, unsubscribed or token cancelled.
                            try
                            {
                                await Task.WhenAny(
                                    this.WhenChannelClosingAsync(this.innerChannel, token),
                                    this.whenUnsubscribed.Task);
                            }
                            catch
                            {
                            }
                            finally
                            {
                                this.progress.Report(CommunicationState.Closing);
                            }
                        }
                        catch (Exception ex)
                        {
                            this.logger?.LogError($"Error creating MonitoredItems. {ex.Message}");
                            this.progress.Report(CommunicationState.Faulted);
                        }
                        finally
                        {
                            linkToken.Dispose();
                        }

                        if (this.innerChannel.State == CommunicationState.Opened)
                        {
                            try
                            {
                                // delete the subscription.
                                var deleteRequest = new DeleteSubscriptionsRequest
                                {
                                    SubscriptionIds = new uint[] { id }
                                };
                                await this.innerChannel.DeleteSubscriptionsAsync(deleteRequest);
                            }
                            catch (Exception ex)
                            {
                                this.logger?.LogError($"Error deleting subscription. {ex.Message}");
                                await Task.Delay(2000);
                            }
                        }

                        this.progress.Report(CommunicationState.Closed);
                    }
                    catch (Exception ex)
                    {
                        this.logger?.LogError($"Error creating subscription. {ex.Message}");
                        this.progress.Report(CommunicationState.Faulted);
                        await Task.Delay(2000);
                    }
                }
                catch (Exception ex)
                {
                    this.logger?.LogTrace($"Error getting channel. {ex.Message}");
                    this.progress.Report(CommunicationState.Faulted);
                    await Task.Delay(2000);
                }
            }
        }
Example #13
0
        /// <summary>
        /// Adds the MonitoredItems to the request collection.
        /// </summary>
        private void AddMonitoredItems(
            Node node, 
            MonitoredItemCreateRequestCollection itemsToCreate, 
            params uint[] attributeIds)
        {
            if (attributeIds != null)
            {
                for (int ii = 0; ii < attributeIds.Length; ii++)
                {
                    MonitoredItemCreateRequest request = new MonitoredItemCreateRequest();

                    request.ItemToMonitor.NodeId = node.NodeId;
                    request.ItemToMonitor.AttributeId = attributeIds[ii];
                    request.MonitoringMode = MonitoringMode.Reporting;
                    request.RequestedParameters.ClientHandle = ++m_lastClientHandle;
                    request.RequestedParameters.SamplingInterval = 6000000;
                    request.RequestedParameters.QueueSize = 0;
                    request.RequestedParameters.DiscardOldest = true;
                    request.RequestedParameters.Filter = null;
                    request.Handle = node;

                    itemsToCreate.Add(request);
                }
            }
        }
Example #14
0
        /// <summary>
        /// Validates a monitored item create request parameter.
        /// </summary>
        protected static ServiceResult ValidateMonitoredItemCreateRequest(MonitoredItemCreateRequest item)
        {
            // check for null structure.
            if (item == null)
            {
                return new ServiceResult(StatusCodes.BadStructureMissing);
            }
              
            // validate read value id component.
            ServiceResult error = ReadValueId.Validate(item.ItemToMonitor);
            
            if (ServiceResult.IsBad(error))
            {
                return error;
            }

            // check for valid monitoring mode.
            if ((int)item.MonitoringMode < 0 || (int)item.MonitoringMode > (int)MonitoringMode.Reporting)
            {
                return new ServiceResult(StatusCodes.BadMonitoringModeInvalid);
            }
                        
            // check for null structure.
            MonitoringParameters attributes = item.RequestedParameters;
            
            error = ValidateMonitoringAttributes(attributes);

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

            // check that no filter is specified for non-value attributes.
            if (item.ItemToMonitor.AttributeId != Attributes.Value && item.ItemToMonitor.AttributeId != Attributes.EventNotifier)
            {
                if (!ExtensionObject.IsNull(attributes.Filter))
                {
                    return new ServiceResult(StatusCodes.BadFilterNotAllowed);
                }
            }
            else
            {                
                error = ValidateMonitoringFilter(attributes.Filter);

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

            // passed basic validation.
            return null;
        }
Example #15
0
        public static async Task ReadSubscribed(CancellationToken token = default(CancellationToken))
        {
            {
                // setup logger
                var loggerFactory = new LoggerFactory();
                loggerFactory.AddConsole(LogLevel.Information);
                //var logger = loggerFactory?.CreateLogger<Program>();

                // Describe this app.
                var appDescription = new ApplicationDescription()
                {
                    ApplicationName = "DataLoggingConsole",
                    ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:DataLoggingConsole",
                    ApplicationType = ApplicationType.Client,
                };

                // Create a certificate store on disk.

                // Create array of NodeIds to log.
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        // Discover endpoints.
                        var getEndpointsRequest = new GetEndpointsRequest
                        {
                            EndpointUrl = discoveryUrl,
                            ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                        };
                        var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest)
                                                   .ConfigureAwait(false);

                        if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0)
                        {
                            throw new InvalidOperationException($"'{discoveryUrl}' returned no endpoints.");
                        }

                        // Choose the endpoint with highest security level.
                        var remoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

                        // Create a session with the server.
                        var channel = new UaTcpSessionChannel(appDescription, certificateStore,
                                                              async e => GetIUserIdentity(remoteEndpoint).GetAwaiter().GetResult(),
                                                              remoteEndpoint, loggerFactory);
                        try
                        {
                            await channel.OpenAsync();

                            var subscriptionRequest = new CreateSubscriptionRequest
                            {
                                RequestedPublishingInterval = 1000,
                                RequestedMaxKeepAliveCount  = 10,
                                RequestedLifetimeCount      = 30,
                                PublishingEnabled           = true
                            };
                            var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                            var id = subscriptionResponse.SubscriptionId;

                            var itemsToCreate = new MonitoredItemCreateRequest[]
                            {
                                #region MonitoredItems

                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Admin.ProdProcessedCount"), AttributeId = AttributeIds.Value
                                    },                                                                                                               //ProdProcessedCount
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 1, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },


                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[0].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Next batch ID
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 2, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },

                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[1].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Next product ID
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 3, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[2].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                 //Amount of product in next batch
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 4, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[2].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Humidity
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 5, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[3].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Temperature
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 6, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[4].Value"), AttributeId = AttributeIds.Value
                                    },                                                                                                                //Vibration
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 7, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.MachSpeed"), AttributeId = AttributeIds.Value
                                    },                                                                                                       //MachineSpeed
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 8, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value
                                    },                                                                                                          //state
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 9, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                },
                                new MonitoredItemCreateRequest
                                {
                                    ItemToMonitor = new ReadValueId
                                    {
                                        NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value
                                    },                                                                                                          //cmdCtrln
                                    MonitoringMode      = MonitoringMode.Reporting,
                                    RequestedParameters = new MonitoringParameters
                                    {
                                        ClientHandle = 10, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                                    }
                                }

                                #endregion
                            };


                            var itemsRequest = new CreateMonitoredItemsRequest
                            {
                                SubscriptionId = id,
                                ItemsToCreate  = itemsToCreate,
                            };
                            var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                            var subToken = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
                            {
                                // loop through all the data change notifications
                                var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                                foreach (var dcn in dcns)
                                {
                                    foreach (var min in dcn.MonitoredItems)
                                    {
                                        switch (min.ClientHandle)
                                        {
                                        case 1:
                                            prodProc = (int)min.Value.Value;
                                            time     = (DateTime)min.Value.ServerTimestamp;
                                            break;

                                        case 2:
                                            time        = (DateTime)min.Value.ServerTimestamp;
                                            nextBatchID = (float)min.Value.Value;
                                            break;

                                        case 3:
                                            time          = (DateTime)min.Value.ServerTimestamp;
                                            nextProductID = (float)min.Value.Value;
                                            break;

                                        case 4:
                                            time = (DateTime)min.Value.ServerTimestamp;
                                            nextProductAmount = (float)min.Value.Value;
                                            break;

                                        case 5:
                                            time     = (DateTime)min.Value.ServerTimestamp;
                                            humidity = (float)min.Value.Value;
                                            break;

                                        case 6:
                                            time        = (DateTime)min.Value.ServerTimestamp;
                                            temperature = (float)min.Value.Value;
                                            break;

                                        case 7:
                                            time      = (DateTime)min.Value.ServerTimestamp;
                                            vibration = (float)min.Value.Value;
                                            break;

                                        case 8:
                                            time         = (DateTime)min.Value.ServerTimestamp;
                                            machinespeed = (float)min.Value.Value;
                                            break;

                                        case 9:
                                            time  = (DateTime)min.Value.ServerTimestamp;
                                            State = (int)min.Value.Value;
                                            break;

                                        case 10:
                                            cmdctrl = (int)min.Value.Value;
                                            time    = (DateTime)min.Value.ServerTimestamp;
                                            break;
                                        }
                                    }
                                }
                            });

                            while (!token.IsCancellationRequested)
                            {
                                await Task.Delay(500);
                            }
                        }
                        catch
                        {
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    //try
                    //{
                    //    await Task.Delay(cycleTime, token);
                    //}
                    //catch
                    //{
                    //}
                }
            }
        }
Example #16
0
        /// <summary>
        /// Starts monitoring the value of the currently selected item.
        /// </summary>
        public void CreateMonitoredItem(ReferenceDescription node)
        {
            ListOfMonitoredItemCreateRequest itemsToCreate = new ListOfMonitoredItemCreateRequest();

            MonitoredItemCreateRequest itemToCreate = new MonitoredItemCreateRequest();

            itemToCreate.ItemToMonitor = new ReadValueId();
            itemToCreate.ItemToMonitor.NodeId = new NodeId(node.NodeId);
            itemToCreate.ItemToMonitor.AttributeId = Attributes.Value;
            itemToCreate.MonitoringMode = MonitoringMode.Reporting_2;
            itemToCreate.RequestedParameters = new MonitoringParameters();
            itemToCreate.RequestedParameters.ClientHandle = ++m_monitoredItemCount;
            itemToCreate.RequestedParameters.SamplingInterval = 1000;
            itemToCreate.RequestedParameters.QueueSize = 0;
            itemToCreate.RequestedParameters.DiscardOldest = true;
            itemToCreate.RequestedParameters.Filter = new ExtensionObject();

            itemsToCreate.Add(itemToCreate);

            ListOfMonitoredItemCreateResult results;
            ListOfDiagnosticInfo diagnosticInfos;

            m_client.CreateMonitoredItems(
                m_client.CreateRequestHeader(),
                m_subscriptionId,
                TimestampsToReturn.Both_2,
                itemsToCreate,
                out results,
                out diagnosticInfos);

            if (results != null)
            {
                // update the list view.
                MonitoredItemCreateResult result = results[0];

                ListViewItem item = new ListViewItem(itemToCreate.RequestedParameters.ClientHandle.ToString());

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[1].Text = node.DisplayName.Text;

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[2].Text = "<Unknown>";

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[3].Text = String.Format("{0}", result.StatusCode);

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[4].Text = String.Format("{0:HH:mm:ss}", DateTime.Now);

                UpdatesLV.Items.Add(item);

                // save the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.MonitoredItemId = result.MonitoredItemId;
                monitoredItem.ItemToMonitor = itemToCreate.ItemToMonitor;
                monitoredItem.MonitoringMode = itemToCreate.MonitoringMode;
                monitoredItem.Parameters = itemToCreate.RequestedParameters;

                monitoredItem.Parameters.SamplingInterval = result.RevisedSamplingInterval;
                monitoredItem.Parameters.QueueSize = result.RevisedQueueSize;

                m_monitoredItems.Add(itemToCreate.RequestedParameters.ClientHandle, monitoredItem);

                item.Tag = monitoredItem;
            }
        }
Example #17
0
        /// <summary>
        /// Creates a set of monitored items.
        /// </summary>
        public MonitoredItem CreateMonitoredItem(
            OperationContext           context,
            INodeManager               nodeManager,
            object                     handle,
            uint                       subscriptionId,
            uint                       monitoredItemId,
            TimestampsToReturn         timestampsToReturn,
            double                     publishingInterval,
            MonitoredItemCreateRequest itemToCreate,
            EventFilter                filter)
        {
            lock (m_lock)
            {
                // calculate sampling interval.
                double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;
                
                if (samplingInterval < 0)
                {
                    samplingInterval = publishingInterval;
                }
                
                // limit the queue size.
                uint queueSize = itemToCreate.RequestedParameters.QueueSize;

                if (queueSize > m_maxEventQueueSize)
                {
                    queueSize = m_maxEventQueueSize;
                }
                
                // create the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem(
                    m_server,
                    nodeManager,
                    handle,
                    subscriptionId,
                    monitoredItemId,
                    context.Session,
                    itemToCreate.ItemToMonitor,
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToCreate.MonitoringMode,
                    itemToCreate.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    samplingInterval,
                    queueSize,
                    itemToCreate.RequestedParameters.DiscardOldest,
                    MinimumSamplingIntervals.Continuous);

                // save the monitored item.
                m_monitoredItems.Add(monitoredItemId, monitoredItem);

                return monitoredItem;
            }
        }
Example #18
0
 public MonitoredItem CreateMonitoredItem(
     OperationContext           context,
     INodeManager               nodeManager,
     object                     handle,
     uint                       subscriptionId,
     uint                       monitoredItemId,
     TimestampsToReturn         timestampsToReturn,
     MonitoredItemCreateRequest itemToCreate,
     EventFilter                filter)
 {
     return CreateMonitoredItem(
         context,
         nodeManager,
         handle,
         subscriptionId,
         monitoredItemId,
         timestampsToReturn,
         0,
         itemToCreate,
         filter);
 }
        /// <summary>
        /// Updates the object with the results of a create monitored item request.
        /// </summary>
        public void SetCreateResult(            
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult  result,
            int                        index,
            DiagnosticInfoCollection   diagnosticInfos,            
            ResponseHeader             responseHeader)
        {
            ServiceResult error = null;

            if (StatusCode.IsBad(result.StatusCode))
            {
                error = ClientBase.GetResult(result.StatusCode, index, diagnosticInfos, responseHeader);
            }

            m_status.SetCreateResult(request, result, error);
            m_attributesModified = false;
        }
        /// <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;


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

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

            // no filters supported at this time.
            var 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.
            var initialValue = new DataValue {
                Value           = null,
                ServerTimestamp = DateTime.UtcNow,
                SourceTimestamp = DateTime.MinValue,
                StatusCode      = StatusCodes.Good
            };

            var 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.

            if (!(tag.Parent is MemoryBufferState buffer))
            {
                return(StatusCodes.BadInternalError);
            }

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

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

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

            // create the item.
            var datachangeItem = buffer.CreateDataChangeItem(
                context as ServerSystemContext,
                tag,
                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);
        }
Example #21
0
        /// <summary>
        /// Starts monitoring the value of the currently selected item.
        /// </summary>
        public void CreateMonitoredItem(ReferenceDescription node)
        {
            ListOfMonitoredItemCreateRequest itemsToCreate = new ListOfMonitoredItemCreateRequest();

            MonitoredItemCreateRequest itemToCreate = new MonitoredItemCreateRequest();

            itemToCreate.ItemToMonitor                        = new ReadValueId();
            itemToCreate.ItemToMonitor.NodeId                 = new NodeId(node.NodeId);
            itemToCreate.ItemToMonitor.AttributeId            = Attributes.Value;
            itemToCreate.MonitoringMode                       = MonitoringMode.Reporting_2;
            itemToCreate.RequestedParameters                  = new MonitoringParameters();
            itemToCreate.RequestedParameters.ClientHandle     = ++m_monitoredItemCount;
            itemToCreate.RequestedParameters.SamplingInterval = 1000;
            itemToCreate.RequestedParameters.QueueSize        = 0;
            itemToCreate.RequestedParameters.DiscardOldest    = true;
            itemToCreate.RequestedParameters.Filter           = new ExtensionObject();

            itemsToCreate.Add(itemToCreate);

            ListOfMonitoredItemCreateResult results;
            ListOfDiagnosticInfo            diagnosticInfos;

            m_client.CreateMonitoredItems(
                m_client.CreateRequestHeader(),
                m_subscriptionId,
                TimestampsToReturn.Both_2,
                itemsToCreate,
                out results,
                out diagnosticInfos);

            if (results != null)
            {
                // update the list view.
                MonitoredItemCreateResult result = results[0];

                ListViewItem item = new ListViewItem(itemToCreate.RequestedParameters.ClientHandle.ToString());

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[1].Text = node.DisplayName.Text;

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[2].Text = "<Unknown>";

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[3].Text = String.Format("{0}", result.StatusCode);

                item.SubItems.Add(new ListViewItem.ListViewSubItem());
                item.SubItems[4].Text = String.Format("{0:HH:mm:ss}", DateTime.Now);

                UpdatesLV.Items.Add(item);

                // save the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.MonitoredItemId = result.MonitoredItemId;
                monitoredItem.ItemToMonitor   = itemToCreate.ItemToMonitor;
                monitoredItem.MonitoringMode  = itemToCreate.MonitoringMode;
                monitoredItem.Parameters      = itemToCreate.RequestedParameters;

                monitoredItem.Parameters.SamplingInterval = result.RevisedSamplingInterval;
                monitoredItem.Parameters.QueueSize        = result.RevisedQueueSize;

                m_monitoredItems.Add(itemToCreate.RequestedParameters.ClientHandle, monitoredItem);

                item.Tag = monitoredItem;
            }
        }
        /// <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 virtual 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;
            ServiceResult error = null;
            
            // read initial value.
            DataValue initialValue = new DataValue();

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

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

            if (ServiceResult.IsBad(error))
            {
                return error;
            }
            
            // validate parameters.
            MonitoringParameters parameters = itemToCreate.RequestedParameters;

            // validate the data change filter.
            DataChangeFilter filter = null;
            Range range = null;

            if (!ExtensionObject.IsNull(parameters.Filter))
            {
                error = ValidateDataChangeFilter(
                    context,
                    source,
                    itemToCreate.ItemToMonitor.AttributeId,
                    parameters.Filter,
                    out filter,
                    out range);

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

            // create monitored node.
            MonitoredNode monitoredNode = source.Handle as MonitoredNode;

            if (monitoredNode == null)
            {
                source.Handle = monitoredNode = new MonitoredNode(m_server, this, source);
            }

            // 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;
            }

            // check if the variable needs to be sampled.
            bool samplingRequired = false;

            if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = source as BaseVariableState;

                if (variable.MinimumSamplingInterval > 0)
                {
                    samplingInterval = CalculateSamplingInterval(variable, samplingInterval);
                    samplingRequired = true;
                }
            }

            // create the item.
            DataChangeMonitoredItem datachangeItem = monitoredNode.CreateDataChangeItem(
                context,
                monitoredItemId,
                itemToCreate.ItemToMonitor.AttributeId,
                itemToCreate.ItemToMonitor.ParsedIndexRange,
                itemToCreate.ItemToMonitor.DataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                samplingInterval,
                itemToCreate.RequestedParameters.QueueSize,
                itemToCreate.RequestedParameters.DiscardOldest,
                filter,
                range,
                false);

            if (samplingRequired)
            {
                CreateSampledItem(samplingInterval, datachangeItem);
            }

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

            // do any post processing.
            OnCreateMonitoredItem(context, itemToCreate, monitoredNode, datachangeItem);

            // update monitored item list.
            monitoredItem = datachangeItem;

            return ServiceResult.Good;
        }
Example #23
0
        private static async Task TestAsync()
        {
            var discoveryUrl = "opc.tcp://*****:*****@"%LOCALAPPDATA%\Workstation.ConsoleApp\pki")),
                       userIdentity,
                       remoteEndpoint))
            {
                try
                {
                    await session.OpenAsync();
                }
                catch (ServiceResultException ex)
                {
                    if ((uint)ex.HResult == StatusCodes.BadSecurityChecksFailed)
                    {
                        Console.WriteLine("Error connecting to endpoint. Did the server reject our certificate?");
                    }

                    throw ex;
                }

                Console.WriteLine("Step 5 - Browse the server namespace.");
                Console.WriteLine("+ Root");
                BrowseRequest browseRequest = new BrowseRequest
                {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = NodeId.Parse(ObjectIds.RootFolder), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                              } },
                };
                BrowseResponse browseResponse = await session.BrowseAsync(browseRequest);

                foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                {
                    Console.WriteLine("  + {0}: {1}, {2}", rd1.DisplayName, rd1.BrowseName, rd1.NodeClass);
                    browseRequest = new BrowseRequest
                    {
                        NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                      NodeId = ExpandedNodeId.ToNodeId(rd1.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                  } },
                    };
                    browseResponse = await session.BrowseAsync(browseRequest);

                    foreach (var rd2 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                    {
                        Console.WriteLine("    + {0}: {1}, {2}", rd2.DisplayName, rd2.BrowseName, rd2.NodeClass);
                        browseRequest = new BrowseRequest
                        {
                            NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                          NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                      } },
                        };
                        browseResponse = await session.BrowseAsync(browseRequest);

                        foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                        {
                            Console.WriteLine("      + {0}: {1}, {2}", rd3.DisplayName, rd3.BrowseName, rd3.NodeClass);
                        }
                    }
                }

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 6 - Create a subscription.");
                var subscriptionRequest = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 1000,
                    RequestedMaxKeepAliveCount  = 10,
                    RequestedLifetimeCount      = 30,
                    PublishingEnabled           = true
                };
                var subscriptionResponse = await session.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                var id = subscriptionResponse.SubscriptionId;

                Console.WriteLine("Step 7 - Add items to the subscription.");
                var itemsToCreate = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest {
                        ItemToMonitor = new ReadValueId {
                            NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                        }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                            ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                        }
                    }
                };
                var itemsRequest = new CreateMonitoredItemsRequest
                {
                    SubscriptionId = id,
                    ItemsToCreate  = itemsToCreate,
                };
                var itemsResponse = await session.CreateMonitoredItemsAsync(itemsRequest).ConfigureAwait(false);

                Console.WriteLine("Step 8 - Publish the subscription.");
                var publishRequest = new PublishRequest
                {
                    SubscriptionAcknowledgements = new SubscriptionAcknowledgement[0]
                };
                Console.WriteLine("Press any key to delete the subscription...");
                while (!Console.KeyAvailable)
                {
                    var publishResponse = await session.PublishAsync(publishRequest).ConfigureAwait(false);

                    // loop thru all the data change notifications
                    var dcns = publishResponse.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var dcn in dcns)
                    {
                        foreach (var min in dcn.MonitoredItems)
                        {
                            Console.WriteLine($"clientHandle: {min.ClientHandle}; value: {min.Value}");
                        }
                    }

                    publishRequest = new PublishRequest
                    {
                        SubscriptionAcknowledgements = new[] { new SubscriptionAcknowledgement {
                                                                   SequenceNumber = publishResponse.NotificationMessage.SequenceNumber, SubscriptionId = publishResponse.SubscriptionId
                                                               } }
                    };
                }

                Console.ReadKey(true);

                Console.WriteLine("Step 9 - Delete the subscription.");
                var request = new DeleteSubscriptionsRequest
                {
                    SubscriptionIds = new uint[] { id }
                };
                await session.DeleteSubscriptionsAsync(request).ConfigureAwait(false);

                Console.WriteLine("Press any key to close the session...");
                Console.ReadKey(true);
                Console.WriteLine("Step 10 - Close the session.");
                await session.CloseAsync();
            }
        }
Example #24
0
        /// <summary>
        /// Creates a monitored item.
        /// </summary>
        public void CreateMonitoredItem(
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // initialize the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.Id = (uint)Interlocked.Increment(ref m_monitoredItemCounter);
                monitoredItem.ItemToMonitor = request.ItemToMonitor;
                monitoredItem.MonitoringMode = request.MonitoringMode;
                monitoredItem.Parameters = request.RequestedParameters;
                monitoredItem.NextScanTime = 0;

                // use the publishing interval as the default.
                if (monitoredItem.Parameters.SamplingInterval < 0)
                {
                    monitoredItem.Parameters.SamplingInterval = m_publishingInterval;
                }

                // ensure the queue is at least one.
                if (monitoredItem.Parameters.QueueSize == 0)
                {
                    monitoredItem.Parameters.QueueSize = 1;
                }

                result.MonitoredItemId = monitoredItem.Id;
                result.RevisedQueueSize = monitoredItem.Parameters.QueueSize;
                result.RevisedSamplingInterval = monitoredItem.Parameters.SamplingInterval;
                result.FilterResult = new ExtensionObject();

                m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                // start a background thread that scans the items.
                if (m_monitoredItems.Count == 1)
                {
                    ThreadPool.QueueUserWorkItem(OnScanItems);
                }
            }
        }
Example #25
0
        private static async Task TestAsync()
        {
            var loggerFactory = new LoggerFactory();

            loggerFactory.AddDebug(LogLevel.Trace);

            var discoveryUrl = "opc.tcp://localhost:26543"; // Workstation.NodeServer

            //var discoveryUrl = "opc.tcp://localhost:48010"; // UaCppServer - see  http://www.unified-automation.com/
            //var discoveryUrl = "opc.tcp://localhost:16664"; // open62541

            Console.WriteLine("Step 1 - Describe this app.");
            var appDescription = new ApplicationDescription()
            {
                ApplicationName = "MyHomework",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:MyHomework",
                ApplicationType = ApplicationType.Client,
            };

            Console.WriteLine("Step 2 - Create a certificate store.");
            var certificateStore = new DirectoryStore(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Workstation.ConsoleApp", "pki"));

            Console.WriteLine("Step 3 - Create a session with your server.");
            var channel = new UaTcpSessionChannel(
                appDescription,
                certificateStore,
                ShowSignInDialog,
                discoveryUrl,
                loggerFactory: loggerFactory);

            try
            {
                await channel.OpenAsync();

                Console.WriteLine($"  Opened channel with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                Console.WriteLine($"  SecurityPolicyUri: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                Console.WriteLine($"  SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                Console.WriteLine($"  UserIdentity: '{channel.UserIdentity}'.");

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 4 - Browse the server namespace.");
                Console.WriteLine("+ Root");
                BrowseRequest browseRequest = new BrowseRequest
                {
                    NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                  NodeId = NodeId.Parse(ObjectIds.RootFolder), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                              } },
                };
                BrowseResponse browseResponse = await channel.BrowseAsync(browseRequest);

                foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                {
                    Console.WriteLine("  + {0}: {1}, {2}", rd1.DisplayName, rd1.BrowseName, rd1.NodeClass);
                    browseRequest = new BrowseRequest
                    {
                        NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                      NodeId = ExpandedNodeId.ToNodeId(rd1.NodeId, channel.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                  } },
                    };
                    browseResponse = await channel.BrowseAsync(browseRequest);

                    foreach (var rd2 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                    {
                        Console.WriteLine("    + {0}: {1}, {2}", rd2.DisplayName, rd2.BrowseName, rd2.NodeClass);
                        browseRequest = new BrowseRequest
                        {
                            NodesToBrowse = new BrowseDescription[] { new BrowseDescription {
                                                                          NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, channel.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All
                                                                      } },
                        };
                        browseResponse = await channel.BrowseAsync(browseRequest);

                        foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
                        {
                            Console.WriteLine("      + {0}: {1}, {2}", rd3.DisplayName, rd3.BrowseName, rd3.NodeClass);
                        }
                    }
                }

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey(true);

                Console.WriteLine("Step 5 - Create a subscription.");
                var subscriptionRequest = new CreateSubscriptionRequest
                {
                    RequestedPublishingInterval = 1000,
                    RequestedMaxKeepAliveCount  = 10,
                    RequestedLifetimeCount      = 30,
                    PublishingEnabled           = true
                };
                var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                var id = subscriptionResponse.SubscriptionId;

                Console.WriteLine("Step 6 - Add items to the subscription.");
                var itemsToCreate = new MonitoredItemCreateRequest[]
                {
                    new MonitoredItemCreateRequest {
                        ItemToMonitor = new ReadValueId {
                            NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                        }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                            ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                        }
                    }
                };
                var itemsRequest = new CreateMonitoredItemsRequest
                {
                    SubscriptionId = id,
                    ItemsToCreate  = itemsToCreate,
                };
                var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                Console.WriteLine("Step 7 - Subscribe to PublishResponse stream.");
                var token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
                {
                    // loop thru all the data change notifications
                    var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                    foreach (var dcn in dcns)
                    {
                        foreach (var min in dcn.MonitoredItems)
                        {
                            Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                        }
                    }
                });

                Console.WriteLine("Press any key to delete the subscription...");
                while (!Console.KeyAvailable)
                {
                    await Task.Delay(500);
                }

                Console.ReadKey(true);

                Console.WriteLine("Step 8 - Delete the subscription.");
                var request = new DeleteSubscriptionsRequest
                {
                    SubscriptionIds = new uint[] { id }
                };
                await channel.DeleteSubscriptionsAsync(request);

                token.Dispose();

                Console.WriteLine("Press any key to close the session...");
                Console.ReadKey(true);

                Console.WriteLine("Step 9 - Close the session.");
                await channel.CloseAsync();
            }
            catch (ServiceResultException ex)
            {
                if ((uint)ex.HResult == StatusCodes.BadSecurityChecksFailed)
                {
                    Console.WriteLine("Error connecting to endpoint. Did the server reject our certificate?");
                }

                await channel.AbortAsync();

                throw;
            }
        }
Example #26
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);
        }
Example #27
0
        private static async Task ConnectAndPublish(CancellationToken token = default)
        {
            var discoveryUrl = "opc.tcp://localhost:48010"; // UaCppServer - see  http://www.unified-automation.com/

            var appDescription = new ApplicationDescription()
            {
                ApplicationName = "MyHomework",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:MyHomework",
                ApplicationType = ApplicationType.Client,
            };

            var certificateStore = new DirectoryStore(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Workstation.ConsoleApp", "pki"));

            while (!token.IsCancellationRequested)
            {
                var channel = new UaTcpSessionChannel(
                    appDescription,
                    certificateStore,
                    new AnonymousIdentity(),
                    discoveryUrl);
                try
                {
                    await channel.OpenAsync();

                    var subscriptionRequest = new CreateSubscriptionRequest
                    {
                        RequestedPublishingInterval = 1000,
                        RequestedMaxKeepAliveCount  = 10,
                        RequestedLifetimeCount      = 30,
                        PublishingEnabled           = true
                    };
                    var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);

                    var id = subscriptionResponse.SubscriptionId;

                    var itemsToCreate = new MonitoredItemCreateRequest[]
                    {
                        new MonitoredItemCreateRequest {
                            ItemToMonitor = new ReadValueId {
                                NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value
                            }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters {
                                ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true
                            }
                        }
                    };
                    var itemsRequest = new CreateMonitoredItemsRequest
                    {
                        SubscriptionId = id,
                        ItemsToCreate  = itemsToCreate,
                    };
                    var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);

                    var subtoken = channel.Where(pr => pr.SubscriptionId == id).Subscribe(
                        pr =>
                    {
                        var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>();
                        foreach (var dcn in dcns)
                        {
                            foreach (var min in dcn.MonitoredItems)
                            {
                                Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
                            }
                        }
                    },
                        // need to handle error when server closes
                        ex => { });

                    try
                    {
                        Task.WaitAny(new Task[] { channel.Completion }, token);
                    }
                    catch (OperationCanceledException) { }

                    var request = new DeleteSubscriptionsRequest
                    {
                        SubscriptionIds = new uint[] { id }
                    };
                    await channel.DeleteSubscriptionsAsync(request);

                    subtoken.Dispose();

                    await channel.CloseAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error connecting and publishing. {ex.Message}");
                    await channel.AbortAsync();

                    try
                    {
                        await Task.Delay(5000, token);
                    }
                    catch (TaskCanceledException) { }
                }
            }
        }