/// <summary> /// Updates or inserts events. /// </summary> protected override void HistoryUpdateEvents( ServerSystemContext context, IList <UpdateEventDetails> nodesToUpdate, IList <HistoryUpdateResult> results, IList <ServiceResult> errors, List <NodeHandle> nodesToProcess, IDictionary <NodeId, NodeState> cache) { for (int ii = 0; ii < nodesToProcess.Count; ii++) { NodeHandle handle = nodesToProcess[ii]; UpdateEventDetails nodeToUpdate = nodesToUpdate[handle.Index]; HistoryUpdateResult result = results[handle.Index]; // validate the event filter. FilterContext filterContext = new FilterContext(context.NamespaceUris, context.TypeTable, context); EventFilter.Result filterResult = nodeToUpdate.Filter.Validate(filterContext); if (ServiceResult.IsBad(filterResult.Status)) { errors[handle.Index] = filterResult.Status; continue; } // all done. errors[handle.Index] = StatusCodes.BadNotImplemented; } }
static void HistoryUpdate(Session session) { DiagnosticInfoCollection diagnosticInfos; // translate browse paths. IList <NodeOfInterest> nodeIds; nodeIds = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder, VariableBrowsePaths.ToArray()); ExtensionObjectCollection eoc = new ExtensionObjectCollection(); for (int ii = 0; ii < nodeIds.Count; ii++) { UpdateDataDetails updateDetails = new UpdateDataDetails(); updateDetails.NodeId = nodeIds[ii].NodeId; updateDetails.PerformInsertReplace = PerformUpdateType.Update; updateDetails.UpdateValues = new DataValueCollection(); for (int jj = 0; jj <= 5; jj++) { DataValue dv = new DataValue(new Variant(jj * 10), StatusCodes.Good, new DateTime(2008, 01, 01, 12, 0, jj * 2)); updateDetails.UpdateValues.Add(dv); } ExtensionObject eo = new ExtensionObject(updateDetails.TypeId, updateDetails); eoc.Add(eo); } HistoryUpdateResultCollection historyUpdateResults; ResponseHeader responseHeader = session.HistoryUpdate(null, eoc, out historyUpdateResults, out diagnosticInfos); // process results. for (int ii = 0; ii < historyUpdateResults.Count; ii++) { HistoryUpdateResult historyUpdateResult = historyUpdateResults[ii]; Console.WriteLine("HistoryUpdate result code for {0}: {1}", VariableBrowsePaths[ii], historyUpdateResult.StatusCode.ToString()); if (StatusCode.IsGood(historyUpdateResult.StatusCode)) { for (int jj = 0; jj < historyUpdateResult.OperationResults.Count; jj++) { Console.WriteLine(" {0}: {1}", jj, historyUpdateResult.OperationResults[jj]); } Console.WriteLine(""); } } }
/// <summary> /// Deletes the history of values for a set of variables at given time. /// </summary> static void HistoryDeleteAtTime(Session session) { // translate browse paths. IList <NodeOfInterest> results = GetNodeIds(session, Opc.Ua.Objects.ObjectsFolder, VariableBrowsePaths.ToArray()); DiagnosticInfoCollection diagnosticInfos; ExtensionObjectCollection eoc = new ExtensionObjectCollection(); for (int ii = 0; ii < results.Count; ii++) { DeleteAtTimeDetails deleteDetails = new DeleteAtTimeDetails(); deleteDetails.ReqTimes = new DateTimeCollection(); for (int jj = 0; jj < 5; jj++) { deleteDetails.ReqTimes.Add(new DateTime(2008, 01, 01, 12, 0, jj * 2)); } deleteDetails.NodeId = results[ii].NodeId; deleteDetails.Processed = false; ExtensionObject eo = new ExtensionObject(deleteDetails.TypeId, deleteDetails); eoc.Add(eo); } HistoryUpdateResultCollection historyUpdateResults; ResponseHeader responseHeader = session.HistoryUpdate(null, eoc, out historyUpdateResults, out diagnosticInfos); // process results. for (int ii = 0; ii < historyUpdateResults.Count; ii++) { HistoryUpdateResult historyUpdateResult = historyUpdateResults[ii]; Console.WriteLine("HistoryUpdate result code for {0}: {1}", VariableBrowsePaths[ii], historyUpdateResult.StatusCode.ToString()); if (StatusCode.IsGood(historyUpdateResult.StatusCode)) { for (int jj = 0; jj < historyUpdateResult.OperationResults.Count; jj++) { Console.WriteLine(" {0}: {1}", jj, historyUpdateResult.OperationResults[jj]); } Console.WriteLine(""); } } }
/// <summary> /// Updates the history of an item. /// </summary> public StatusCode DeleteRaw(string itemId, DeleteRawModifiedDetails details, HistoryUpdateResult result) { // create handles. HdaItem[] items = GetItems(itemId); if (items == null || items[0].Error < 0) { result.StatusCode = StatusCodes.BadNodeIdUnknown; return result.StatusCode; } try { // update data. result.StatusCode = DeleteRaw( items[0], details.StartTime, details.EndTime); } catch (Exception) { result.StatusCode = StatusCodes.BadUnexpectedError; } finally { // release handles. ReleaseItemHandles(items); } return result.StatusCode; }
/// <summary> /// Updates the history of an item. /// </summary> public StatusCode UpdateData(string itemId, UpdateDataDetails details, HistoryUpdateResult result) { // create handles. HdaItem[] items = GetItems(itemId); if (items == null || items[0].Error < 0) { result.StatusCode = StatusCodes.BadNodeIdUnknown; return result.StatusCode; } int[] errors = null; try { // update data. result.StatusCode = UpdateData( items[0], details.PerformInsertReplace, details.UpdateValues, out errors); // update error codes. for (int ii = 0; ii < errors.Length; ii++) { StatusCode statusCode = MapErrorCodeToUpdateStatus(errors[ii]); result.OperationResults.Add(statusCode); } } catch (Exception) { result.StatusCode = StatusCodes.BadUnexpectedError; } finally { // reelase handles. ReleaseItemHandles(items); } return result.StatusCode; }
/// <summary> /// Updates the history of an item. /// </summary> public StatusCode DeleteAtTime(string itemId, DeleteAtTimeDetails details, HistoryUpdateResult result) { // create handles. HdaItem[] items = GetItems(itemId); if (items == null || items[0].Error < 0) { result.StatusCode = StatusCodes.BadNodeIdUnknown; return result.StatusCode; } try { int[] errors = DeleteAtTime(items[0], details.ReqTimes); // update error codes. for (int ii = 0; ii < errors.Length; ii++) { StatusCode statusCode = MapErrorCodeToUpdateStatus(errors[ii]); result.OperationResults.Add(statusCode); } } catch (Exception) { result.StatusCode = StatusCodes.BadUnexpectedError; } finally { // release handles. ReleaseItemHandles(items); } return result.StatusCode; }
/// <summary> /// Updates the history for the specified nodes. /// </summary> public virtual void HistoryUpdate( OperationContext context, Type detailsType, IList<HistoryUpdateDetails> nodesToUpdate, IList<HistoryUpdateResult> 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 < nodesToUpdate.Count; ii++) { HistoryUpdateDetails nodeToUpdate = nodesToUpdate[ii]; // skip items that have already been processed. if (nodeToUpdate.Processed) { continue; } // check for valid handle. NodeHandle handle = GetManagerHandle(systemContext, nodeToUpdate.NodeId, operationCache); if (handle == null) { continue; } // owned by this node manager. nodeToUpdate.Processed = true; // create an initial result. HistoryUpdateResult result = results[ii] = new HistoryUpdateResult(); 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.HistoryWrite) != 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.HistoryWrite) != 0) { handle.Index = ii; nodesToProcess.Add(handle); continue; } } } // check for nothing to do. if (nodesToProcess.Count == 0) { return; } } // validates the nodes and updates. HistoryUpdate( systemContext, detailsType, nodesToUpdate, results, errors, nodesToProcess, operationCache); }
/// <summary> /// Deletes history events. /// </summary> protected override void HistoryDeleteEvents( ServerSystemContext context, IList <DeleteEventDetails> nodesToUpdate, IList <HistoryUpdateResult> results, IList <ServiceResult> errors, List <NodeHandle> nodesToProcess, IDictionary <NodeId, NodeState> cache) { for (int ii = 0; ii < nodesToProcess.Count; ii++) { NodeHandle handle = nodesToProcess[ii]; DeleteEventDetails nodeToUpdate = nodesToUpdate[handle.Index]; HistoryUpdateResult result = results[handle.Index]; // delete events. bool failed = false; for (int jj = 0; jj < nodeToUpdate.EventIds.Count; jj++) { try { string eventId = new Guid(nodeToUpdate.EventIds[jj]).ToString(); if (!m_generator.DeleteEvent(eventId)) { result.OperationResults.Add(StatusCodes.BadEventIdUnknown); failed = true; continue; } result.OperationResults.Add(StatusCodes.Good); } catch { result.OperationResults.Add(StatusCodes.BadEventIdUnknown); failed = true; } } // check if diagnostics are required. if (failed) { if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { for (int jj = 0; jj < nodeToUpdate.EventIds.Count; jj++) { if (StatusCode.IsBad(result.OperationResults[jj])) { result.DiagnosticInfos.Add(ServerUtils.CreateDiagnosticInfo(Server, context.OperationContext, result.OperationResults[jj])); } } } } // clear operation results if all good. else { result.OperationResults.Clear(); } // all done. errors[handle.Index] = ServiceResult.Good; } }
/// <summary> /// Updates the history for a set of nodes. /// </summary> public virtual void HistoryUpdate( OperationContext context, ExtensionObjectCollection historyUpdateDetails, out HistoryUpdateResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { Type detailsType = null; List<HistoryUpdateDetails> nodesToUpdate = new List<HistoryUpdateDetails>(); // verify that all extension objects in the list have the same type. foreach (ExtensionObject details in historyUpdateDetails) { if (detailsType == null) { detailsType = details.Body.GetType(); } if (!ExtensionObject.IsNull(details)) { nodesToUpdate.Add(details.Body as HistoryUpdateDetails); } } // create result lists. bool diagnosticsExist = false; results = new HistoryUpdateResultCollection(nodesToUpdate.Count); diagnosticInfos = new DiagnosticInfoCollection(nodesToUpdate.Count); // pre-validate items. bool validItems = false; for (int ii = 0; ii < nodesToUpdate.Count; ii++) { HistoryUpdateResult result = null; DiagnosticInfo diagnosticInfo = null; // check the type of details parameter. ServiceResult error = null; if (nodesToUpdate[ii].GetType() != detailsType) { error = StatusCodes.BadHistoryOperationInvalid; } // pre-validate and pre-parse parameter. else { error = HistoryUpdateDetails.Validate(nodesToUpdate[ii]); } // return error status. if (ServiceResult.IsBad(error)) { nodesToUpdate[ii].Processed = true; result = new HistoryUpdateResult(); 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 { nodesToUpdate[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 < nodesToUpdate.Count; ii++) { errors.Add(null); } foreach (INodeManager nodeManager in m_nodeManagers) { nodeManager.HistoryUpdate( context, detailsType, nodesToUpdate, results, errors); } for (int ii = 0; ii < nodesToUpdate.Count; ii++) { HistoryUpdateResult result = results[ii]; // set an error code for nodes that were not handled by any node manager. if (!nodesToUpdate[ii].Processed) { nodesToUpdate[ii].Processed = true; result = results[ii] = new HistoryUpdateResult(); result.StatusCode = StatusCodes.BadNodeIdUnknown; errors[ii] = result.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 HistoryUpdateResult(); } 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); }