Example #1
0
        /// <summary>
        /// 读取历史数据
        /// </summary>
        /// <param name="context"></param>
        /// <param name="details"></param>
        /// <param name="timestampsToReturn"></param>
        /// <param name="releaseContinuationPoints"></param>
        /// <param name="nodesToRead"></param>
        /// <param name="results"></param>
        /// <param name="errors"></param>
        public override void HistoryRead(OperationContext context, HistoryReadDetails details, TimestampsToReturn timestampsToReturn, bool releaseContinuationPoints,
                                         IList <HistoryReadValueId> nodesToRead, IList <HistoryReadResult> results, IList <ServiceResult> errors)
        {
            ReadProcessedDetails readDetail = details as ReadProcessedDetails;

            //假设查询历史数据  都是带上时间范围的
            if (readDetail == null || readDetail.StartTime == DateTime.MinValue || readDetail.EndTime == DateTime.MinValue)
            {
                errors[0] = StatusCodes.BadHistoryOperationUnsupported;
                return;
            }
            for (int ii = 0; ii < nodesToRead.Count; ii++)
            {
                int    sss = readDetail.StartTime.Millisecond;
                double res = sss + DateTime.Now.Millisecond;
                //这里  返回的历史数据可以是多种数据类型  请根据实际的业务来选择
                Opc.Ua.KeyValuePair keyValue = new Opc.Ua.KeyValuePair()
                {
                    Key   = new QualifiedName(nodesToRead[ii].NodeId.Identifier.ToString()),
                    Value = res
                };
                results[ii] = new HistoryReadResult()
                {
                    StatusCode  = StatusCodes.Good,
                    HistoryData = new ExtensionObject(keyValue)
                };
                errors[ii] = StatusCodes.Good;
                //切记,如果你已处理完了读取历史数据的操作,请将Processed设为true,这样OPC-UA类库就知道你已经处理过了
                //不需要再进行检查了
                nodesToRead[ii].Processed = true;
            }
        }
        /// <summary>
        /// Saves a continuation point for later use.
        /// </summary>
        private void SaveContinuationPoint(HistoryReadDetails details, HistoryReadValueId nodeToRead, byte[] continuationPoint)
        {
            // clear existing continuation point.
            if (m_nodeToContinue != null)
            {
                HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
                nodesToRead.Add(m_nodeToContinue);

                HistoryReadResultCollection results         = null;
                DiagnosticInfoCollection    diagnosticInfos = null;

                m_session.HistoryRead(
                    null,
                    new ExtensionObject(m_details),
                    TimestampsToReturn.Neither,
                    true,
                    nodesToRead,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
            }

            m_details        = null;
            m_nodeToContinue = null;

            // save new continutation point.
            if (continuationPoint != null && continuationPoint.Length > 0)
            {
                m_details        = details;
                m_nodeToContinue = nodeToRead;
                m_nodeToContinue.ContinuationPoint = continuationPoint;
            }

            // update controls.
            if (m_nodeToContinue != null)
            {
                GoBTN.Visible   = false;
                NextBTN.Visible = true;
                NextBTN.Enabled = true;
                StopBTN.Enabled = true;
            }
            else
            {
                GoBTN.Visible   = true;
                GoBTN.Enabled   = true;
                NextBTN.Visible = false;
                StopBTN.Enabled = false;
            }
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HdaHistoryReadRequest"/> class.
 /// </summary>
 /// <param name="itemId">The item id.</param>
 /// <param name="details">The details.</param>
 /// <param name="nodeToRead">The node to read.</param>
 public HdaHistoryReadRequest(string itemId, HistoryReadDetails details, HistoryReadValueId nodeToRead)
 {
     ItemId       = itemId;
     IndexRange   = nodeToRead.ParsedIndexRange;
     DataEncoding = nodeToRead.DataEncoding;
 }
        /// <summary>
        /// Validates the nodes and reads the values from the underlying source.
        /// </summary>
        protected virtual void HistoryRead(
            ServerSystemContext context,
            HistoryReadDetails details, 
            TimestampsToReturn timestampsToReturn, 
            bool releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult> results, 
            IList<ServiceResult> errors,
            List<NodeHandle> nodesToProcess,
            IDictionary<NodeId, NodeState> cache)
        {
            // check if continuation points are being released.
            if (releaseContinuationPoints)
            {
                HistoryReleaseContinuationPoints(
                    context,
                    nodesToRead,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // check timestamps to return.
            if (timestampsToReturn < TimestampsToReturn.Source || timestampsToReturn > TimestampsToReturn.Neither)
            {
                throw new ServiceResultException(StatusCodes.BadTimestampsToReturnInvalid);
            }

            // handle raw data request.
            ReadRawModifiedDetails readRawModifiedDetails = details as ReadRawModifiedDetails;
            
            if (readRawModifiedDetails != null)
            {
                // at least one must be provided.
                if (readRawModifiedDetails.StartTime == DateTime.MinValue && readRawModifiedDetails.EndTime == DateTime.MinValue)
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                }

                // if one is null the num values must be provided.
                if (readRawModifiedDetails.StartTime == DateTime.MinValue || readRawModifiedDetails.EndTime == DateTime.MinValue)
                {
                    if (readRawModifiedDetails.NumValuesPerNode == 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }

                HistoryReadRawModified(
                    context,
                    readRawModifiedDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // handle processed data request.
            ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails;
            
            if (readProcessedDetails != null)
            {
                // check the list of aggregates.
                if (readProcessedDetails.AggregateType == null || readProcessedDetails.AggregateType.Count != nodesToRead.Count)
                {
                    throw new ServiceResultException(StatusCodes.BadAggregateListMismatch);
                }

                // check start/end time.
                if (readProcessedDetails.StartTime == DateTime.MinValue || readProcessedDetails.EndTime == DateTime.MinValue)
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                }

                HistoryReadProcessed(
                    context,
                    readProcessedDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }
            
            // handle raw data at time request.
            ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails;
            
            if (readAtTimeDetails != null)
            {
                HistoryReadAtTime(
                    context,
                    readAtTimeDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // handle read events request.
            ReadEventDetails readEventDetails = details as ReadEventDetails;

            if (readEventDetails != null)
            {
                // check start/end time and max values.
                if (readEventDetails.NumValuesPerNode == 0)
                {
                    if (readEventDetails.StartTime == DateTime.MinValue || readEventDetails.EndTime == DateTime.MinValue)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }
                else
                {
                    if (readEventDetails.StartTime == DateTime.MinValue && readEventDetails.EndTime == DateTime.MinValue)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }

                // validate the event filter.
                EventFilter.Result result = readEventDetails.Filter.Validate(new FilterContext(m_server.NamespaceUris, m_server.TypeTree, context));

                if (ServiceResult.IsBad(result.Status))
                {
                    throw new ServiceResultException(result.Status);
                }

                // read the event history.
                HistoryReadEvents(
                    context,
                    readEventDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }
        }
        /// <summary>
        /// Reads the history for the specified nodes.
        /// </summary>
        public virtual void HistoryRead(
            OperationContext          context, 
            HistoryReadDetails        details, 
            TimestampsToReturn        timestampsToReturn, 
            bool                      releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult>  results, 
            IList<ServiceResult>      errors)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
            List<NodeHandle> nodesToProcess = new List<NodeHandle>();

            lock (Lock)
            {
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    HistoryReadValueId nodeToRead = nodesToRead[ii];

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

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

                    if (handle == null)
                    {
                        continue;
                    }

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

                    // create an initial result.
                    HistoryReadResult result = results[ii] = new HistoryReadResult();

                    result.HistoryData       = null;
                    result.ContinuationPoint = null;
                    result.StatusCode        = StatusCodes.Good;

                    // check if the node is a area in memory.
                    if (handle.Node == null)
                    {
                        errors[ii] = StatusCodes.BadNodeIdUnknown;

                        // must validate node in a seperate operation
                        handle.Index = ii;
                        nodesToProcess.Add(handle);

                        continue;
                    }

                    errors[ii] = StatusCodes.BadHistoryOperationUnsupported;

                    // check for data history variable.
                    BaseVariableState variable = handle.Node as BaseVariableState;

                    if (variable != null)
                    {
                        if ((variable.AccessLevel & AccessLevels.HistoryRead) != 0)
                        {
                            handle.Index = ii;
                            nodesToProcess.Add(handle);
                            continue;
                        }
                    }

                    // check for event history object.
                    BaseObjectState notifier = handle.Node as BaseObjectState;

                    if (notifier != null)
                    {
                        if ((notifier.EventNotifier & EventNotifiers.HistoryRead) != 0)
                        {
                            handle.Index = ii;
                            nodesToProcess.Add(handle);
                            continue;
                        }
                    }
                }

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

            // validates the nodes (reads values from the underlying data source if required).
            HistoryRead(
                systemContext,
                details,
                timestampsToReturn,
                releaseContinuationPoints,
                nodesToRead,
                results,
                errors,
                nodesToProcess,
                operationCache);
        }
        /// <see cref="INodeManager.HistoryRead" />
        public void HistoryRead(
            OperationContext          context,
            HistoryReadDetails        details, 
            TimestampsToReturn        timestampsToReturn, 
            bool                      releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult>  results, 
            IList<ServiceResult>      errors) 
        {
            if (context == null)     throw new ArgumentNullException("context");
            if (details == null)     throw new ArgumentNullException("details");
            if (nodesToRead == null) throw new ArgumentNullException("nodesToRead");
            if (results == null)     throw new ArgumentNullException("results");
            if (errors == null)      throw new ArgumentNullException("errors");

            ReadRawModifiedDetails readRawModifiedDetails = details as ReadRawModifiedDetails;
            ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails;
            ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails;
            ReadEventDetails readEventDetails = details as ReadEventDetails;

#if LEGACY_CORENODEMANAGER
            Dictionary<object,List<RequestHandle>> historians = new Dictionary<object,List<RequestHandle>>();
#endif

            lock (m_lock)
            {
                #if LEGACY_CORENODEMANAGER 
                Type sourceType = typeof(IDataHistoryProducer);

                if (readEventDetails != null)
                {
                    sourceType = typeof(IEventHistoryProducer);
                }                
                #endif

                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    HistoryReadValueId nodeToRead = nodesToRead[ii];

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

                    if (node == null)
                    {
                        continue;
                    }
                    
                    // owned by this node manager.
                    nodeToRead.Processed = true;
                    
                    #if LEGACY_CORENODEMANAGER 
                    // find the historian.
                    if (!CheckSourceHandle(node, sourceType, ii, historians))
                    {
                        errors[ii] = StatusCodes.BadNotReadable;
                        continue;
                    }
                    #else
                    errors[ii] = StatusCodes.BadNotReadable;
                    #endif
                }
                
                #if LEGACY_CORENODEMANAGER 
                // check if nothing to do.
                if (historians.Count == 0)
                {
                    return;
                }
                #endif
            }
            
            #if LEGACY_CORENODEMANAGER 
            // call the historians.
            foreach (KeyValuePair<object,List<RequestHandle>> entry in historians)
            {
                if (readRawModifiedDetails != null)
                {
                    ((IDataHistoryProducer)entry.Key).ReadRaw(
                        context,
                        readRawModifiedDetails,
                        timestampsToReturn,
                        releaseContinuationPoints,
                        entry.Value,
                        nodesToRead,
                        results,
                        errors);                            
                }

                else if (readAtTimeDetails != null)
                {
                    ((IDataHistoryProducer)entry.Key).ReadAtTime(
                        context,
                        readAtTimeDetails,
                        timestampsToReturn,
                        releaseContinuationPoints,
                        entry.Value,
                        nodesToRead,
                        results,
                        errors);                            
                }

                else if (readProcessedDetails != null)
                {
                    ((IDataHistoryProducer)entry.Key).ReadProcessed(
                        context,
                        readProcessedDetails,
                        timestampsToReturn,
                        releaseContinuationPoints,
                        entry.Value,
                        nodesToRead,
                        results,
                        errors);                            
                }

                else if (readEventDetails != null)
                {
                    ((IEventHistoryProducer)entry.Key).ReadEvents(
                        context,
                        readEventDetails,
                        timestampsToReturn,
                        releaseContinuationPoints,
                        entry.Value,
                        nodesToRead,
                        results,
                        errors);                            
                }
            } 
            #endif
        }
        /// <summary>
        /// Reads the history for a single node which has already been validated.
        /// </summary>
        protected virtual ServiceResult HistoryRead(
            ISystemContext context, 
            NodeState           source,
            HistoryReadDetails  details, 
            TimestampsToReturn  timestampsToReturn, 
            bool                releaseContinuationPoints, 
            HistoryReadValueId  nodesToRead, 
            HistoryReadResult   result)
        {
            // check for variable.
            BaseVariableState variable = source as BaseVariableState;

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

            // check for access.
            lock (Lock)
            {
                if ((variable.AccessLevel & AccessLevels.HistoryRead) == 0)
                {
                    return StatusCodes.BadNotReadable;
                }
            }

            // handle read raw.
            ReadRawModifiedDetails readRawDetails = details as ReadRawModifiedDetails;

            if (readRawDetails != null)
            {
                return HistoryReadRaw(
                    context,
                    variable,
                    readRawDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }

            // handle read processed.
            ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails;

            if (readProcessedDetails != null)
            {
                return HistoryReadProcessed(
                    context,
                    variable,
                    readProcessedDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }

            // handle read processed.
            ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails;

            if (readAtTimeDetails != null)
            {
                return HistoryReadAtTime(
                    context,
                    variable,
                    readAtTimeDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }
 
            return StatusCodes.BadHistoryOperationUnsupported;
        }
        /// <summary>
        /// Reads the history for the specified nodes.
        /// </summary>
        public virtual void HistoryRead(
            OperationContext          context, 
            HistoryReadDetails        details, 
            TimestampsToReturn        timestampsToReturn, 
            bool                      releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult>  results, 
            IList<ServiceResult>      errors)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
            List<ReadWriteOperationState> nodesToValidate = new List<ReadWriteOperationState>();
            List<ReadWriteOperationState> readsToComplete = new List<ReadWriteOperationState>();

            lock (Lock)
            {
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {                    
                    HistoryReadValueId nodeToRead = nodesToRead[ii];

                    // skip items that have already been processed.
                    if (nodeToRead.Processed)
                    {
                        continue;
                    }
                    
                    // check for valid handle.
                    NodeState source = GetManagerHandle(systemContext, nodeToRead.NodeId, operationCache) as NodeState;

                    if (source == null)
                    {
                        continue;
                    }

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

                    // only variables supported.
                    BaseVariableState variable = source as BaseVariableState;

                    if (variable == null)
                    {
                        errors[ii] = StatusCodes.BadHistoryOperationUnsupported;
                        continue;
                    }
                    
                    results[ii] = new HistoryReadResult();
                    
                    ReadWriteOperationState operation = new ReadWriteOperationState();
                    
                    operation.Source = source;
                    operation.Index = ii;

                    // check if the node is ready for reading.
                    if (source.ValidationRequired)
                    {
                        // must validate node in a seperate operation.
                        errors[ii] = StatusCodes.BadNodeIdUnknown;
                        nodesToValidate.Add(operation);                        
                        continue;
                    }

                    // read the data.
                    readsToComplete.Add(operation);
                }

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

                    if (!ValidateNode(systemContext, operation.Source))
                    {
                        continue;
                    }

                    readsToComplete.Add(operation);
                }
            }

            // reads the data without holding onto the lock.
            for (int ii = 0; ii < readsToComplete.Count; ii++)
            {
                ReadWriteOperationState operation = readsToComplete[ii];

                errors[operation.Index] = HistoryRead(
                    systemContext,
                    operation.Source,
                    details,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead[operation.Index],
                    results[operation.Index]);
            }
        }
Example #9
0
        /// <summary>
        /// Saves a continuation point for later use.
        /// </summary>
        private void SaveContinuationPoint(HistoryReadDetails details, HistoryReadValueId nodeToRead, byte[] continuationPoint)
        {
            // clear existing continuation point.
            if (m_nodeToContinue != null)
            {
                HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
                nodesToRead.Add(m_nodeToContinue);
                                
                HistoryReadResultCollection results = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                m_session.HistoryRead(
                    null,
                    new ExtensionObject(m_details),
                    TimestampsToReturn.Neither,
                    true,
                    nodesToRead,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
            }

            m_details = null;
            m_nodeToContinue = null;

            // save new continutation point.
            if (continuationPoint != null && continuationPoint.Length > 0)
            {
                m_details = details;
                m_nodeToContinue = nodeToRead;
                m_nodeToContinue.ContinuationPoint = continuationPoint;
            }

            // update controls.
            if (m_nodeToContinue != null)
            {
                GoBTN.Visible = false;
                NextBTN.Visible = true;
                NextBTN.Enabled = true;
                StopBTN.Enabled = true;
            }
            else
            {
                GoBTN.Visible = true;
                GoBTN.Enabled = true;
                NextBTN.Visible = false;
                StopBTN.Enabled = false;
            }
        }