Exemplo n.º 1
0
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);
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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;
}