/// <summary> /// Validates a read value id parameter. /// </summary> public static ServiceResult Validate(HistoryReadValueId valueId) { // check for null structure. if (valueId == null) { return(StatusCodes.BadStructureMissing); } // null node ids are always invalid. if (NodeId.IsNull(valueId.NodeId)) { return(StatusCodes.BadNodeIdInvalid); } // initialize as empty. valueId.ParsedIndexRange = NumericRange.Empty; // parse the index range if specified. if (!String.IsNullOrEmpty(valueId.IndexRange)) { try { valueId.ParsedIndexRange = NumericRange.Parse(valueId.IndexRange); } catch (Exception e) { return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty)); } } else { valueId.ParsedIndexRange = NumericRange.Empty; } // passed basic validation. return(null); }
/// <summary> /// Validates a read value id parameter. /// </summary> public static ServiceResult Validate(HistoryReadValueId valueId) { // check for null structure. if (valueId == null) { return StatusCodes.BadStructureMissing; } // null node ids are always invalid. if (NodeId.IsNull(valueId.NodeId)) { return StatusCodes.BadNodeIdInvalid; } // initialize as empty. valueId.ParsedIndexRange = NumericRange.Empty; // parse the index range if specified. if (!String.IsNullOrEmpty(valueId.IndexRange)) { try { valueId.ParsedIndexRange = NumericRange.Parse(valueId.IndexRange); } catch (Exception e) { return ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty); } } else { valueId.ParsedIndexRange = NumericRange.Empty; } // passed basic validation. return null; }
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(); }
/// <summary> /// Reads the first date in the archive (truncates milliseconds and converts to local). /// </summary> private DateTime ReadFirstDate() { // use the historical data configuration if available. if (m_configuration != null) { if (StatusCode.IsGood(m_configuration.StartOfOnlineArchive.StatusCode)) { return m_configuration.StartOfOnlineArchive.Value.ToLocalTime(); } if (StatusCode.IsGood(m_configuration.StartOfArchive.StatusCode)) { return m_configuration.StartOfArchive.Value.ToLocalTime(); } } // do it the hard way (may take a long time with some servers). ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime = new DateTime(1970, 1, 1); details.EndTime = DateTime.MinValue; details.NumValuesPerNode = 1; details.IsReadModified = false; details.ReturnBounds = false; HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; 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)) { return DateTime.MinValue; } HistoryData data = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; if (results == null) { return DateTime.MinValue; } DateTime startTime = data.DataValues[0].SourceTimestamp; if (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Source, true, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); } startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, startTime.Minute, startTime.Second, 0, DateTimeKind.Utc); startTime = startTime.ToLocalTime(); return startTime; }
private DateTime ReadFirstDate() { ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime = new DateTime(1970, 1, 1); details.EndTime = DateTime.UtcNow.AddDays(1); details.IsReadModified = false; details.NumValuesPerNode = 1; details.ReturnBounds = false; HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; 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)) { return DateTime.MinValue; } HistoryData data = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; if (results == null) { return DateTime.MinValue; } DateTime startTime = data.DataValues[0].SourceTimestamp; if (results[0].ContinuationPoint != null) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Source, true, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); } return startTime; }
/// <summary> /// Starts a new read operation. /// </summary> private void ReadFirst() { ResultsLV.ClearEventHistory(); // set up the request parameters. ReadEventDetails details = new ReadEventDetails(); details.StartTime = DateTime.MinValue; details.EndTime = DateTime.MinValue; details.NumValuesPerNode = 0; details.Filter = m_filter.GetFilter(); if (StartTimeCK.Checked) { details.StartTime = StartTimeDP.Value.ToUniversalTime(); } if (EndTimeCK.Checked) { details.EndTime = EndTimeDP.Value.ToUniversalTime(); } if (MaxReturnValuesCK.Checked) { details.NumValuesPerNode = (uint)MaxReturnValuesNP.Value; } // read the events from the server. HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_areaId; ReadNext(details, nodeToRead); }
/// <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; }
private void ReadHistory(DateTime StartTime, DateTime EndTime, NodeId node, uint HCount, String DriverName) { ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime = DateTime.MinValue; details.EndTime = DateTime.MinValue; details.IsReadModified = false; details.NumValuesPerNode = HCount; details.ReturnBounds = true; details.StartTime = StartTime.ToUniversalTime(); details.EndTime = EndTime.ToUniversalTime(); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = node; 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); for (int i = 0; i < results.Count; i++) { HistoryData hd_results = ExtensionObject.ToEncodeable(results[i].HistoryData) as HistoryData; if (hd_results != null) { for (int ii = 0; ii < hd_results.DataValues.Count; ii++) { StatusCode status = hd_results.DataValues[ii].StatusCode; string timestamp = hd_results.DataValues[ii].SourceTimestamp.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"); string value = Utils.Format("{0}", hd_results.DataValues[ii].WrappedValue); string quality = Utils.Format("{0}", (StatusCode)status.CodeBits); string historyInfo = Utils.Format("{0:X2}", (int)status.AggregateBits); Log("UID:" + S80(node.ToString()) + " \tTime: " + timestamp + "\tValue: " + value); // + ", Q:" + quality + ", histInfo:" + historyInfo); dr = dt.NewRow(); dr["UID"] = node.ToString(); dr["SourceTime"] = timestamp; dr["Value"] = value; dr["Name"] = DriverName; dt.Rows.Add(dr); } } } }
/// <summary> /// Releases any continuation points. /// </summary> private void ReleaseContinuationPoints() { if (m_details != null) { HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); nodesToRead.Add(m_nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(m_details), TimestampsToReturn.Neither, true, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); NextBTN.Visible = false; StopBTN.Enabled = false; GoBTN.Visible = true; m_details = null; m_nodeToRead = null; } }
/// <summary> /// Fetches the recent history. /// </summary> private void ReadHistory(ReadEventDetails details, NodeId areaId) { HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = areaId; nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Neither, false, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); if (StatusCode.IsBad(results[0].StatusCode)) { throw new ServiceResultException(results[0].StatusCode); } HistoryEvent events = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryEvent; AddEventHistory(events); // release continuation points. if (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Neither, true, nodesToRead, out results, out diagnosticInfos); } }
/// <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> /// Creates a new history request. /// </summary> private DataValue RowToDataValue( ServerSystemContext context, HistoryReadValueId nodeToRead, DataRowView row, bool applyIndexRangeOrEncoding) { DataValue value = (DataValue)row[2]; // apply any index range or encoding. if (applyIndexRangeOrEncoding) { object rawValue = value.Value; ServiceResult result = BaseVariableState.ApplyIndexRangeAndDataEncoding(context, nodeToRead.ParsedIndexRange, nodeToRead.DataEncoding, ref rawValue); if (ServiceResult.IsBad(result)) { value.Value = rawValue; } else { value.Value = null; value.StatusCode = result.StatusCode; } } return value; }
/// <summary> /// Reads the initial value for a monitored item. /// </summary> /// <param name="context">The context.</param> /// <param name="handle">The item handle.</param> /// <param name="monitoredItem">The monitored item.</param> protected override void ReadInitialValue( ServerSystemContext context, NodeHandle handle, MonitoredItem monitoredItem) { ArchiveItemState item = handle.Node as ArchiveItemState; if (item == null || monitoredItem.AttributeId != Attributes.Value) { base.ReadInitialValue(context, handle, monitoredItem); return; } AggregateFilter filter = monitoredItem.Filter as AggregateFilter; if (filter == null || filter.StartTime >= DateTime.UtcNow.AddMilliseconds(-filter.ProcessingInterval)) { base.ReadInitialValue(context, handle, monitoredItem); return; } ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime = filter.StartTime; details.EndTime = DateTime.UtcNow; details.ReturnBounds = true; details.IsReadModified = false; details.NumValuesPerNode = 0; HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = handle.NodeId; nodeToRead.ParsedIndexRange = NumericRange.Empty; try { HistoryReadRequest request = CreateHistoryReadRequest( context, details, handle, nodeToRead); while (request.Values.Count > 0) { if (request.Values.Count == 0) { break; } DataValue value = request.Values.First.Value; request.Values.RemoveFirst(); monitoredItem.QueueValue(value, null); } } catch (Exception e) { ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Unexpected error fetching initial values."); monitoredItem.QueueValue(null, error); } }
/// <summary> /// Creates a new history request. /// </summary> private HistoryReadRequest CreateHistoryReadRequest( ServerSystemContext context, ReadAtTimeDetails details, NodeHandle handle, HistoryReadValueId nodeToRead) { bool applyIndexRangeOrEncoding = (nodeToRead.ParsedIndexRange != NumericRange.Empty || !QualifiedName.IsNull(nodeToRead.DataEncoding)); ArchiveItemState item = handle.Node as ArchiveItemState; if (item == null) { throw new ServiceResultException(StatusCodes.BadNotSupported); } item.ReloadFromSource(context); // find the start and end times. DateTime startTime = DateTime.MaxValue; DateTime endTime = DateTime.MinValue; for (int ii = 0; ii < details.ReqTimes.Count; ii++) { if (startTime > details.ReqTimes[ii]) { startTime = details.ReqTimes[ii]; } if (endTime < details.ReqTimes[ii]) { endTime = details.ReqTimes[ii]; } } DataView view = item.ReadHistory(startTime, endTime, false); LinkedList<DataValue> values = new LinkedList<DataValue>(); for (int ii = 0; ii < details.ReqTimes.Count; ii++) { bool dataBeforeIgnored = false; bool dataAfterIgnored = false; // find the value at the time. int index = item.FindValueAtOrBefore(view, details.ReqTimes[ii], !details.UseSimpleBounds, out dataBeforeIgnored); if (index < 0) { values.AddLast(new DataValue(StatusCodes.BadNoData, details.ReqTimes[ii])); continue; } // nothing more to do if a raw value exists. if ((DateTime)view[index].Row[0] == details.ReqTimes[ii]) { values.AddLast((DataValue)view[index].Row[2]); continue; } DataValue before = (DataValue)view[index].Row[2]; DataValue value; // find the value after the time. int afterIndex = item.FindValueAfter(view, index, !details.UseSimpleBounds, out dataAfterIgnored); if (afterIndex < 0) { // use stepped interpolation if no end bound exists. value = AggregateCalculator.SteppedInterpolate(details.ReqTimes[ii], before); if (StatusCode.IsNotBad(value.StatusCode) && dataBeforeIgnored) { value.StatusCode = value.StatusCode.SetCodeBits(StatusCodes.UncertainDataSubNormal); } values.AddLast(value); continue; } // use stepped or slopped interpolation depending on the value. if (item.ArchiveItem.Stepped) { value = AggregateCalculator.SteppedInterpolate(details.ReqTimes[ii], before); if (StatusCode.IsNotBad(value.StatusCode) && dataBeforeIgnored) { value.StatusCode = value.StatusCode.SetCodeBits(StatusCodes.UncertainDataSubNormal); } } else { value = AggregateCalculator.SlopedInterpolate(details.ReqTimes[ii], before, (DataValue)view[afterIndex].Row[2]); if (StatusCode.IsNotBad(value.StatusCode) && (dataBeforeIgnored || dataAfterIgnored)) { value.StatusCode = value.StatusCode.SetCodeBits(StatusCodes.UncertainDataSubNormal); } } values.AddLast(value); } HistoryReadRequest request = new HistoryReadRequest(); request.Values = values; request.NumValuesPerNode = 0; request.Filter = null; return request; }
/// <summary> /// Creates a new history request. /// </summary> private HistoryReadRequest CreateHistoryReadRequest( ServerSystemContext context, ReadProcessedDetails details, NodeHandle handle, HistoryReadValueId nodeToRead, NodeId aggregateId) { bool applyIndexRangeOrEncoding = (nodeToRead.ParsedIndexRange != NumericRange.Empty || !QualifiedName.IsNull(nodeToRead.DataEncoding)); bool timeFlowsBackward = (details.EndTime < details.StartTime); ArchiveItemState item = handle.Node as ArchiveItemState; if (item == null) { throw new ServiceResultException(StatusCodes.BadNotSupported); } item.ReloadFromSource(context); LinkedList<DataValue> values = new LinkedList<DataValue>(); // read history. DataView view = item.ReadHistory(details.StartTime, details.EndTime, false); int ii = (timeFlowsBackward) ? view.Count - 1 : 0; // choose the aggregate configuration. AggregateConfiguration configuration = (AggregateConfiguration)details.AggregateConfiguration.Clone(); ReviseAggregateConfiguration(context, item, configuration); // create the aggregate calculator. IAggregateCalculator calculator = Server.AggregateManager.CreateCalculator( aggregateId, details.StartTime, details.EndTime, details.ProcessingInterval, item.ArchiveItem.Stepped, configuration); while (ii >= 0 && ii < view.Count) { try { DataValue value = (DataValue)view[ii].Row[2]; calculator.QueueRawValue(value); // queue any processed values. QueueProcessedValues( context, calculator, nodeToRead.ParsedIndexRange, nodeToRead.DataEncoding, applyIndexRangeOrEncoding, false, values); } finally { if (timeFlowsBackward) { ii--; } else { ii++; } } } // queue any processed values beyond the end of the data. QueueProcessedValues( context, calculator, nodeToRead.ParsedIndexRange, nodeToRead.DataEncoding, applyIndexRangeOrEncoding, true, values); HistoryReadRequest request = new HistoryReadRequest(); request.Values = values; request.NumValuesPerNode = 0; request.Filter = null; return request; }
/// <summary> /// Creates a new history request. /// </summary> private HistoryReadRequest CreateHistoryReadRequest( ServerSystemContext context, ReadRawModifiedDetails details, NodeHandle handle, HistoryReadValueId nodeToRead) { bool sizeLimited = (details.StartTime == DateTime.MinValue || details.EndTime == DateTime.MinValue); bool applyIndexRangeOrEncoding = (nodeToRead.ParsedIndexRange != NumericRange.Empty || !QualifiedName.IsNull(nodeToRead.DataEncoding)); bool returnBounds = !details.IsReadModified && details.ReturnBounds; bool timeFlowsBackward = (details.StartTime == DateTime.MinValue) || (details.EndTime != DateTime.MinValue && details.EndTime < details.StartTime); // find the archive item. ArchiveItemState item = Reload(context, handle); if (item == null) { throw new ServiceResultException(StatusCodes.BadNotSupported); } LinkedList<DataValue> values = new LinkedList<DataValue>(); LinkedList<ModificationInfo> modificationInfos = null; if (details.IsReadModified) { modificationInfos = new LinkedList<ModificationInfo>(); } // read history. DataView view = item.ReadHistory(details.StartTime, details.EndTime, details.IsReadModified, handle.Node.BrowseName); int startBound = -1; int endBound = -1; int ii = (timeFlowsBackward)?view.Count-1:0; while (ii >= 0 && ii < view.Count) { try { DateTime timestamp = (DateTime)view[ii].Row[0]; // check if looking for start of data. if (values.Count == 0) { if (timeFlowsBackward) { if ((details.StartTime != DateTime.MinValue && timestamp >= details.StartTime) || (details.StartTime == DateTime.MinValue && timestamp >= details.EndTime)) { startBound = ii; if (timestamp > details.StartTime) { continue; } } } else { if (timestamp <= details.StartTime) { startBound = ii; if (timestamp < details.StartTime) { continue; } } } } // check if absolute max values specified. if (sizeLimited) { if (details.NumValuesPerNode > 0 && details.NumValuesPerNode < values.Count) { break; } } // check for end bound. if (details.EndTime != DateTime.MinValue && timestamp >= details.EndTime) { if (timeFlowsBackward) { if (timestamp <= details.EndTime) { endBound = ii; break; } } else { if (timestamp >= details.EndTime) { endBound = ii; break; } } } // check if the start bound needs to be returned. if (returnBounds && values.Count == 0 && startBound != ii && details.StartTime != DateTime.MinValue) { // add start bound. if (startBound == -1) { values.AddLast(new DataValue(Variant.Null, StatusCodes.BadBoundNotFound, details.StartTime, details.StartTime)); } else { values.AddLast(RowToDataValue(context, nodeToRead, view[startBound], applyIndexRangeOrEncoding)); } // check if absolute max values specified. if (sizeLimited) { if (details.NumValuesPerNode > 0 && details.NumValuesPerNode < values.Count) { break; } } } // add value. values.AddLast(RowToDataValue(context, nodeToRead, view[ii], applyIndexRangeOrEncoding)); if (modificationInfos != null) { modificationInfos.AddLast((ModificationInfo)view[ii].Row[6]); } } finally { if (timeFlowsBackward) { ii--; } else { ii++; } } } // add late bound. while (returnBounds && details.EndTime != DateTime.MinValue) { // add start bound. if (values.Count == 0) { if (startBound == -1) { values.AddLast(new DataValue(Variant.Null, StatusCodes.BadBoundNotFound, details.StartTime, details.StartTime)); } else { values.AddLast(RowToDataValue(context, nodeToRead, view[startBound], applyIndexRangeOrEncoding)); } } // check if absolute max values specified. if (sizeLimited) { if (details.NumValuesPerNode > 0 && details.NumValuesPerNode < values.Count) { break; } } // add end bound. if (endBound == -1) { values.AddLast(new DataValue(Variant.Null, StatusCodes.BadBoundNotFound, details.EndTime, details.EndTime)); } else { values.AddLast(RowToDataValue(context, nodeToRead, view[endBound], applyIndexRangeOrEncoding)); } break; } HistoryReadRequest request = new HistoryReadRequest(); request.Values = values; request.ModificationInfos = modificationInfos; request.NumValuesPerNode = details.NumValuesPerNode; request.Filter = null; return request; }
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(); }
/// <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> /// Creates a new history request. /// </summary> private HistoryReadRequest CreateHistoryReadRequest( ServerSystemContext context, ReadEventDetails details, NodeHandle handle, HistoryReadValueId nodeToRead) { FilterContext filterContext = new FilterContext(context.NamespaceUris, context.TypeTable, context.PreferredLocales); LinkedList<BaseEventState> events = new LinkedList<BaseEventState>(); for (ReportType ii = ReportType.FluidLevelTest; ii <= ReportType.InjectionTest; ii++) { DataView view = null; if (handle.Node is WellState) { view = m_generator.ReadHistoryForWellId( ii, (string)handle.Node.NodeId.Identifier, details.StartTime, details.EndTime); } else { view = m_generator.ReadHistoryForArea( ii, handle.Node.NodeId.Identifier as string, details.StartTime, details.EndTime); } LinkedListNode<BaseEventState> pos = events.First; bool sizeLimited = (details.StartTime == DateTime.MinValue || details.EndTime == DateTime.MinValue); foreach (DataRowView row in view) { // check if reached max results. if (sizeLimited) { if (events.Count >= details.NumValuesPerNode) { break; } } BaseEventState e = m_generator.GetReport(context, NamespaceIndex, ii, row.Row); if (details.Filter.WhereClause != null && details.Filter.WhereClause.Elements.Count > 0) { if (!details.Filter.WhereClause.Evaluate(filterContext, e)) { continue; } } bool inserted = false; for (LinkedListNode<BaseEventState> jj = pos; jj != null; jj = jj.Next) { if (jj.Value.Time.Value > e.Time.Value) { events.AddBefore(jj, e); pos = jj; inserted = true; break; } } if (!inserted) { events.AddLast(e); pos = null; } } } HistoryReadRequest request = new HistoryReadRequest(); request.Events = events; request.TimeFlowsBackward = details.StartTime == DateTime.MinValue || (details.EndTime != DateTime.MinValue && details.EndTime < details.StartTime); request.NumValuesPerNode = details.NumValuesPerNode; request.Filter = details.Filter; request.FilterContext = filterContext; return request; }
/// <summary> /// Reads the last date in the archive (truncates milliseconds and converts to local). /// </summary> private DateTime ReadLastDate() { ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime = DateTime.MinValue; details.EndTime = DateTime.UtcNow.AddDays(1); details.NumValuesPerNode = 1; details.IsReadModified = false; details.ReturnBounds = false; HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; 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)) { return DateTime.MinValue; } HistoryData data = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; if (data == null || data.DataValues.Count == 0) { return DateTime.MinValue; } DateTime endTime = data.DataValues[0].SourceTimestamp; if (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Source, true, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); } endTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, endTime.Minute, endTime.Second, 0, DateTimeKind.Utc); endTime = endTime.AddSeconds(1); endTime = endTime.ToLocalTime(); return endTime; }
/// <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); } } }
/// <summary> /// Fetches the recent history. /// </summary> private void ReadRaw(bool isReadModified) { ReadRawModifiedDetails details = new ReadRawModifiedDetails(); details.StartTime =(StartTimeCK.Checked)?StartTimeDP.Value.ToUniversalTime():DateTime.MinValue; details.EndTime = (EndTimeCK.Checked)?EndTimeDP.Value.ToUniversalTime():DateTime.MinValue; details.NumValuesPerNode = (MaxReturnValuesCK.Checked)?(uint)MaxReturnValuesNP.Value:0; details.IsReadModified = isReadModified; details.ReturnBounds = (isReadModified)?false:ReturnBoundsCK.Checked; HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Both, false, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); if (StatusCode.IsBad(results[0].StatusCode)) { throw new ServiceResultException(results[0].StatusCode); } HistoryData values = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; DisplayResults(values); // save any continuation point. SaveContinuationPoint(details, nodeToRead, results[0].ContinuationPoint); }
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> /// Fetches the recent history. /// </summary> private void ReadAtTime() { ReadAtTimeDetails details = new ReadAtTimeDetails(); // generate times DateTime startTime = StartTimeDP.Value.ToUniversalTime(); for (int ii = 0; ii < MaxReturnValuesNP.Value; ii++) { details.ReqTimes.Add(startTime.AddMilliseconds((double)(ii*TimeStepNP.Value))); } HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Both, false, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); if (StatusCode.IsBad(results[0].StatusCode)) { throw new ServiceResultException(results[0].StatusCode); } HistoryData values = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; DisplayResults(values); // save any continuation point. SaveContinuationPoint(details, nodeToRead, results[0].ContinuationPoint); }
/// <summary> /// Returns the UTC timestamp of the first event in the archive. /// </summary> private DateTime ReadFirstDate() { // read the time of the first event in the archive. ReadEventDetails details = new ReadEventDetails(); details.StartTime = new DateTime(1970, 1, 1); details.EndTime = DateTime.MinValue; details.NumValuesPerNode = 1; details.Filter = new EventFilter(); details.Filter.AddSelectClause(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.Time); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_areaId; HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Neither, 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); } // get the data. HistoryEvent data = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryEvent; // release the continuation point. if (results[0].ContinuationPoint != null) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Neither, true, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); } // check if an event found. if (data == null || data.Events.Count == 0 || data.Events[0].EventFields.Count == 0) { throw new ServiceResultException(StatusCodes.BadNoDataAvailable); } // get the event time. DateTime? eventTime = data.Events[0].EventFields[0].Value as DateTime?; if (eventTime == null) { throw new ServiceResultException(StatusCodes.BadTypeMismatch); } // return time as UTC value. return eventTime.Value; }
/// <summary> /// Fetches the recent history. /// </summary> private void ReadProcessed() { AvailableAggregate aggregate = (AvailableAggregate)AggregateCB.SelectedItem; ReadProcessedDetails details = new ReadProcessedDetails(); details.StartTime = StartTimeDP.Value.ToUniversalTime(); details.EndTime = EndTimeDP.Value.ToUniversalTime(); details.ProcessingInterval = (double)ResampleIntervalNP.Value; details.AggregateType.Add(aggregate.NodeId); details.AggregateConfiguration.UseServerCapabilitiesDefaults = true; HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); HistoryReadValueId nodeToRead = new HistoryReadValueId(); nodeToRead.NodeId = m_nodeId; nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Both, false, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); if (StatusCode.IsBad(results[0].StatusCode)) { throw new ServiceResultException(results[0].StatusCode); } HistoryData values = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryData; DisplayResults(values); // save any continuation point. SaveContinuationPoint(details, nodeToRead, results[0].ContinuationPoint); }
/// <summary> /// Continues a read operation. /// </summary> private void ReadNext(ReadEventDetails details, HistoryReadValueId nodeToRead) { HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection(); nodesToRead.Add(nodeToRead); HistoryReadResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.HistoryRead( null, new ExtensionObject(details), TimestampsToReturn.Neither, false, nodesToRead, out results, out diagnosticInfos); Session.ValidateResponse(results, nodesToRead); Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); if (StatusCode.IsBad(results[0].StatusCode)) { throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // display results. HistoryEvent data = ExtensionObject.ToEncodeable(results[0].HistoryData) as HistoryEvent; ResultsLV.AddEventHistory(data); // check if a continuation point exists. if (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { nodeToRead.ContinuationPoint = results[0].ContinuationPoint; NextBTN.Visible = true; StopBTN.Enabled = true; GoBTN.Visible = false; m_details = details; m_nodeToRead = nodeToRead; } // all done. else { NextBTN.Visible = false; StopBTN.Enabled = false; GoBTN.Visible = true; m_details = null; m_nodeToRead = null; } }
/// <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; } }
/// <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; }
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(); }