Преглед на файлове

client_historical_update: Add api to alter raw data.

Peter Rustler преди 5 години
родител
ревизия
5c5c92da57
променени са 3 файла, в които са добавени 157 реда и са изтрити 0 реда
  1. 8 0
      include/ua_client.h
  2. 22 0
      include/ua_client_highlevel.h
  3. 127 0
      src/client/ua_client_highlevel.c

+ 8 - 0
include/ua_client.h

@@ -246,6 +246,14 @@ UA_Client_Service_historyRead(UA_Client *client, const UA_HistoryReadRequest req
         &response, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]);
     return response;
 }
+
+static UA_INLINE UA_HistoryUpdateResponse
+UA_Client_Service_historyUpdate(UA_Client *client, const UA_HistoryUpdateRequest request) {
+    UA_HistoryUpdateResponse response;
+    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST],
+        &response, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]);
+    return response;
+}
 #endif
 
 /*

+ 22 - 0
include/ua_client_highlevel.h

@@ -249,6 +249,28 @@ UA_Client_HistoryRead_modified(UA_Client *client, const UA_NodeId *nodeId,
                                   UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode,
                                   UA_TimestampsToReturn timestampsToReturn, void *callbackContext);
 #endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING
+
+UA_StatusCode UA_EXPORT
+UA_Client_HistoryUpdate_insert(UA_Client *client,
+                               const UA_NodeId *nodeId,
+                               UA_DataValue *value);
+
+UA_StatusCode UA_EXPORT
+UA_Client_HistoryUpdate_replace(UA_Client *client,
+                                const UA_NodeId *nodeId,
+                                UA_DataValue *value);
+
+UA_StatusCode UA_EXPORT
+UA_Client_HistoryUpdate_update(UA_Client *client,
+                               const UA_NodeId *nodeId,
+                               UA_DataValue *value);
+
+UA_StatusCode UA_EXPORT
+UA_Client_HistoryUpdate_deleteRaw(UA_Client *client,
+                                  const UA_NodeId *nodeId,
+                                  UA_DateTime startTimestamp,
+                                  UA_DateTime endTimestamp);
+
 #endif // UA_ENABLE_HISTORIZING
 /**
  * Write Attributes

+ 127 - 0
src/client/ua_client_highlevel.c

@@ -623,6 +623,133 @@ UA_Client_HistoryRead_modified(UA_Client *client, const UA_NodeId *nodeId,
                                                      maxItems, UA_TRUE, timestampsToReturn, callbackContext);
 }
 #endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING
+
+static UA_HistoryUpdateResponse
+__UA_Client_HistoryUpdate(UA_Client *client,
+                          void *details,
+                          size_t typeId)
+{
+    UA_HistoryUpdateRequest request;
+    UA_HistoryUpdateRequest_init(&request);
+
+    UA_ExtensionObject extension;
+    UA_ExtensionObject_init(&extension);
+    request.historyUpdateDetailsSize = 1;
+    request.historyUpdateDetails = &extension;
+
+    extension.encoding = UA_EXTENSIONOBJECT_DECODED;
+    extension.content.decoded.type = &UA_TYPES[typeId];
+    extension.content.decoded.data = details;
+
+    UA_HistoryUpdateResponse response;
+    response = UA_Client_Service_historyUpdate(client, request);
+    //UA_HistoryUpdateRequest_deleteMembers(&request);
+    return response;
+}
+
+static UA_StatusCode
+__UA_Client_HistoryUpdate_updateData(UA_Client *client,
+                          const UA_NodeId *nodeId,
+                          UA_PerformUpdateType type,
+                          UA_DataValue *value)
+{
+    UA_StatusCode ret = UA_STATUSCODE_GOOD;
+    UA_UpdateDataDetails details;
+    UA_UpdateDataDetails_init(&details);
+
+    details.performInsertReplace = type;
+    details.updateValuesSize = 1;
+    details.updateValues = value;
+    UA_NodeId_copy(nodeId, &details.nodeId);
+
+    UA_HistoryUpdateResponse response;
+    response = __UA_Client_HistoryUpdate(client, &details, UA_TYPES_UPDATEDATADETAILS);
+    if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
+        ret = response.responseHeader.serviceResult;
+        goto cleanup;
+    }
+    if (response.resultsSize != 1 || response.results[0].operationResultsSize != 1) {
+        ret = UA_STATUSCODE_BADUNEXPECTEDERROR;
+        goto cleanup;
+    }
+    if (response.results[0].statusCode != UA_STATUSCODE_GOOD) {
+        ret = response.results[0].statusCode;
+        goto cleanup;
+    }
+    ret = response.results[0].operationResults[0];
+cleanup:
+    UA_HistoryUpdateResponse_deleteMembers(&response);
+    UA_NodeId_deleteMembers(&details.nodeId);
+    return ret;
+}
+
+UA_StatusCode
+UA_Client_HistoryUpdate_insert(UA_Client *client,
+                               const UA_NodeId *nodeId,
+                               UA_DataValue *value)
+{
+    return __UA_Client_HistoryUpdate_updateData(client,
+                                                nodeId,
+                                                UA_PERFORMUPDATETYPE_INSERT,
+                                                value);
+}
+
+UA_StatusCode
+UA_Client_HistoryUpdate_replace(UA_Client *client,
+                                const UA_NodeId *nodeId,
+                                UA_DataValue *value)
+{
+    return __UA_Client_HistoryUpdate_updateData(client,
+                                                nodeId,
+                                                UA_PERFORMUPDATETYPE_REPLACE,
+                                                value);
+}
+
+UA_StatusCode
+UA_Client_HistoryUpdate_update(UA_Client *client,
+                               const UA_NodeId *nodeId,
+                               UA_DataValue *value)
+{
+    return __UA_Client_HistoryUpdate_updateData(client,
+                                                nodeId,
+                                                UA_PERFORMUPDATETYPE_UPDATE,
+                                                value);
+}
+
+UA_StatusCode
+UA_Client_HistoryUpdate_deleteRaw(UA_Client *client,
+                                  const UA_NodeId *nodeId,
+                                  UA_DateTime startTimestamp,
+                                  UA_DateTime endTimestamp)
+{
+    UA_StatusCode ret = UA_STATUSCODE_GOOD;
+
+    UA_DeleteRawModifiedDetails details;
+    UA_DeleteRawModifiedDetails_init(&details);
+
+    details.isDeleteModified = false;
+    details.startTime = startTimestamp;
+    details.endTime = endTimestamp;
+    UA_NodeId_copy(nodeId, &details.nodeId);
+
+    UA_HistoryUpdateResponse response;
+    response = __UA_Client_HistoryUpdate(client, &details, UA_TYPES_DELETERAWMODIFIEDDETAILS);
+    if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
+        ret = response.responseHeader.serviceResult;
+        goto cleanup;
+    }
+    if (response.resultsSize != 1) {
+        ret = UA_STATUSCODE_BADUNEXPECTEDERROR;
+        goto cleanup;
+    }
+
+    ret = response.results[0].statusCode;
+
+cleanup:
+    UA_HistoryUpdateResponse_deleteMembers(&response);
+    UA_NodeId_deleteMembers(&details.nodeId);
+    return ret;
+}
 #endif // UA_ENABLE_HISTORIZING
 
 /* Async Functions */