/// <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; } }
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); } } }
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); } }
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); } }
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); } }
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); }
/// <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); }
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); }
/// <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; }
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(); }
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 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); } }
/// <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> /// 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; }
/// <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]); } }
/// <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; }