/// <summary> /// Reads the raw data history. /// </summary> /// <param name="request">The request.</param> public StatusCode ReadAnnotationHistory(HdaHistoryReadAnnotationRequest request) { // check if nothing to do. if (request == null) { return StatusCodes.BadNothingToDo; } // create the handle. HdaItem[] items = GetItems(request.ItemId); if (items == null || items[0].Error < 0) { return StatusCodes.BadNodeIdUnknown; } request.ServerHandle = items[0].ServerHandle; try { // read modified not supported for annotations. if (request.IsReadModified) { return StatusCodes.BadNoData; } // read the values and them in the request object. return ReadAnnotations(request); } catch (Exception) { return StatusCodes.BadUnexpectedError; } finally { ReleaseItemHandles(request.ServerHandle); request.ServerHandle = 0; } }
/// <summary> /// Reads the annotation data for an item. /// </summary> private StatusCode ReadAnnotations(HdaHistoryReadAnnotationRequest request) { string methodName = "IOPCHDA_SyncAnnotations.Read"; OPCHDA_TIME htStartTime = ConvertTime(request.StartTime); OPCHDA_TIME htEndTime = ConvertTime(request.EndTime); IntPtr ppAnnotationValues; IntPtr ppErrors; try { IOPCHDA_SyncAnnotations server = BeginComCall<IOPCHDA_SyncAnnotations>(methodName, true); server.Read( ref htStartTime, ref htEndTime, 1, new int[] { request.ServerHandle }, out ppAnnotationValues, out ppErrors); } catch (Exception e) { ComCallError(methodName, e); return StatusCodes.BadUnexpectedError; } finally { EndComCall(methodName); } // check for error. int[] errors = ComUtils.GetInt32s(ref ppErrors, 1, true); if (errors[0] < 0) { return StatusCodes.BadNodeIdUnknown; } // unmarshal the results. OPCHDA_ANNOTATION result = (OPCHDA_ANNOTATION)Marshal.PtrToStructure(ppAnnotationValues, typeof(OPCHDA_ANNOTATION)); if (result.dwNumValues > 0) { DateTime[] timestamps = ComUtils.GetDateTimes(ref result.ftTimeStamps, result.dwNumValues, true); string[] annotations = ComUtils.GetUnicodeStrings(ref result.szAnnotation, result.dwNumValues, true); DateTime[] annotationTimes = ComUtils.GetDateTimes(ref result.ftAnnotationTime, result.dwNumValues, true); string[] userNames = ComUtils.GetUnicodeStrings(ref result.szUser, result.dwNumValues, true); request.Annotations = new List<DataValue>(result.dwNumValues); for (int ii = 0; ii < result.dwNumValues; ii++) { Annotation annotation = new Annotation(); annotation.AnnotationTime = annotationTimes[ii]; annotation.Message = annotations[ii]; annotation.UserName = userNames[ii]; DataValue value = new DataValue(new Variant(new ExtensionObject(annotation))); value.SourceTimestamp = timestamps[ii]; request.Annotations.Add(value); } } Marshal.FreeCoTaskMem(ppAnnotationValues); return StatusCodes.Good; }
/// <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; }