void LogWidgetModel::changeMode(bool active) { if (active) { m_mode = qobject_cast<QRadioButton *>(sender())->property("mode").toInt(); requestHistory(b_engine->getFullId(), m_mode); emit headerDataChanged(Qt::Horizontal, 0, 3); reset(); } }
END_TEST START_TEST(Server_HistorizingStrategyValueSet) { // init to a defined value UA_StatusCode retval = setUInt32(client, outNodeId, 43); ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD)); // set a data backend UA_HistorizingNodeIdSettings setting; setting.historizingBackend = UA_HistoryDataBackend_Memory(3, 100); setting.maxHistoryDataResponseSize = 100; setting.historizingUpdateStrategy = UA_HISTORIZINGUPDATESTRATEGY_VALUESET; serverMutexLock(); retval = gathering->registerNodeId(server, gathering->context, &outNodeId, setting); serverMutexUnlock(); ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD)); // fill the data UA_fakeSleep(100); UA_DateTime start = UA_DateTime_now(); UA_fakeSleep(100); for (UA_UInt32 i = 0; i < 10; ++i) { retval = setUInt32(client, outNodeId, i); ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD)); UA_fakeSleep(100); } UA_DateTime end = UA_DateTime_now(); // request UA_HistoryReadResponse response; UA_HistoryReadResponse_init(&response); requestHistory(start, end, &response, 0, false, NULL); // test the response ck_assert_str_eq(UA_StatusCode_name(response.responseHeader.serviceResult), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(response.resultsSize, 1); for (size_t i = 0; i < response.resultsSize; ++i) { ck_assert_str_eq(UA_StatusCode_name(response.results[i].statusCode), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(response.results[i].historyData.encoding, UA_EXTENSIONOBJECT_DECODED); ck_assert(response.results[i].historyData.content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYDATA]); UA_HistoryData * data = (UA_HistoryData *)response.results[i].historyData.content.decoded.data; ck_assert(data->dataValuesSize > 0); for (size_t j = 0; j < data->dataValuesSize; ++j) { ck_assert(data->dataValues[j].sourceTimestamp >= start && data->dataValues[j].sourceTimestamp < end); ck_assert_uint_eq(data->dataValues[j].hasSourceTimestamp, true); ck_assert_str_eq(UA_StatusCode_name(data->dataValues[j].status), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(data->dataValues[j].hasValue, true); ck_assert(data->dataValues[j].value.type == &UA_TYPES[UA_TYPES_UINT32]); UA_UInt32 * value = (UA_UInt32 *)data->dataValues[j].value.data; ck_assert_uint_eq(*value, j); } } UA_HistoryReadResponse_deleteMembers(&response); UA_HistoryDataBackend_Memory_deleteMembers(&setting.historizingBackend); }
void Synchronizer::loop() { // keep the history up to date // if the history is more than x minutes old pull it if (m_historyReceivedAt.secsTo(QDateTime::currentDateTime()) > m_historyUpdateInterval){ requestHistory(); } // if we are not already using all allocated connections, pull/push queued statediffs while (m_numPulls < (m_maxPulls+1)){ if (!m_stateDiffsToPull.isEmpty()){ QString name = m_stateDiffsToPull.takeFirst(); m_numPulls += 1; get(m_trackerUrl, "state_diffs/"+name); }else break; } while (m_numPushes < (m_maxPushes+1)){ if (!m_stateDiffsToPush.isEmpty()){ QString name = m_stateDiffsToPush.takeFirst(); bool ok; StateDiff diff = m_repo->logger()->loadStateDiff(name, &ok); if (ok){ m_numPushes += 1; post(m_trackerUrl, "state_diffs", diff.toJSON()); }else{ qCritical() << "failed to loadStateDiff for push"; } }else break; } // if numPulls and numPushes == 0 and toPull and toPush == 0 // so we must have pulled and pushed all statediffs // so the problem of applying state // incomming state diffs should be ordered alphabetically by name // we then want a minimal list of operations from that // then presumably we have synchronized metadata // now we want to compare the most recent state to the repo // and see which files we need to download before we can recreate the state locally }
History::History(QWidget *parent) : XLet(parent, tr("History"), ":/images/tab-history.svg"), m_model(NULL), m_proxy_model(NULL) { this->ui.setupUi(this); m_model = new HistoryModel(this); m_proxy_model = new HistorySortFilterProxyModel(this); m_proxy_model->setSourceModel(m_model); this->ui.history_table->setModel(m_proxy_model); this->ui.history_table->sortByColumn(2, Qt::DescendingOrder); QAction *all_call_action = this->ui.menu->addAction(tr("All calls")); QAction *sent_call_action = this->ui.menu->addAction(tr("Sent calls")); QAction *received_call_action = this->ui.menu->addAction(tr("Received calls")); QAction *missed_call_action = this->ui.menu->addAction(tr("Missed calls")); connect(all_call_action, SIGNAL(triggered()), this, SLOT(allCallsMode())); connect(sent_call_action, SIGNAL(triggered()), this, SLOT(sentCallsMode())); connect(received_call_action, SIGNAL(triggered()), this, SLOT(receivedCallsMode())); connect(missed_call_action, SIGNAL(triggered()), this, SLOT(missedCallsMode())); this->ui.menu->setSelectedAction(0); connect(b_engine, SIGNAL(settingsChanged()), this, SLOT(requestHistory())); connect(this->ui.history_table, SIGNAL(extensionClicked(const QString &)), b_engine, SLOT(pasteToDial(const QString &))); registerListener("history"); }
static void testResult(UA_DateTime *resultData, UA_HistoryData * historyData) { // request UA_HistoryReadResponse localResponse; UA_HistoryReadResponse_init(&localResponse); requestHistory(TIMESTAMP_FIRST, TIMESTAMP_LAST, &localResponse, 0, false, NULL); // test the response ck_assert_str_eq(UA_StatusCode_name(localResponse.responseHeader.serviceResult), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(localResponse.resultsSize, 1); ck_assert_str_eq(UA_StatusCode_name(localResponse.results[0].statusCode), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(localResponse.results[0].historyData.encoding, UA_EXTENSIONOBJECT_DECODED); ck_assert(localResponse.results[0].historyData.content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYDATA]); UA_HistoryData * data = (UA_HistoryData *)localResponse.results[0].historyData.content.decoded.data; if (historyData) UA_HistoryData_copy(data, historyData); for (size_t j = 0; j < data->dataValuesSize; ++j) { ck_assert(resultData[j] != 0); ck_assert_uint_eq(data->dataValues[j].hasSourceTimestamp, true); ck_assert_uint_eq(data->dataValues[j].sourceTimestamp, resultData[j]); } UA_HistoryReadResponse_deleteMembers(&localResponse); }
END_TEST START_TEST(Server_HistorizingStrategyUser) { // set a data backend UA_HistorizingNodeIdSettings setting; setting.historizingBackend = UA_HistoryDataBackend_Memory(3, 100); setting.maxHistoryDataResponseSize = 100; setting.historizingUpdateStrategy = UA_HISTORIZINGUPDATESTRATEGY_USER; UA_StatusCode retval = gathering->registerNodeId(server, gathering->context, &outNodeId, setting); ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD)); // fill the data UA_DateTime start = UA_DateTime_now(); UA_DateTime end = start + (10 * UA_DATETIME_SEC); for (UA_UInt32 i = 0; i < 10; ++i) { UA_DataValue value; UA_DataValue_init(&value); value.hasValue = true; value.hasStatus = true; value.status = UA_STATUSCODE_GOOD; UA_Variant_setScalarCopy(&value.value, &i, &UA_TYPES[UA_TYPES_UINT32]); value.hasSourceTimestamp = true; value.sourceTimestamp = start + (i * UA_DATETIME_SEC); value.hasServerTimestamp = true; value.serverTimestamp = value.sourceTimestamp; retval = setting.historizingBackend.serverSetHistoryData(server, setting.historizingBackend.context, NULL, NULL, &outNodeId, UA_FALSE, &value); ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD)); UA_DataValue_deleteMembers(&value); } // request UA_HistoryReadResponse response; UA_HistoryReadResponse_init(&response); requestHistory(start, end, &response, 0, false, NULL); // test the response ck_assert_str_eq(UA_StatusCode_name(response.responseHeader.serviceResult), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(response.resultsSize, 1); for (size_t i = 0; i < response.resultsSize; ++i) { ck_assert_str_eq(UA_StatusCode_name(response.results[i].statusCode), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(response.results[i].historyData.encoding, UA_EXTENSIONOBJECT_DECODED); ck_assert(response.results[i].historyData.content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYDATA]); UA_HistoryData * data = (UA_HistoryData *)response.results[i].historyData.content.decoded.data; ck_assert_uint_eq(data->dataValuesSize, 10); for (size_t j = 0; j < data->dataValuesSize; ++j) { ck_assert_uint_eq(data->dataValues[j].hasSourceTimestamp, true); ck_assert_uint_eq(data->dataValues[j].sourceTimestamp, start + (j * UA_DATETIME_SEC)); ck_assert_uint_eq(data->dataValues[j].hasStatus, true); ck_assert_str_eq(UA_StatusCode_name(data->dataValues[j].status), UA_StatusCode_name(UA_STATUSCODE_GOOD)); ck_assert_uint_eq(data->dataValues[j].hasValue, true); ck_assert(data->dataValues[j].value.type == &UA_TYPES[UA_TYPES_UINT32]); UA_UInt32 * value = (UA_UInt32 *)data->dataValues[j].value.data; ck_assert_uint_eq(*value, j); } } UA_HistoryReadResponse_deleteMembers(&response); UA_HistoryDataBackend_Memory_deleteMembers(&setting.historizingBackend); }
static UA_UInt32 testHistoricalDataBackend(size_t maxResponseSize) { const UA_HistorizingNodeIdSettings* setting = gathering->getHistorizingSetting(server, gathering->context, &outNodeId); UA_HistorizingNodeIdSettings newSetting = *setting; newSetting.maxHistoryDataResponseSize = maxResponseSize; gathering->updateNodeIdSetting(server, gathering->context, &outNodeId, newSetting); UA_UInt32 retval = 0; size_t i = 0; testTuple *current = &testRequests[i]; fprintf(stderr, "Testing with maxResponseSize of %lu\n", maxResponseSize); fprintf(stderr, "Start | End | numValuesPerNode | returnBounds |ContPoint| {Expected}{Result} Result\n"); fprintf(stderr, "------+------+------------------+--------------+---------+----------------\n"); size_t j; while (current->start || current->end) { j = 0; if (current->start == TIMESTAMP_UNSPECIFIED) { fprintf(stderr, "UNSPEC|"); } else { fprintf(stderr, " %3lld |", current->start / UA_DATETIME_SEC); } if (current->end == TIMESTAMP_UNSPECIFIED) { fprintf(stderr, "UNSPEC|"); } else { fprintf(stderr, " %3lld |", current->end / UA_DATETIME_SEC); } fprintf(stderr, " %2u | %s | %s | {", current->numValuesPerNode, (current->returnBounds ? "Yes" : " No"), (current->returnContinuationPoint ? "Yes" : " No")); while (current->result[j]) { printTimestamp(current->result[j]); ++j; } fprintf(stderr, "}"); UA_DataValue *result = NULL; size_t resultSize = 0; UA_ByteString continuous; UA_ByteString_init(&continuous); UA_Boolean readOk = true; size_t reseivedValues = 0; fprintf(stderr, "{"); size_t counter = 0; do { UA_HistoryReadResponse response; UA_HistoryReadResponse_init(&response); UA_UInt32 numValuesPerNode = current->numValuesPerNode; if (numValuesPerNode > 0 && numValuesPerNode + (UA_UInt32)reseivedValues > current->numValuesPerNode) numValuesPerNode = current->numValuesPerNode - (UA_UInt32)reseivedValues; requestHistory(current->start, current->end, &response, numValuesPerNode, current->returnBounds, &continuous); ++counter; if(response.resultsSize != 1) { fprintf(stderr, "ResultError:Size %lu %s", response.resultsSize, UA_StatusCode_name(response.responseHeader.serviceResult)); readOk = false; UA_HistoryReadResponse_deleteMembers(&response); break; } UA_StatusCode stat = response.results[0].statusCode; if (stat == UA_STATUSCODE_BADBOUNDNOTSUPPORTED && current->returnBounds) { fprintf(stderr, "%s", UA_StatusCode_name(stat)); UA_HistoryReadResponse_deleteMembers(&response); break; } if(response.results[0].historyData.encoding != UA_EXTENSIONOBJECT_DECODED || response.results[0].historyData.content.decoded.type != &UA_TYPES[UA_TYPES_HISTORYDATA]) { fprintf(stderr, "ResultError:HistoryData"); readOk = false; UA_HistoryReadResponse_deleteMembers(&response); break; } UA_HistoryData * data = (UA_HistoryData *)response.results[0].historyData.content.decoded.data; resultSize = data->dataValuesSize; result = data->dataValues; if (resultSize == 0 && continuous.length > 0) { fprintf(stderr, "continuousResultEmpty"); readOk = false; UA_HistoryReadResponse_deleteMembers(&response); break; } if (resultSize > maxResponseSize) { fprintf(stderr, "resultToBig"); readOk = false; UA_HistoryReadResponse_deleteMembers(&response); break; } if (stat != UA_STATUSCODE_GOOD) { fprintf(stderr, "%s", UA_StatusCode_name(stat)); } else { for (size_t k = 0; k < resultSize; ++k) printResult(&result[k]); } if (stat == UA_STATUSCODE_GOOD && j >= resultSize + reseivedValues) { for (size_t l = 0; l < resultSize; ++l) { /* See OPC UA Part 11, Version 1.03, Page 5-6, Table 1, Mark a for details.*/ if (current->result[l + reseivedValues] == TIMESTAMP_LAST && current->end == TIMESTAMP_UNSPECIFIED) { // This test will work on not continous read, only if (reseivedValues == 0 && !(l > 0 && result[l].sourceTimestamp == result[l-1].sourceTimestamp + UA_DATETIME_SEC)) readOk = false; } /* See OPC UA Part 11, Version 1.03, Page 5-6, Table 1, Mark b for details.*/ if (current->result[l + reseivedValues] == TIMESTAMP_FIRST && current->start == TIMESTAMP_UNSPECIFIED) { // This test will work on not continous read, only if (reseivedValues == 0 && !(l > 0 && result[l].sourceTimestamp == result[l-1].sourceTimestamp - UA_DATETIME_SEC)) readOk = false; } if (!resultIsEqual(&result[l], current, l + reseivedValues)) readOk = false; } if (response.results[0].continuationPoint.length > 0) fprintf(stderr, "C,"); reseivedValues += resultSize; if (reseivedValues == j) { if (current->returnContinuationPoint && response.results[0].continuationPoint.length == 0) { readOk = false; fprintf(stderr, "missingContinuationPoint"); } if (!current->returnContinuationPoint && response.results[0].continuationPoint.length > 0) { readOk = false; fprintf(stderr, "unexpectedContinuationPoint"); } UA_HistoryReadResponse_deleteMembers(&response); break; } UA_ByteString_deleteMembers(&continuous); UA_ByteString_copy(&response.results[0].continuationPoint, &continuous); } else { readOk = false; UA_HistoryReadResponse_deleteMembers(&response); break; } UA_HistoryReadResponse_deleteMembers(&response); } while (continuous.length > 0); if (j != reseivedValues) { readOk = false; } UA_ByteString_deleteMembers(&continuous); if (!readOk) { fprintf(stderr, "} Fail (%lu requests)\n", counter); ++retval; } else { fprintf(stderr, "} OK (%lu requests)\n", counter); } current = &testRequests[++i]; } return retval; }