|
@@ -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 */
|