Skip to content

Commit

Permalink
client_historical_update: Add api to alter raw data.
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-rustler-basyskom committed Jan 16, 2019
1 parent fe01551 commit d2531e4
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/ua_client.h
Expand Up @@ -268,6 +268,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

/*
Expand Down
22 changes: 22 additions & 0 deletions include/ua_client_highlevel.h
Expand Up @@ -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
Expand Down
127 changes: 127 additions & 0 deletions src/client/ua_client_highlevel.c
Expand Up @@ -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 */
Expand Down

0 comments on commit d2531e4

Please sign in to comment.