I manage to compile my code that contains historizing capabilities.
However, I am still getting the following messages within UAExpert when i add a historizing node:
- found session for ServerId 0
- HistoryReadRawModified succeeded
- HistoryReadDataResults[0] has bad status BadHistoryOperationInvalid
- No history values received for node 'NS1|Numeric|10302'
i combed through the documentations relating to Historizing function. See below:
Did i miss anything?
***********************************************************************************************************************
in SV_StartOPCUAServer.c:, i have the following functions declared:
=========
static UA_Boolean allowHistoryUpdateUpdateData(UA_Server *server, UA_AccessControl *ac,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId,
UA_PerformUpdateType performInsertReplace,
const UA_DataValue *value) {
return true;
}
static UA_Boolean allowHistoryUpdateDeleteRawModified(UA_Server *server, UA_AccessControl *ac,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId,
UA_DateTime startTimestamp,
UA_DateTime endTimestamp,
bool isDeleteModified) {
return true;
}
=========
In my main() function, i have:
main()
{
UA_Server myServer;
UA_ServerConfig config1;
...
config1.accessHistoryDataCapability = true;
config1.maxReturnDataValues = 0 ; // 0 means unlimited size
config1.accessHistoryEventsCapability = true;
config1.maxReturnEventValues = 0; // 0 means unlimted size
config1.insertDataCapability = true;
config1.insertEventCapability = true;
config1.insertAnnotationsCapability = true;
config1.replaceDataCapability = true;
config1.replaceEventCapability = true;
config1.updateDataCapability = true;
config1.updateEventCapability = true;
config1.deleteRawCapability = true;
config1.deleteEventCapability = true;
config1.deleteAtTimeDataCapability = true;
config1.accessControl.allowHistoryUpdateUpdateData = allowHistoryUpdateUpdateData;
config1.accessControl.allowHistoryUpdateDeleteRawModified = allowHistoryUpdateDeleteRawModified;
CreateOPCUANodes(myServer); // verified ok
CreateServerMethodItems(myServer); // verified ok
CreateServerHistorizingItems(myServer); // error messages shown in UAExpert
CreateServerMonitoredItems(myServer); // server log shows successful
}
==================
In CreateOPCUANodes() function::
---------------------
// In SV_CreateOPCUANodes.c
extern UA_NodeId outIgramPP_Id;
CreateOPCUANodes(myServer)
{
...
UA_VariableAttributes vIgramPPAttr = UA_VariableAttributes_default;
vIgramPPAttr.description = UA_LOCALIZEDTEXT("en-US", "IgramPPInfo");
vIgramPPAttr.displayName = UA_LOCALIZEDTEXT("en-US", "01. Igram PP");
vIgramPPAttr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_HISTORYREAD;
vIgramPPAttr.historizing = true;
//UA_Float IgramPP = (UA_Float) XMLIgramPP; // value is set in print_element_names
UA_Variant_setScalar(&vIgramPPAttr.value, &IgramPP, &UA_TYPES[UA_TYPES_FLOAT]);
UA_Server_addVariableNode(uaServer, UA_NODEID_NUMERIC(1, 10301), // 1 refers to namespace : NS1
r2_airgard_diagnostics_Id,
UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY),
UA_QUALIFIEDNAME(1, "Igram PP"),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
vIgramPPAttr, NULL, &outIgramPP_Id);
//vIgramPPAttr, NULL, &ds1IgramPPId);
}
---------------------
In CreateServerHistorizingItems() function::
// In SV_Historizing.c
extern UA_NodeId outIgramPP_Id;
..
void CreateServerHistorizingItems(UA_Server *server)
{
size_t initialNodeIdStoreSize = 100000;
UA_HistoryDataGathering HistoryDataGathering = UA_HistoryDataGathering_Default(initialNodeIdStoreSize); // initial NodeStore Size = 1
UA_ServerConfig *config = UA_Server_getConfig(server);
config->historyDatabase = UA_HistoryDatabase_default(HistoryDataGathering);
UA_HistorizingNodeIdSettings HistorizingSetting;
HistorizingSetting.historizingBackend = UA_HistoryDataBackend_Memory(21, 20); // 21 nodes, 20 values
HistorizingSetting.maxHistoryDataResponseSize = 20;
HistorizingSetting.pollingInterval = 100;
HistorizingSetting.historizingUpdateStrategy = UA_HISTORIZINGUPDATESTRATEGY_POLL;
int retval;
retval = HistoryDataGathering.registerNodeId(server, HistoryDataGathering.context, &outIgramPP_Id, HistorizingSetting);
retval = HistoryDataGathering.registerNodeId(server, HistoryDataGathering.context, &outIgramDC_Id, HistorizingSetting);
retval = HistoryDataGathering.registerNodeId(server, HistoryDataGathering.context, &outLaserPP_Id, HistorizingSetting);
retval = HistoryDataGathering.registerNodeId(server, HistoryDataGathering.context, &outLaserDC_Id, HistorizingSetting);
retval = HistoryDataGathering.registerNodeId(server, HistoryDataGathering.context, &outSingleBeamAt900_Id, HistorizingSetting);
====================