Esempio n. 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;
            }
        }
Esempio n. 2
0
        public override void Execute(OpcSession session)
        {
            LogExecutionStart(session);
            NormalizeNodeId(session);
            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection
            {
                new HistoryReadValueId {
                    NodeId = OpcUaNodeId
                }
            };

            Opc.Ua.Client.Session uaSession = session.OpcUaClientSession;
            Logger.Debug("About to perform a HistoryRead:");
            Logger.Debug("Details:");
            Logger.Debug($"  Start time:  {details.StartTime}");
            Logger.Debug($"  End time:  {details.EndTime}");
            Logger.Debug($"  Read modified:  {details.IsReadModified}");
            Logger.Debug($"  Values per node:  {details.NumValuesPerNode}");
            Logger.Debug($"  Return bounds:  {details.ReturnBounds}");
            Logger.Debug("Nodes to read:");
            nodesToRead.ForEach(n => Logger.Debug($"  {n}({n.NodeId})"));
            uaSession.HistoryRead(
                null,
                new ExtensionObject(details),
                TimestampsToReturn.Both,
                false,
                nodesToRead,
                out HistoryReadResultCollection results,
                out DiagnosticInfoCollection diagnostics
                );
            Logger.Debug($"HistoryRead got {results.Count} results, {diagnostics.Count} diagnostics.");
            HistoryReadResult hrr      = results[0];
            HistoryData       histData = (HistoryData)ExtensionObject.ToEncodeable(hrr.HistoryData);

            if (StatusCode.IsBad(hrr.StatusCode))
            {
                Logger.Information($"Bad result ({hrr.StatusCode}) reading {OpcNodeId}");
            }
            else
            {
                if (StatusCode.IsGood(hrr.StatusCode))
                {
                    Logger.Debug($"Good result: {histData}, {histData.DataValues.Count} values.");
                }
                if (StatusCode.IsUncertain(hrr.StatusCode))
                {
                    Logger.Information($"Uncertain result: {hrr}");
                }
            }
            foreach (DataValue dv in histData.DataValues)
            {
                Logger.Debug($"  {dv} ({dv.SourceTimestamp})");
                dataValue1 = new DataValue();                 // Acá debería asignarse algo que viene desde «results».
                if (Program.HaveToWriteCsv)
                {
                    WriteDataValueToCsvFile(dv);
                }
            }
        }
Esempio n. 3
0
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            } catch (Exception exception) {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
            }
        }
Esempio n. 5
0
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException("Error Reading History", exception);
            }
        }
Esempio n. 6
0
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error Reading History", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Esempio n. 7
0
        private void ReleaseContinuationPoints()
        {
            ReadRawModifiedDetails details = new ReadRawModifiedDetails();

            HistoryReadValueId nodeToRead = new HistoryReadValueId();

            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();

            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results         = null;
            DiagnosticInfoCollection    diagnosticInfos = null;

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

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            m_result = null;

            ShowResults();
        }
        /// <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);
        }
Esempio n. 9
0
        /// <summary>
        /// Reads the history of a set of items.
        /// </summary>
        public virtual void HistoryRead(
            OperationContext                context,
            ExtensionObject                 historyReadDetails, 
            TimestampsToReturn              timestampsToReturn, 
            bool                            releaseContinuationPoints, 
            HistoryReadValueIdCollection    nodesToRead, 
            out HistoryReadResultCollection results, 
            out DiagnosticInfoCollection    diagnosticInfos)
        {
            // validate history details parameter.
            if (ExtensionObject.IsNull(historyReadDetails))
            {
                throw new ServiceResultException(StatusCodes.BadHistoryOperationInvalid);
            }

            HistoryReadDetails details = historyReadDetails.Body as HistoryReadDetails;

            if (details == null)
            {
                throw new ServiceResultException(StatusCodes.BadHistoryOperationUnsupported);
            }
            
            // create result lists.
            bool diagnosticsExist = false;
            results = new HistoryReadResultCollection(nodesToRead.Count);
            diagnosticInfos = new DiagnosticInfoCollection(nodesToRead.Count);

            // pre-validate items.
            bool validItems = false;

            for (int ii = 0; ii < nodesToRead.Count; ii++)
            {
                HistoryReadResult result = null;
                DiagnosticInfo diagnosticInfo = null;

                // pre-validate and pre-parse parameter.
                ServiceResult error = HistoryReadValueId.Validate(nodesToRead[ii]);
                
                // return error status.
                if (ServiceResult.IsBad(error))
                {
                    nodesToRead[ii].Processed = true;
                    result = new HistoryReadResult();
                    result.StatusCode = error.Code;
                    
                    // add diagnostics if requested.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
                        diagnosticsExist = true;
                    }
                }

                // found at least one valid item.
                else
                {
                    nodesToRead[ii].Processed = false;
                    validItems = true;
                }

                results.Add(result);
                diagnosticInfos.Add(diagnosticInfo);
            } 
            
            // call each node manager.
            if (validItems)
            {
                List<ServiceResult> errors = new List<ServiceResult>(results.Count);

                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    errors.Add(null);
                }

                foreach (INodeManager nodeManager in m_nodeManagers)
                {
                    nodeManager.HistoryRead(
                        context,
                        details,
                        timestampsToReturn,
                        releaseContinuationPoints,
                        nodesToRead,
                        results,
                        errors);
                }
                                
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    HistoryReadResult result = results[ii];
 
                    // set an error code for nodes that were not handled by any node manager.
                    if (!nodesToRead[ii].Processed)
                    {
                        nodesToRead[ii].Processed = true;
                        result = results[ii] = new HistoryReadResult();
                        result.StatusCode = StatusCodes.BadNodeIdUnknown;
                        errors[ii] = results[ii].StatusCode;
                    }
                    
                    // update the diagnostic info and ensure the status code in the result is the same as the error code.
                    if (errors[ii] != null && errors[ii].Code != StatusCodes.Good)
                    {
                        if (result == null)
                        {
                            result = results[ii] = new HistoryReadResult();
                        }

                        result.StatusCode = errors[ii].Code;
                        
                        // add diagnostics if requested.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                            diagnosticsExist = true;
                        }
                    }
                }
            }

            // clear the diagnostics array if no diagnostics requested or no errors occurred.
            UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos);
        }
Esempio n. 10
0
        static void HistoryReadProcessed(Session session)
        {
            // translate browse paths.
            IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder,
                                                        VariableBrowsePaths.ToArray());

            DiagnosticInfoCollection diagnosticInfos;

            NodeId aggregateNodeId = null;

            RequestHeader   rh = null;
            ViewDescription vd = null;
            ReferenceDescriptionCollection references;

            byte[] cp;

            //Get the list of avalilable aggregate functions:
            session.Browse(
                rh,
                vd,
                Opc.Ua.ObjectIds.Server_ServerCapabilities_AggregateFunctions,
                1000,
                BrowseDirection.Forward,
                ReferenceTypeIds.Aggregates,
                false,
                0,
                out cp,
                out references);

            Console.WriteLine("{0} aggregates are detected:", references.Count);

            //Print the list of avalible aggregates:
            int i = 0;

            foreach (ReferenceDescription rd in references)
            {
                i++;
                Console.WriteLine("{0}. {1} {2}", i, rd.BrowseName, rd.NodeId.Identifier.ToString());
            }

            //Select aggregate function:
            Console.WriteLine("\nEnter aggregate number: ");
            string str = Console.ReadLine();

            i = System.Int16.Parse(str);

            if (i > 0 && i <= references.Count)
            {
                aggregateNodeId = ExpandedNodeId.ToNodeId(references[i - 1].NodeId, session.NamespaceUris);
            }

            //Prepare arguments to pass to read processed history
            ReadProcessedDetails readDetails = new ReadProcessedDetails();

            readDetails.StartTime = new DateTime(2008, 1, 1, 12, 0, 0);
            readDetails.EndTime   = new DateTime(2008, 1, 1, 12, 0, 12);

            readDetails.AggregateType = new NodeIdCollection(nodeIds.Count);
            for (int x = 0; x < nodeIds.Count; x++)
            {
                readDetails.AggregateType.Add(aggregateNodeId);
            }

            readDetails.ProcessingInterval = 500; //500 milliseconds

            ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails);

            HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection();

            for (int ii = 0; ii < nodeIds.Count; ii++)
            {
                HistoryReadValueId readValueId = new HistoryReadValueId();
                readValueId.NodeId    = nodeIds[ii].NodeId;
                readValueId.Processed = true;
                idCollection.Add(readValueId);
            }

            HistoryReadResultCollection historyReadResults;

            //Read processed history:
            ResponseHeader responseHeader =
                session.HistoryRead(null, eo, TimestampsToReturn.Both, true,
                                    idCollection, out historyReadResults, out diagnosticInfos);

            //Print results:
            for (int ii = 0; ii < historyReadResults.Count; ii++)
            {
                HistoryReadResult historyReadResult = historyReadResults[ii];
                ServiceResult     result            = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader);

                HistoryData         historyData = null;
                DataValueCollection dataValues  = null;
                if (!(historyReadResult.HistoryData == null))
                {
                    historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData;
                    if (historyData == null)
                    {
                        dataValues = null;
                    }
                    else
                    {
                        dataValues = historyData.DataValues;
                    }
                }

                Console.WriteLine("\nHistoryRead result code for {0}:  {1}", VariableBrowsePaths[ii], result.StatusCode.ToString());

                if (dataValues == null)
                {
                    Console.WriteLine("dataValues == null");
                    continue;
                }

                for (int jj = 0; jj < dataValues.Count; jj++)
                {
                    DataValue dataValue = dataValues[jj];
                    if (dataValue == null)
                    {
                        continue;
                    }

                    // write value.
                    Console.WriteLine("{0}: V={1}, Q={2}, SrvT={3}, SrcT={4}", jj,
                                      dataValue.Value == null ? "null" : dataValue.Value.ToString(),
                                      dataValue.StatusCode.ToString(),
                                      dataValue.ServerTimestamp, dataValue.SourceTimestamp);
                }
            }
        }
        /// <summary>
        /// Reads the raw data for a variable
        /// </summary>
        protected ServiceResult HistoryReadRaw(
            ISystemContext context,
            BaseVariableState source,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            bool releaseContinuationPoints,
            HistoryReadValueId nodeToRead,
            HistoryReadResult result)
        {
            ServerSystemContext serverContext = context as ServerSystemContext;

            HistoryDataReader reader = null;
            HistoryData       data   = new HistoryData();

            if (nodeToRead.ContinuationPoint != null && nodeToRead.ContinuationPoint.Length > 0)
            {
                // restore the continuation point.
                reader = RestoreDataReader(serverContext, nodeToRead.ContinuationPoint);

                if (reader == null)
                {
                    return(StatusCodes.BadContinuationPointInvalid);
                }

                // node id must match previous node id.
                if (reader.VariableId != nodeToRead.NodeId)
                {
                    Utils.SilentDispose(reader);
                    return(StatusCodes.BadContinuationPointInvalid);
                }

                // check if releasing continuation points.
                if (releaseContinuationPoints)
                {
                    Utils.SilentDispose(reader);
                    return(ServiceResult.Good);
                }
            }
            else
            {
                // get the source for the variable.
                IHistoryDataSource datasource = null;
                ServiceResult      error      = GetHistoryDataSource(serverContext, source, out datasource);

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

                // create a reader.
                reader = new HistoryDataReader(nodeToRead.NodeId, datasource);

                // start reading.
                reader.BeginReadRaw(
                    serverContext,
                    details,
                    timestampsToReturn,
                    nodeToRead.ParsedIndexRange,
                    nodeToRead.DataEncoding,
                    data.DataValues);
            }

            // continue reading data until done or max values reached.
            bool complete = reader.NextReadRaw(
                serverContext,
                timestampsToReturn,
                nodeToRead.ParsedIndexRange,
                nodeToRead.DataEncoding,
                data.DataValues);

            // save continuation point.
            if (!complete)
            {
                SaveDataReader(serverContext, reader);
                result.StatusCode = StatusCodes.GoodMoreData;
            }

            // return the dat.
            result.HistoryData = new ExtensionObject(data);

            return(result.StatusCode);
        }
Esempio n. 12
0
        /// <summary>
        /// Reads the history of an HDA item annotations.
        /// </summary>
        private ServiceResult HistoryReadAnnotations(
            ServerSystemContext context,
            ComHdaClient client,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            HistoryReadValueId nodeToRead,
            HdaParsedNodeId parsedNodeId,
            HistoryReadResult result)
        {
            // create the request or load it from a continuation point.
            HdaHistoryReadAnnotationRequest request = null;

            if (nodeToRead.ContinuationPoint == null)
            {
                // create a new request.
                request = new HdaHistoryReadAnnotationRequest(parsedNodeId.RootId, details, nodeToRead);

                // fetch all of the data at once.
                result.StatusCode = client.ReadAnnotationHistory(request);
            }
            else
            {
                request = LoadContinuationPoint(context, nodeToRead.ContinuationPoint) as HdaHistoryReadAnnotationRequest;

                if (request == null)
                {
                    return StatusCodes.BadContinuationPointInvalid;
                }
            }

            // select a subset of the results.
            if (StatusCode.IsGood(result.StatusCode))
            {
                request.Results = new DataValueCollection();
                request.GetHistoryResults(context, nodeToRead, request.Results);
            }

            // fill in the results.
            if (request.Results != null)
            {
                HistoryData data = new HistoryData();
                data.DataValues = request.Results;
                result.HistoryData = new ExtensionObject(data);
            }

            // create a new continuation point.
            if (!request.Completed)
            {
                result.ContinuationPoint = SaveContinuationPoint(context, request);
            }

            return result.StatusCode;
        }
        /// <summary>
        /// Reads the raw data for a variable
        /// </summary>
        protected ServiceResult HistoryReadRaw(
            ISystemContext context, 
            BaseVariableState source, 
            ReadRawModifiedDetails details, 
            TimestampsToReturn timestampsToReturn, 
            bool releaseContinuationPoints, 
            HistoryReadValueId nodeToRead, 
            HistoryReadResult result)
        {
            ServerSystemContext serverContext = context as ServerSystemContext;

            HistoryDataReader reader = null;
            HistoryData data = new HistoryData();

            if (nodeToRead.ContinuationPoint != null && nodeToRead.ContinuationPoint.Length > 0)
            {
                // restore the continuation point.
                reader = RestoreDataReader(serverContext, nodeToRead.ContinuationPoint);

                if (reader == null)
                {
                    return StatusCodes.BadContinuationPointInvalid;
                }

                // node id must match previous node id.
                if (reader.VariableId != nodeToRead.NodeId)
                {
                    Utils.SilentDispose(reader);
                    return StatusCodes.BadContinuationPointInvalid;
                }

                // check if releasing continuation points.
                if (releaseContinuationPoints)
                {
                    Utils.SilentDispose(reader);
                    return ServiceResult.Good;
                }
            }
            else
            {
                // get the source for the variable.
                IHistoryDataSource datasource = null;
                ServiceResult error = GetHistoryDataSource(serverContext, source, out datasource);

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

                // create a reader.
                reader = new HistoryDataReader(nodeToRead.NodeId, datasource);
                
                // start reading.
                reader.BeginReadRaw(
                    serverContext, 
                    details, 
                    timestampsToReturn, 
                    nodeToRead.ParsedIndexRange,
                    nodeToRead.DataEncoding,
                    data.DataValues);
            }
     
            // continue reading data until done or max values reached.
            bool complete = reader.NextReadRaw(
                serverContext, 
                timestampsToReturn, 
                nodeToRead.ParsedIndexRange,
                nodeToRead.DataEncoding,
                data.DataValues);

            // save continuation point.
            if (!complete)
            {
                SaveDataReader(serverContext, reader);
                result.StatusCode = StatusCodes.GoodMoreData;
            }

            // return the dat.
            result.HistoryData = new ExtensionObject(data);
            
            return result.StatusCode;
        }
        /// <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;
        }
Esempio n. 15
0
        private void ReadProcessed()
        {
            ReadProcessedDetails details = new ReadProcessedDetails();
            details.StartTime = StartTimeDP.Value.ToUniversalTime();
            details.EndTime = EndTimeDP.Value.ToUniversalTime();
            details.ProcessingInterval = (double)ResampleIntervalNP.Value;

            NodeId aggregateId = null;

            switch ((string)AggregateCB.SelectedItem)
            {
                case BrowseNames.AggregateFunction_Interpolative: { aggregateId = ObjectIds.AggregateFunction_Interpolative; break; }
                case BrowseNames.AggregateFunction_TimeAverage: { aggregateId = ObjectIds.AggregateFunction_TimeAverage; break; }
                case BrowseNames.AggregateFunction_Average: { aggregateId = ObjectIds.AggregateFunction_Average; break; }
                case BrowseNames.AggregateFunction_Count: { aggregateId = ObjectIds.AggregateFunction_Count; break; }
                case BrowseNames.AggregateFunction_Maximum: { aggregateId = ObjectIds.AggregateFunction_Maximum; break; }
                case BrowseNames.AggregateFunction_Minimum: { aggregateId = ObjectIds.AggregateFunction_Minimum; break; }
                case BrowseNames.AggregateFunction_Total: { aggregateId = ObjectIds.AggregateFunction_Total; break; }
            }

            details.AggregateType.Add(aggregateId);

            HistoryReadValueId nodeToRead = new HistoryReadValueId();
            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.HistoryRead(
                null,
                new ExtensionObject(details),
                TimestampsToReturn.Source,
                false,
                nodesToRead,
                out results,
                out diagnosticInfos);

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw new ServiceResultException(results[0].StatusCode);
            }

            m_result = results[0];

            ShowResults();
        }
Esempio n. 16
0
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Esempio n. 17
0
        private void ReadRaw(bool isReadModified)
        {
            ReadRawModifiedDetails details = new ReadRawModifiedDetails();
            details.StartTime = DateTime.MinValue;
            details.EndTime = DateTime.MinValue;
            details.IsReadModified = isReadModified;
            details.NumValuesPerNode = 0;
            details.ReturnBounds = ReturnBoundsCK.Checked;

            if (StartTimeCK.Checked)
            {
                details.StartTime = StartTimeDP.Value.ToUniversalTime();
            }

            if (EndTimeCK.Checked)
            {
                details.EndTime = EndTimeDP.Value.ToUniversalTime();
            }

            if (MaxReturnValuesCK.Checked)
            {
                details.NumValuesPerNode = (uint)MaxReturnValuesNP.Value;
            }

            HistoryReadValueId nodeToRead = new HistoryReadValueId();
            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.HistoryRead(
                null,
                new ExtensionObject(details),
                TimestampsToReturn.Source,
                false,
                nodesToRead,
                out results,
                out diagnosticInfos);

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
            
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw new ServiceResultException(results[0].StatusCode);
            }

            m_result = results[0];
       
            ShowResults();
        }
Esempio n. 18
0
        private void ReleaseContinuationPoints()
        {
            ReadRawModifiedDetails details = new ReadRawModifiedDetails();

            HistoryReadValueId nodeToRead = new HistoryReadValueId();
            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

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

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            m_result = null;

            ShowResults();
        }
        /// <summary>
        /// Reads history events.
        /// </summary>
        protected override void HistoryReadEvents(
            ServerSystemContext context,
            ReadEventDetails details,
            TimestampsToReturn timestampsToReturn,
            IList <HistoryReadValueId> nodesToRead,
            IList <HistoryReadResult> results,
            IList <ServiceResult> errors,
            List <NodeHandle> nodesToProcess,
            IDictionary <NodeId, NodeState> cache)
        {
            for (int ii = 0; ii < nodesToProcess.Count; ii++)
            {
                NodeHandle         handle     = nodesToProcess[ii];
                HistoryReadValueId nodeToRead = nodesToRead[handle.Index];
                HistoryReadResult  result     = results[handle.Index];

                HistoryReadRequest request = null;

                // load an exising request.
                if (nodeToRead.ContinuationPoint != null)
                {
                    request = LoadContinuationPoint(context, nodeToRead.ContinuationPoint);

                    if (request == null)
                    {
                        errors[handle.Index] = StatusCodes.BadContinuationPointInvalid;
                        continue;
                    }
                }

                // create a new request.
                else
                {
                    request = CreateHistoryReadRequest(
                        context,
                        details,
                        handle,
                        nodeToRead);
                }

                // process events until the max is reached.
                HistoryEvent events = new HistoryEvent();

                while (request.NumValuesPerNode == 0 || events.Events.Count < request.NumValuesPerNode)
                {
                    if (request.Events.Count == 0)
                    {
                        break;
                    }

                    BaseEventState e = null;

                    if (request.TimeFlowsBackward)
                    {
                        e = request.Events.Last.Value;
                        request.Events.RemoveLast();
                    }
                    else
                    {
                        e = request.Events.First.Value;
                        request.Events.RemoveFirst();
                    }

                    events.Events.Add(GetEventFields(request, e));
                }

                errors[handle.Index] = ServiceResult.Good;

                // check if a continuation point is requred.
                if (request.Events.Count > 0)
                {
                    // only set if both end time and start time are specified.
                    if (details.StartTime != DateTime.MinValue && details.EndTime != DateTime.MinValue)
                    {
                        result.ContinuationPoint = SaveContinuationPoint(context, request);
                    }
                }

                // check if no data returned.
                else
                {
                    errors[handle.Index] = StatusCodes.GoodNoData;
                }

                // return the data.
                result.HistoryData = new ExtensionObject(events);
            }
        }
Esempio n. 20
0
        private void ReadRaw(bool isReadModified)
        {
            ReadRawModifiedDetails details = new ReadRawModifiedDetails();

            details.StartTime        = DateTime.MinValue;
            details.EndTime          = DateTime.MinValue;
            details.IsReadModified   = isReadModified;
            details.NumValuesPerNode = 0;
            details.ReturnBounds     = ReturnBoundsCK.Checked;

            if (StartTimeCK.Checked)
            {
                details.StartTime = StartTimeDP.Value.ToUniversalTime();
            }

            if (EndTimeCK.Checked)
            {
                details.EndTime = EndTimeDP.Value.ToUniversalTime();
            }

            if (MaxReturnValuesCK.Checked)
            {
                details.NumValuesPerNode = (uint)MaxReturnValuesNP.Value;
            }

            HistoryReadValueId nodeToRead = new HistoryReadValueId();

            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();

            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results         = null;
            DiagnosticInfoCollection    diagnosticInfos = null;

            m_session.HistoryRead(
                null,
                new ExtensionObject(details),
                TimestampsToReturn.Source,
                false,
                nodesToRead,
                out results,
                out diagnosticInfos);

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw new ServiceResultException(results[0].StatusCode);
            }

            m_result = results[0];

            ShowResults();
        }
Esempio n. 21
0
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException("Error Reading History", exception);
            }
        }
Esempio n. 22
0
        private void ReadProcessed()
        {
            ReadProcessedDetails details = new ReadProcessedDetails();

            details.StartTime          = StartTimeDP.Value.ToUniversalTime();
            details.EndTime            = EndTimeDP.Value.ToUniversalTime();
            details.ProcessingInterval = (double)ResampleIntervalNP.Value;

            NodeId aggregateId = null;

            switch ((string)AggregateCB.SelectedItem)
            {
            case BrowseNames.AggregateFunction_Interpolative: { aggregateId = ObjectIds.AggregateFunction_Interpolative; break; }

            case BrowseNames.AggregateFunction_TimeAverage: { aggregateId = ObjectIds.AggregateFunction_TimeAverage; break; }

            case BrowseNames.AggregateFunction_Average: { aggregateId = ObjectIds.AggregateFunction_Average; break; }

            case BrowseNames.AggregateFunction_Count: { aggregateId = ObjectIds.AggregateFunction_Count; break; }

            case BrowseNames.AggregateFunction_Maximum: { aggregateId = ObjectIds.AggregateFunction_Maximum; break; }

            case BrowseNames.AggregateFunction_Minimum: { aggregateId = ObjectIds.AggregateFunction_Minimum; break; }

            case BrowseNames.AggregateFunction_Total: { aggregateId = ObjectIds.AggregateFunction_Total; break; }
            }

            details.AggregateType.Add(aggregateId);

            HistoryReadValueId nodeToRead = new HistoryReadValueId();

            nodeToRead.NodeId = m_nodeId;

            if (m_result != null)
            {
                nodeToRead.ContinuationPoint = m_result.ContinuationPoint;
            }

            HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();

            nodesToRead.Add(nodeToRead);

            HistoryReadResultCollection results         = null;
            DiagnosticInfoCollection    diagnosticInfos = null;

            m_session.HistoryRead(
                null,
                new ExtensionObject(details),
                TimestampsToReturn.Source,
                false,
                nodesToRead,
                out results,
                out diagnosticInfos);

            Session.ValidateResponse(results, nodesToRead);
            Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw new ServiceResultException(results[0].StatusCode);
            }

            m_result = results[0];

            ShowResults();
        }
Esempio n. 23
0
        /// <summary>
        /// Reads the history of attributes for Bucket Brigade.Int1.
        /// </summary>
        static void HistoryReadAttributes(Session session)
        {
            List <string> VariableBrowsePaths = new List <string>();

            VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:Description");
            VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:DataType");
            VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1/7:ITEMID");

            // translate browse paths.
            IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder,
                                                        VariableBrowsePaths.ToArray());


            DiagnosticInfoCollection diagnosticInfos;

            ReadRawModifiedDetails readDetails = new ReadRawModifiedDetails();

            readDetails.StartTime        = DateTime.MinValue;
            readDetails.EndTime          = DateTime.Now;
            readDetails.IsReadModified   = false;
            readDetails.NumValuesPerNode = 100;
            readDetails.ReturnBounds     = false;

            ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails);

            HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection();

            for (int ii = 0; ii < nodeIds.Count; ii++)
            {
                HistoryReadValueId readValueId = new HistoryReadValueId();
                readValueId.NodeId    = nodeIds[ii].NodeId;
                readValueId.Processed = false;
                idCollection.Add(readValueId);
            }

            HistoryReadResultCollection historyReadResults;

            ResponseHeader responseHeader =
                session.HistoryRead(null, eo, TimestampsToReturn.Both, true,
                                    idCollection, out historyReadResults, out diagnosticInfos);

            // process results.

            for (int ii = 0; ii < historyReadResults.Count; ii++)
            {
                HistoryReadResult   historyReadResult = historyReadResults[ii];
                HistoryData         historyData       = null;
                DataValueCollection dataValues        = null;
                if (historyReadResult.HistoryData != null)
                {
                    historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData;
                    dataValues  = historyData.DataValues;
                }

                ServiceResult result = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader);

                Console.WriteLine("\nHistoryRead result code for {0}:  {1}", VariableBrowsePaths[ii], result.StatusCode.ToString());

                if (StatusCode.IsBad(historyReadResult.StatusCode))
                {
                    continue;
                }

                if (dataValues == null)
                {
                    Console.WriteLine("dataValues == null");
                    continue;
                }

                for (int jj = 0; jj < dataValues.Count; jj++)
                {
                    DataValue dataValue = dataValues[jj];

                    // write value.
                    Console.WriteLine("\t{0}: V={1}", jj, dataValue.Value == null ? "null" : dataValue.Value.ToString());
                    Console.WriteLine("\t Q={0}, SrvT={1}, SrcT={2}\n",
                                      dataValue.StatusCode.ToString(), dataValue.ServerTimestamp, dataValue.SourceTimestamp);
                }
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Reads the history of an HDA item.
        /// </summary>
        private ServiceResult HistoryReadItem(
            ServerSystemContext context,
            ComHdaClient client,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            HistoryReadValueId nodeToRead,
            HdaParsedNodeId parsedNodeId,
            HistoryReadResult result)
        { 
            // create the request or load it from a continuation point.
            HdaHistoryReadRawModifiedRequest request = null;

            if (nodeToRead.ContinuationPoint == null)
            {
                request = new HdaHistoryReadRawModifiedRequest(parsedNodeId.RootId, details, nodeToRead);
            }
            else
            {
                request = LoadContinuationPoint(context, nodeToRead.ContinuationPoint) as HdaHistoryReadRawModifiedRequest;

                if (request == null)
                {
                    return StatusCodes.BadContinuationPointInvalid;
                }
            }

            // fetch the data.
            result.StatusCode = client.ReadHistory(request);

            // fill in the results.
            if (request.Results != null)
            {
                HistoryData data = (request.IsReadModified)?new HistoryModifiedData():new HistoryData();

                if (request.IsReadModified)
                {
                    ((HistoryModifiedData)data).ModificationInfos = request.ModificationInfos;
                }

                data.DataValues = request.Results;
                result.HistoryData = new ExtensionObject(data);
            }

            // create a new continuation point.
            if (!request.Completed)
            {
                result.ContinuationPoint = SaveContinuationPoint(context, request);
            }

            return result.StatusCode;
        }
Esempio n. 25
0
        /// <summary>
        /// Reads the history of values for a set of variables at given time.
        /// </summary>
        static void HistoryReadAtTime(Session session)
        {
            // translate browse paths.
            IList <NodeOfInterest> nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder,
                                                        VariableBrowsePaths.ToArray());


            DiagnosticInfoCollection diagnosticInfos;

            ReadAtTimeDetails readDetails = new ReadAtTimeDetails();

            readDetails.ReqTimes = new DateTimeCollection();

            for (int jj = 0; jj < 10; jj++)
            {
                readDetails.ReqTimes.Add(new DateTime(2008, 01, 01, 12, 0, jj));
                readDetails.ReqTimes.Add(new DateTime(2008, 01, 01, 12, 0, jj, (int)500));
            }

            ExtensionObject eo = new ExtensionObject(readDetails.TypeId, readDetails);

            HistoryReadValueIdCollection idCollection = new HistoryReadValueIdCollection();

            for (int ii = 0; ii < nodeIds.Count; ii++)
            {
                HistoryReadValueId readValueId = new HistoryReadValueId();
                readValueId.NodeId    = nodeIds[ii].NodeId;
                readValueId.Processed = false;
                idCollection.Add(readValueId);
            }

            HistoryReadResultCollection historyReadResults;

            ResponseHeader responseHeader =
                session.HistoryRead(null, eo, TimestampsToReturn.Both, true,
                                    idCollection, out historyReadResults, out diagnosticInfos);

            // process results.

            for (int ii = 0; ii < historyReadResults.Count; ii++)
            {
                HistoryReadResult   historyReadResult = historyReadResults[ii];
                HistoryData         historyData       = null;
                DataValueCollection dataValues        = null;
                if (historyReadResult.HistoryData != null)
                {
                    historyData = ExtensionObject.ToEncodeable(historyReadResult.HistoryData) as HistoryData;
                    dataValues  = historyData.DataValues;
                }

                ServiceResult result = Session.GetResult(historyReadResult.StatusCode, ii, diagnosticInfos, responseHeader);
                Console.WriteLine("HistoryRead result code for {0}:  {1}", VariableBrowsePaths[ii], result.StatusCode.ToString());

                if (StatusCode.IsBad(historyReadResult.StatusCode))
                {
                    continue;
                }

                if (dataValues == null)
                {
                    Console.WriteLine("dataValues == null");
                    continue;
                }

                for (int jj = 0; jj < dataValues.Count; jj++)
                {
                    DataValue dataValue = dataValues[jj];

                    // write value.
                    Console.WriteLine("{0}: V={1}, Q={2}, SrvT={3}, SrcT={4}", jj,
                                      dataValue.Value == null ? "null" : dataValue.Value.ToString(),
                                      dataValue.StatusCode.ToString(),
                                      dataValue.ServerTimestamp, dataValue.SourceTimestamp);
                }
            }
        }
        /// <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]);
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Processes the results of a history read operation.
        /// </summary>
        private int ProcessReadResults(
            Session session,
            HistoryReadResult result, 
            uint attributeId,
            List<DaValue> values,
            List<ModificationInfo> modificationInfos)
        {
            // check for item level error.
            int error = MapReadStatusToErrorCode(result.StatusCode);

            if (error < 0)
            {
                return error;
            }

            // check if no data found.
            if (result.StatusCode == StatusCodes.GoodNoData)
            {
                return ResultIds.S_NODATA;
            }

            // extract the history data.
            HistoryData data = ExtensionObject.ToEncodeable(result.HistoryData) as HistoryData;

            if (data == null)
            {
                return ResultIds.E_FAIL;
            }
            
            // check for modified data.
            HistoryModifiedData modifiedData = data as HistoryModifiedData;

            if (modificationInfos != null)
            {
                if (modifiedData == null)
                {
                    return ResultIds.E_FAIL;
                }

                modificationInfos.AddRange(modifiedData.ModificationInfos);
            }
            
            // convert the values.
            for (int ii = 0; ii < data.DataValues.Count; ii++)
            {
                DaValue value = GetAttributeValue(session, m_mapper, attributeId, data.DataValues[ii]);
                values.Add(value);

                // ensure matching modification info record exists.
                if (modificationInfos != null)
                {
                    if (modifiedData == null || ii >= modifiedData.ModificationInfos.Count)
                    {
                        modificationInfos.Add(new ModificationInfo());
                    }
                    else
                    {
                        modificationInfos.Add(modifiedData.ModificationInfos[ii]);
                    }
                }
            }

            // check if no data found.
            if (result.StatusCode == StatusCodes.GoodMoreData)
            {
                return ResultIds.S_MOREDATA;
            }

            return ResultIds.S_OK;
        }
 /// <summary>
 /// Reads the history for the variable value.
 /// </summary>
 protected virtual ServiceResult HistoryReadAtTime(
     ISystemContext context, 
     BaseVariableState      source,
     ReadAtTimeDetails      details, 
     TimestampsToReturn     timestampsToReturn, 
     bool                   releaseContinuationPoints, 
     HistoryReadValueId     nodeToRead, 
     HistoryReadResult      result)
 {
     return StatusCodes.BadHistoryOperationUnsupported;
 }
        private void GoBTN_Click(object sender, EventArgs e)
        {
            try
            {
                m_index = 0;
                ResultsLV.Items.Clear();
                m_result = null;

                Read();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
            }
        }